Changes in libcfa/src/concurrency/invoke.c [b78129a:76e069f]
- File:
-
- 1 edited
-
libcfa/src/concurrency/invoke.c (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/invoke.c
rb78129a r76e069f 28 28 29 29 extern void __suspend_internal(void); 30 extern void __leave_coroutine( struct coroutine_desc *);31 extern void __finish_creation( struct thread_desc *);30 extern void __leave_coroutine(void); 31 extern void __finish_creation(void); 32 32 extern void __leave_thread_monitor( struct thread_desc * this ); 33 33 extern void disable_interrupts(); … … 47 47 cor->state = Active; 48 48 49 enable_interrupts( __cfaabi_dbg_ctx ); 50 49 51 main( this ); 50 52 51 53 //Final suspend, should never return 52 __leave_coroutine( cor);54 __leave_coroutine(); 53 55 __cabi_abort( "Resumed dead coroutine" ); 54 56 } … … 60 62 __attribute((__unused__)) struct _Unwind_Exception * unwind_exception, 61 63 __attribute((__unused__)) struct _Unwind_Context * context, 62 void * param64 __attribute((__unused__)) void * param 63 65 ) { 64 66 if( actions & _UA_END_OF_STACK ) { 65 67 // We finished unwinding the coroutine, 66 68 // leave it 67 __leave_coroutine( param);69 __leave_coroutine(); 68 70 __cabi_abort( "Resumed dead coroutine" ); 69 71 } … … 73 75 } 74 76 75 void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage , struct coroutine_desc * cor) __attribute__ ((__noreturn__));76 void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage , struct coroutine_desc * cor) {77 _Unwind_Reason_Code ret = _Unwind_ForcedUnwind( storage, _CtxCoroutine_UnwindStop, cor);77 void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage) __attribute__ ((__noreturn__)); 78 void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage) { 79 _Unwind_Reason_Code ret = _Unwind_ForcedUnwind( storage, _CtxCoroutine_UnwindStop, NULL ); 78 80 printf("UNWIND ERROR %d after force unwind\n", ret); 79 81 abort(); … … 86 88 void *this 87 89 ) { 90 // First suspend, once the thread arrives here, 91 // the function pointer to main can be invalidated without risk 92 __finish_creation(); 93 88 94 // Fetch the thread handle from the user defined thread structure 89 95 struct thread_desc* thrd = get_thread( this ); 90 91 // First suspend, once the thread arrives here, 92 // the function pointer to main can be invalidated without risk 93 __finish_creation( thrd ); 96 thrd->self_cor.last = NULL; 94 97 95 98 // Officially start the thread by enabling preemption … … 117 120 void (*invoke)(void *) 118 121 ) { 119 struct coroutine_desc * cor = get_coroutine( this ); 120 struct __stack_t * stack = cor->stack.storage; 122 struct coStack_t* stack = &get_coroutine( this )->stack; 121 123 122 124 #if defined( __i386 ) 123 125 124 126 struct FakeStack { 125 void *fixedRegisters[3]; // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant) 127 void *fixedRegisters[3]; // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant) 128 uint32_t mxcr; // SSE Status and Control bits (control bits are preserved across function calls) 129 uint16_t fcw; // X97 FPU control word (preserved across function calls) 126 130 void *rturn; // where to go on return from uSwitch 127 void *dummyReturn; // fake return compiler would have pushed on call to uInvoke128 void *argument[3]; // for 16-byte ABI, 16-byte alignment starts here129 void *padding; // padding to force 16-byte alignment, as "base" is 16-byte aligned131 void *dummyReturn; // fake return compiler would have pushed on call to uInvoke 132 void *argument[3]; // for 16-byte ABI, 16-byte alignment starts here 133 void *padding; // padding to force 16-byte alignment, as "base" is 16-byte aligned 130 134 }; 131 135 132 cor->context.SP = (char *)stack->base - sizeof( struct FakeStack );133 cor->context.FP = NULL; // terminate stack with NULL fp136 ((struct machine_context_t *)stack->context)->SP = (char *)stack->base - sizeof( struct FakeStack ); 137 ((struct machine_context_t *)stack->context)->FP = NULL; // terminate stack with NULL fp 134 138 135 struct FakeStack *fs = (struct FakeStack *)cor->context.SP;136 137 fs->dummyReturn = NULL;138 fs->argument[0] = this; // argument to invoke139 fs->rturn = invoke;139 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->dummyReturn = NULL; 140 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->argument[0] = this; // argument to invoke 141 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke; 142 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520 143 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7 140 144 141 145 #elif defined( __x86_64 ) … … 143 147 struct FakeStack { 144 148 void *fixedRegisters[5]; // fixed registers rbx, r12, r13, r14, r15 149 uint32_t mxcr; // SSE Status and Control bits (control bits are preserved across function calls) 150 uint16_t fcw; // X97 FPU control word (preserved across function calls) 145 151 void *rturn; // where to go on return from uSwitch 146 152 void *dummyReturn; // NULL return address to provide proper alignment 147 153 }; 148 154 149 cor->context.SP = (char *)stack->base - sizeof( struct FakeStack );150 cor->context.FP = NULL; // terminate stack with NULL fp155 ((struct machine_context_t *)stack->context)->SP = (char *)stack->base - sizeof( struct FakeStack ); 156 ((struct machine_context_t *)stack->context)->FP = NULL; // terminate stack with NULL fp 151 157 152 struct FakeStack *fs = (struct FakeStack *)cor->context.SP;153 154 fs->dummyReturn = NULL;155 fs->rturn = CtxInvokeStub;156 fs->fixedRegisters[0] = this;157 fs->fixedRegisters[1] = invoke;158 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->dummyReturn = NULL; 159 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = CtxInvokeStub; 160 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[0] = this; 161 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = invoke; 162 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520 163 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7 158 164 159 165 #elif defined( __ARM_ARCH ) … … 165 171 }; 166 172 167 cor->context.SP = (char *)stack->base - sizeof( struct FakeStack );168 cor->context.FP = NULL;173 ((struct machine_context_t *)stack->context)->SP = (char *)stack->base - sizeof( struct FakeStack ); 174 ((struct machine_context_t *)stack->context)->FP = NULL; 169 175 170 struct FakeStack *fs = (struct FakeStack *) cor->context.SP;176 struct FakeStack *fs = (struct FakeStack *)((struct machine_context_t *)stack->context)->SP; 171 177 172 178 fs->intRegs[8] = CtxInvokeStub;
Note:
See TracChangeset
for help on using the changeset viewer.