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

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since fa66f4e was d9c44c3, checked in by Thierry Delisle <tdelisle@…>, 9 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.