source: src/libcfa/concurrency/invoke.c @ d9c44c3

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since d9c44c3 was d9c44c3, checked in by Thierry Delisle <tdelisle@…>, 8 years ago

Implemented coroutine for i386 and added coroutines to tests

  • Property mode set to 100644
File size: 3.4 KB
Line 
1
2#include <stdbool.h>
3#include <stdlib.h>
4#include <stdio.h>
5
6#include "libhdr.h"
7#include "invoke.h"
8
9struct machine_context_t {
10        void *SP;
11        void *FP;
12        void *PC;
13};
14
15extern void coInvokeStub( void );
16
17// magically invoke the "main" of the most derived class
18// Called from the kernel when starting a coroutine or task so must switch back to user mode.
19void __invokeCoroutine__F_P9scoVtablePv__1(struct coVtable *vtable, void* vthis)
20{
21      LIB_DEBUG_PRINTF("Invoke : Received %p (v %p)\n", vthis, vtable);
22
23      struct coroutine* cor = vtable->this_coroutine(vthis);
24
25      cor->state = Active;
26
27      vtable->main(vthis);
28}
29
30void __startCoroutine__A0_1_0___this_coroutine__PFP10scoroutine_Pd0___co_main__PF_Pd0___vtable__PFP9scoVtable_Pd0__F_Pd0PF_P9scoVtablePv___1(
31      struct coroutine *(*this_coroutine)(void * ),
32      void (*co_main)(void *),
33      struct coVtable *(*get_vtable)(void *),
34      void *vthis,
35      void (*invoke)(struct coVtable *, void *)
36) {
37      LIB_DEBUG_PRINTF("StartCoroutine : Passing in %p (v %p) to %p\n", vthis, vtable, invoke);
38
39      struct coVtable * vtable = get_vtable( vthis );
40      struct coroutine* this = this_coroutine( vthis );
41      struct coStack_t* stack = &this->stack;
42
43#if defined( __i386__ )
44
45        struct FakeStack {
46            void *fixedRegisters[3];                    // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant)
47            void *rturn;                                      // where to go on return from uSwitch
48            void *dummyReturn;                          // fake return compiler would have pushed on call to uInvoke
49            void *argument[2];                          // for 16-byte ABI, 16-byte alignment starts here
50            void *padding[2];                           // padding to force 16-byte alignment, as "base" is 16-byte aligned
51        };
52
53        ((struct machine_context_t *)stack->context)->SP = (char *)stack->base - sizeof( struct FakeStack );
54        ((struct machine_context_t *)stack->context)->FP = NULL;                // terminate stack with NULL fp
55
56        ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->dummyReturn = NULL;
57        ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->argument[0] = vtable; // argument to invoke
58      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->argument[1] = vthis;  // argument to invoke
59        ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke;
60
61#elif defined( __x86_64__ )
62
63      struct FakeStack {
64            void *fixedRegisters[5];                    // fixed registers rbx, r12, r13, r14, r15
65            void *rturn;                                        // where to go on return from uSwitch
66            void *dummyReturn;                          // NULL return address to provide proper alignment
67      };
68
69      ((struct machine_context_t *)stack->context)->SP = (char *)stack->base - sizeof( struct FakeStack );
70      ((struct machine_context_t *)stack->context)->FP = NULL;          // terminate stack with NULL fp
71
72      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->dummyReturn = NULL;
73      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = coInvokeStub;
74      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[0] = vtable;
75      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = vthis;
76      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[2] = invoke;
77#else
78      #error Only __i386__ and __x86_64__ is supported for threads in cfa
79#endif
80}
Note: See TracBrowser for help on using the repository browser.