Changes in src/libcfa/concurrency/invoke.c [c2b9f21:39fea2f]
- File:
-
- 1 edited
-
src/libcfa/concurrency/invoke.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/invoke.c
rc2b9f21 r39fea2f 18 18 #include <stdio.h> 19 19 20 #include "libhdr.h" 20 21 #include "invoke.h" 21 22 … … 30 31 extern void __leave_thread_monitor( struct thread_desc * this ); 31 32 extern void disable_interrupts(); 32 extern void enable_interrupts( __cfaabi_dbg_ctx_param);33 extern void enable_interrupts( DEBUG_CTX_PARAM ); 33 34 34 35 void CtxInvokeCoroutine( 35 void (*main)(void *),36 struct coroutine_desc *(*get_coroutine)(void *),37 void *this36 void (*main)(void *), 37 struct coroutine_desc *(*get_coroutine)(void *), 38 void *this 38 39 ) { 39 struct coroutine_desc* cor = get_coroutine( this);40 // LIB_DEBUG_PRINTF("Invoke Coroutine : Received %p (main %p, get_c %p)\n", this, main, get_coroutine); 40 41 41 if(cor->state == Primed) { 42 __suspend_internal(); 43 } 42 struct coroutine_desc* cor = get_coroutine( this ); 44 43 45 cor->state = Active; 44 if(cor->state == Primed) { 45 __suspend_internal(); 46 } 46 47 47 main( this );48 cor->state = Active; 48 49 49 cor->state = Halted;50 main( this ); 50 51 51 //Final suspend, should never return 52 __leave_coroutine(); 53 abortf("Resumed dead coroutine"); 52 cor->state = Halted; 53 54 //Final suspend, should never return 55 __leave_coroutine(); 56 abortf("Resumed dead coroutine"); 54 57 } 55 58 56 59 void CtxInvokeThread( 57 void (*dtor)(void *),58 void (*main)(void *),59 struct thread_desc *(*get_thread)(void *),60 void *this60 void (*dtor)(void *), 61 void (*main)(void *), 62 struct thread_desc *(*get_thread)(void *), 63 void *this 61 64 ) { 62 // First suspend, once the thread arrives here,63 // the function pointer to main can be invalidated without risk64 __suspend_internal();65 // First suspend, once the thread arrives here, 66 // the function pointer to main can be invalidated without risk 67 __suspend_internal(); 65 68 66 // Fetch the thread handle from the user defined thread structure67 struct thread_desc* thrd = get_thread( this );69 // Fetch the thread handle from the user defined thread structure 70 struct thread_desc* thrd = get_thread( this ); 68 71 69 // Officially start the thread by enabling preemption70 enable_interrupts( __cfaabi_dbg_ctx);72 // Officially start the thread by enabling preemption 73 enable_interrupts( DEBUG_CTX ); 71 74 72 // Call the main of the thread73 main( this );75 // Call the main of the thread 76 main( this ); 74 77 75 // To exit a thread we must :76 // 1 - Mark it as halted77 // 2 - Leave its monitor78 // 3 - Disable the interupts79 // 4 - Final suspend80 // The order of these 4 operations is very important81 //Final suspend, should never return82 __leave_thread_monitor( thrd );83 abortf("Resumed dead thread");78 // To exit a thread we must : 79 // 1 - Mark it as halted 80 // 2 - Leave its monitor 81 // 3 - Disable the interupts 82 // 4 - Final suspend 83 // The order of these 4 operations is very important 84 //Final suspend, should never return 85 __leave_thread_monitor( thrd ); 86 abortf("Resumed dead thread"); 84 87 } 85 88 86 89 87 90 void CtxStart( 88 void (*main)(void *),89 struct coroutine_desc *(*get_coroutine)(void *),90 void *this,91 void (*invoke)(void *)91 void (*main)(void *), 92 struct coroutine_desc *(*get_coroutine)(void *), 93 void *this, 94 void (*invoke)(void *) 92 95 ) { 93 struct coStack_t* stack = &get_coroutine( this )->stack; 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; 94 99 95 100 #if defined( __i386__ ) … … 98 103 void *fixedRegisters[3]; // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant) 99 104 uint32_t mxcr; // SSE Status and Control bits (control bits are preserved across function calls) 100 uint16_t fcw; // X97 FPU control word (preserved across function calls)105 uint16_t fcw; // X97 FPU control word (preserved across function calls) 101 106 void *rturn; // where to go on return from uSwitch 102 107 void *dummyReturn; // fake return compiler would have pushed on call to uInvoke … … 111 116 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->argument[0] = this; // argument to invoke 112 117 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke; 113 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520114 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7118 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520 119 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7 115 120 116 121 #elif defined( __x86_64__ ) 117 122 118 struct FakeStack {119 void *fixedRegisters[5]; // fixed registers rbx, r12, r13, r14, r15120 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 uSwitch123 void *dummyReturn; // NULL return address to provide proper alignment124 };123 struct FakeStack { 124 void *fixedRegisters[5]; // fixed registers rbx, r12, r13, r14, r15 125 uint32_t mxcr; // SSE Status and Control bits (control bits are preserved across function calls) 126 uint16_t fcw; // X97 FPU control word (preserved across function calls) 127 void *rturn; // where to go on return from uSwitch 128 void *dummyReturn; // NULL return address to provide proper alignment 129 }; 125 130 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 fp131 ((struct machine_context_t *)stack->context)->SP = (char *)stack->base - sizeof( struct FakeStack ); 132 ((struct machine_context_t *)stack->context)->FP = NULL; // terminate stack with NULL fp 128 133 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-520134 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7134 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->dummyReturn = NULL; 135 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = CtxInvokeStub; 136 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[0] = this; 137 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = invoke; 138 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520 139 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7 135 140 #else 136 #error Only __i386__ and __x86_64__ is supported for threads in cfa141 #error Only __i386__ and __x86_64__ is supported for threads in cfa 137 142 #endif 138 143 }
Note:
See TracChangeset
for help on using the changeset viewer.