Changeset 3d560060 for src/libcfa/concurrency/invoke.c
- Timestamp:
- Nov 30, 2017, 3:05:25 PM (6 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 557435e, 5da9d6a
- Parents:
- dd9b59e (diff), c2b9f21 (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 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/invoke.c
rdd9b59e r3d560060 18 18 #include <stdio.h> 19 19 20 #include "libhdr.h"21 20 #include "invoke.h" 22 21 … … 31 30 extern void __leave_thread_monitor( struct thread_desc * this ); 32 31 extern void disable_interrupts(); 33 extern void enable_interrupts( DEBUG_CTX_PARAM);32 extern void enable_interrupts( __cfaabi_dbg_ctx_param ); 34 33 35 34 void CtxInvokeCoroutine( 36 37 38 35 void (*main)(void *), 36 struct coroutine_desc *(*get_coroutine)(void *), 37 void *this 39 38 ) { 40 // LIB_DEBUG_PRINTF("Invoke Coroutine : Received %p (main %p, get_c %p)\n", this, main, get_coroutine);39 struct coroutine_desc* cor = get_coroutine( this ); 41 40 42 struct coroutine_desc* cor = get_coroutine( this ); 41 if(cor->state == Primed) { 42 __suspend_internal(); 43 } 43 44 44 if(cor->state == Primed) { 45 __suspend_internal(); 46 } 45 cor->state = Active; 47 46 48 cor->state = Active;47 main( this ); 49 48 50 main( this );49 cor->state = Halted; 51 50 52 cor->state = Halted; 53 54 //Final suspend, should never return 55 __leave_coroutine(); 56 abortf("Resumed dead coroutine"); 51 //Final suspend, should never return 52 __leave_coroutine(); 53 abortf("Resumed dead coroutine"); 57 54 } 58 55 59 56 void CtxInvokeThread( 60 61 62 63 57 void (*dtor)(void *), 58 void (*main)(void *), 59 struct thread_desc *(*get_thread)(void *), 60 void *this 64 61 ) { 65 66 67 62 // First suspend, once the thread arrives here, 63 // the function pointer to main can be invalidated without risk 64 __suspend_internal(); 68 65 69 70 66 // Fetch the thread handle from the user defined thread structure 67 struct thread_desc* thrd = get_thread( this ); 71 68 72 73 enable_interrupts( DEBUG_CTX);69 // Officially start the thread by enabling preemption 70 enable_interrupts( __cfaabi_dbg_ctx ); 74 71 75 76 72 // Call the main of the thread 73 main( this ); 77 74 78 79 80 81 82 83 84 85 86 75 // To exit a thread we must : 76 // 1 - Mark it as halted 77 // 2 - Leave its monitor 78 // 3 - Disable the interupts 79 // 4 - Final suspend 80 // The order of these 4 operations is very important 81 //Final suspend, should never return 82 __leave_thread_monitor( thrd ); 83 abortf("Resumed dead thread"); 87 84 } 88 85 89 86 90 87 void CtxStart( 91 92 93 94 88 void (*main)(void *), 89 struct coroutine_desc *(*get_coroutine)(void *), 90 void *this, 91 void (*invoke)(void *) 95 92 ) { 96 // LIB_DEBUG_PRINTF("StartCoroutine : Passing in %p (main %p) to invoke (%p) from start (%p)\n", this, main, invoke, CtxStart); 97 98 struct coStack_t* stack = &get_coroutine( this )->stack; 93 struct coStack_t* stack = &get_coroutine( this )->stack; 99 94 100 95 #if defined( __i386__ ) … … 103 98 void *fixedRegisters[3]; // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant) 104 99 uint32_t mxcr; // SSE Status and Control bits (control bits are preserved across function calls) 105 100 uint16_t fcw; // X97 FPU control word (preserved across function calls) 106 101 void *rturn; // where to go on return from uSwitch 107 102 void *dummyReturn; // fake return compiler would have pushed on call to uInvoke … … 116 111 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->argument[0] = this; // argument to invoke 117 112 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke; 118 119 113 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520 114 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7 120 115 121 116 #elif defined( __x86_64__ ) 122 117 123 124 125 126 127 128 129 118 struct FakeStack { 119 void *fixedRegisters[5]; // fixed registers rbx, r12, r13, r14, r15 120 uint32_t mxcr; // SSE Status and Control bits (control bits are preserved across function calls) 121 uint16_t fcw; // X97 FPU control word (preserved across function calls) 122 void *rturn; // where to go on return from uSwitch 123 void *dummyReturn; // NULL return address to provide proper alignment 124 }; 130 125 131 132 126 ((struct machine_context_t *)stack->context)->SP = (char *)stack->base - sizeof( struct FakeStack ); 127 ((struct machine_context_t *)stack->context)->FP = NULL; // terminate stack with NULL fp 133 128 134 135 136 137 138 139 129 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->dummyReturn = NULL; 130 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = CtxInvokeStub; 131 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[0] = this; 132 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = invoke; 133 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520 134 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7 140 135 #else 141 136 #error Only __i386__ and __x86_64__ is supported for threads in cfa 142 137 #endif 143 138 }
Note: See TracChangeset
for help on using the changeset viewer.