Changeset b067d9b for libcfa/src/concurrency/invoke.c
- Timestamp:
- Oct 29, 2019, 4:01:24 PM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 773db65, 9421f3d8
- Parents:
- 7951100 (diff), 8364209 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/invoke.c
r7951100 rb067d9b 14 14 // 15 15 16 #define __cforall_thread__ 17 16 18 #include <stdbool.h> 17 19 #include <stdlib.h> 18 20 #include <stdio.h> 21 #include <unwind.h> 19 22 20 23 #include "invoke.h" … … 27 30 28 31 extern void __suspend_internal(void); 29 extern void __leave_coroutine( void);30 extern void __finish_creation( void);32 extern void __leave_coroutine( struct coroutine_desc * ); 33 extern void __finish_creation( struct thread_desc * ); 31 34 extern void __leave_thread_monitor( struct thread_desc * this ); 32 extern void disable_interrupts() ;35 extern void disable_interrupts() OPTIONAL_THREAD; 33 36 extern void enable_interrupts( __cfaabi_dbg_ctx_param ); 34 37 … … 46 49 cor->state = Active; 47 50 48 enable_interrupts( __cfaabi_dbg_ctx );49 50 51 main( this ); 51 52 52 cor->state = Halted; 53 //Final suspend, should never return 54 __leave_coroutine( cor ); 55 __cabi_abort( "Resumed dead coroutine" ); 56 } 53 57 54 //Final suspend, should never return 55 __leave_coroutine(); 56 __cabi_abort( "Resumed dead coroutine" ); 58 static _Unwind_Reason_Code _CtxCoroutine_UnwindStop( 59 __attribute((__unused__)) int version, 60 _Unwind_Action actions, 61 __attribute((__unused__)) _Unwind_Exception_Class exceptionClass, 62 __attribute((__unused__)) struct _Unwind_Exception * unwind_exception, 63 __attribute((__unused__)) struct _Unwind_Context * context, 64 void * param 65 ) { 66 if( actions & _UA_END_OF_STACK ) { 67 // We finished unwinding the coroutine, 68 // leave it 69 __leave_coroutine( param ); 70 __cabi_abort( "Resumed dead coroutine" ); 71 } 72 if( actions & _UA_CLEANUP_PHASE ) return _URC_NO_REASON; 73 74 return _URC_FATAL_PHASE2_ERROR; 75 } 76 77 void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc * cor) __attribute__ ((__noreturn__)); 78 void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc * cor) { 79 _Unwind_Reason_Code ret = _Unwind_ForcedUnwind( storage, _CtxCoroutine_UnwindStop, cor ); 80 printf("UNWIND ERROR %d after force unwind\n", ret); 81 abort(); 57 82 } 58 83 … … 63 88 void *this 64 89 ) { 90 // Fetch the thread handle from the user defined thread structure 91 struct thread_desc* thrd = get_thread( this ); 92 65 93 // First suspend, once the thread arrives here, 66 94 // the function pointer to main can be invalidated without risk 67 __finish_creation(); 68 69 // Fetch the thread handle from the user defined thread structure 70 struct thread_desc* thrd = get_thread( this ); 71 thrd->self_cor.last = NULL; 95 __finish_creation( thrd ); 72 96 73 97 // Officially start the thread by enabling preemption … … 95 119 void (*invoke)(void *) 96 120 ) { 97 struct coStack_t* stack = &get_coroutine( this )->stack; 121 struct coroutine_desc * cor = get_coroutine( this ); 122 struct __stack_t * stack = cor->stack.storage; 98 123 99 124 #if defined( __i386 ) 100 125 101 126 struct FakeStack { 102 void *fixedRegisters[3]; // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant) 103 uint32_t mxcr; // SSE Status and Control bits (control bits are preserved across function calls) 104 uint16_t fcw; // X97 FPU control word (preserved across function calls) 127 void *fixedRegisters[3]; // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant) 105 128 void *rturn; // where to go on return from uSwitch 106 void *dummyReturn; 107 void *argument[3]; 108 void *padding; 129 void *dummyReturn; // fake return compiler would have pushed on call to uInvoke 130 void *argument[3]; // for 16-byte ABI, 16-byte alignment starts here 131 void *padding; // padding to force 16-byte alignment, as "base" is 16-byte aligned 109 132 }; 110 133 111 ((struct machine_context_t *)stack->context)->SP = (char *)stack->base - sizeof( struct FakeStack );112 ((struct machine_context_t *)stack->context)->FP = NULL; // terminate stack with NULL fp134 cor->context.SP = (char *)stack->base - sizeof( struct FakeStack ); 135 cor->context.FP = NULL; // terminate stack with NULL fp 113 136 114 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->dummyReturn = NULL;115 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->argument[0] = this; // argument to invoke 116 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke;117 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520118 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7137 struct FakeStack *fs = (struct FakeStack *)cor->context.SP; 138 139 fs->dummyReturn = NULL; 140 fs->argument[0] = this; // argument to invoke 141 fs->rturn = invoke; 119 142 120 143 #elif defined( __x86_64 ) … … 122 145 struct FakeStack { 123 146 void *fixedRegisters[5]; // fixed registers rbx, r12, r13, r14, r15 124 uint32_t mxcr; // SSE Status and Control bits (control bits are preserved across function calls)125 uint16_t fcw; // X97 FPU control word (preserved across function calls)126 147 void *rturn; // where to go on return from uSwitch 127 148 void *dummyReturn; // NULL return address to provide proper alignment 128 149 }; 129 150 130 ((struct machine_context_t *)stack->context)->SP = (char *)stack->base - sizeof( struct FakeStack );131 ((struct machine_context_t *)stack->context)->FP = NULL; // terminate stack with NULL fp151 cor->context.SP = (char *)stack->base - sizeof( struct FakeStack ); 152 cor->context.FP = NULL; // terminate stack with NULL fp 132 153 133 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->dummyReturn = NULL;134 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = CtxInvokeStub; 135 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[0] = this;136 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = invoke;137 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520138 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7154 struct FakeStack *fs = (struct FakeStack *)cor->context.SP; 155 156 fs->dummyReturn = NULL; 157 fs->rturn = CtxInvokeStub; 158 fs->fixedRegisters[0] = this; 159 fs->fixedRegisters[1] = invoke; 139 160 140 161 #elif defined( __ARM_ARCH ) … … 146 167 }; 147 168 148 ((struct machine_context_t *)stack->context)->SP = (char *)stack->base - sizeof( struct FakeStack );149 ((struct machine_context_t *)stack->context)->FP = NULL;169 cor->context.SP = (char *)stack->base - sizeof( struct FakeStack ); 170 cor->context.FP = NULL; 150 171 151 struct FakeStack *fs = (struct FakeStack *) ((struct machine_context_t *)stack->context)->SP;172 struct FakeStack *fs = (struct FakeStack *)cor->context.SP; 152 173 153 174 fs->intRegs[8] = CtxInvokeStub;
Note:
See TracChangeset
for help on using the changeset viewer.