source: src/libcfa/concurrency/invoke.c @ 78b3f52

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newwith_gc
Last change on this file since 78b3f52 was 78b3f52, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Ugly but working coroutines

  • Property mode set to 100644
File size: 2.4 KB
Line 
1
2#include <stdbool.h>
3#include <stdlib.h>
4#include <stdio.h>
5
6#include "invoke.h"
7
8struct machine_context_t {
9        void *SP;
10        void *FP;
11        void *PC;
12};
13
14extern void coInvokeStub( void );
15
16// magically invoke the "main" of the most derived class
17// Called from the kernel when starting a coroutine or task so must switch back to user mode.
18void __invokeCoroutine__F_P9scoVtablePv__1(struct coVtable *vtable, void* vthis)
19{
20      printf("Invoke : Received %p (v %p)\n", vthis, vtable);
21
22      struct coroutine* cor = vtable->this_coroutine(vthis);
23
24      cor->state = Active;
25
26      vtable->main(vthis);
27}
28
29void __startCoroutine__A0_1_0___this_coroutine__PFP10scoroutine_Pd0___co_main__PF_Pd0___vtable__PFP9scoVtable_Pd0__F_Pd0PF_P9scoVtablePv___1(
30      struct coroutine *(*this_coroutine)(void * ), 
31      void (*co_main)(void *), 
32      struct coVtable *(*get_vtable)(void *), 
33      void *vthis, 
34      void (*invoke)(struct coVtable *, void *)
35) {
36
37      #if ! defined( __x86_64__ )
38            #error Only __x86_64__ is supported for threads in cfa
39      #endif
40
41      #if defined( __U_SWAPCONTEXT__ )
42            #error __U_SWAPCONTEXT__ should not be defined for __x86_64__
43      #endif
44
45      struct coVtable * vtable = get_vtable( vthis );
46      struct coroutine* this = this_coroutine( vthis );
47      struct coStack_t* stack = &this->stack;
48
49      struct FakeStack {
50            void *fixedRegisters[5];                    // fixed registers rbx, r12, r13, r14, r15
51            void *rturn;                                        // where to go on return from uSwitch
52            void *dummyReturn;                          // NULL return address to provide proper alignment
53      }; // FakeStack
54
55      ((struct machine_context_t *)stack->context)->SP = (char *)stack->base - sizeof( struct FakeStack );
56      ((struct machine_context_t *)stack->context)->FP = NULL;          // terminate stack with NULL fp
57
58      fprintf(stderr, "StartCoroutine : Passing in %p (v %p) to %p\n", vthis, vtable, invoke);
59
60      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->dummyReturn = NULL;
61      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = coInvokeStub;
62      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[0] = vtable;
63      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = vthis;
64      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[2] = invoke;
65}
Note: See TracBrowser for help on using the repository browser.