- Timestamp:
- Jan 11, 2019, 10:54:41 AM (6 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer, pthread-emulation, qualifiedEnum
- Children:
- 456834b
- Parents:
- f23b685
- Location:
- libcfa/src/concurrency
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/coroutine.cfa
rf23b685 r76e069f 22 22 #include <string.h> 23 23 #include <unistd.h> 24 // use this define to make unwind.h play nice, definetely a hack 25 #define HIDE_EXPORTS 26 #include <unwind.h> 27 #undef HIDE_EXPORTS 24 28 #include <sys/mman.h> 25 29 } … … 29 33 #define __CFA_INVOKE_PRIVATE__ 30 34 #include "invoke.h" 35 36 extern "C" { 37 void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage) __attribute__ ((__noreturn__)); 38 static void _CtxCoroutine_UnwindCleanup(_Unwind_Reason_Code, struct _Unwind_Exception *) __attribute__ ((__noreturn__)); 39 static void _CtxCoroutine_UnwindCleanup(_Unwind_Reason_Code, struct _Unwind_Exception *) { 40 abort(); 41 } 42 } 31 43 32 44 //----------------------------------------------------------------------------- … … 67 79 starter = NULL; 68 80 last = NULL; 69 } 70 71 void ^?{}(coroutine_desc& this) {} 81 cancellation = NULL; 82 } 83 84 void ^?{}(coroutine_desc& this) { 85 if(this.state != Halted) { 86 coroutine_desc * src = TL_GET( this_coroutine ); 87 coroutine_desc * dst = &this; 88 89 struct _Unwind_Exception storage; 90 storage.exception_class = -1; 91 storage.exception_cleanup = _CtxCoroutine_UnwindCleanup; 92 this.cancellation = &storage; 93 this.last = src; 94 95 // not resuming self ? 96 if ( src == dst ) { 97 abort( "Attempt by coroutine %.256s (%p) to terminate itself.\n", src->name, src ); 98 } 99 100 CoroutineCtxSwitch( src, dst ); 101 } 102 } 72 103 73 104 // Part of the Public API … … 105 136 // Safety note : This could cause some false positives due to preemption 106 137 verify( TL_GET( preemption_state.enabled ) || TL_GET( this_processor )->do_terminate ); 138 139 if( unlikely(src->cancellation != NULL) ) { 140 _CtxCoroutine_Unwind(src->cancellation); 141 } 107 142 } //ctxSwitchDirect 108 143 … … 162 197 } 163 198 164 void __leave_coroutine( void) {199 void __leave_coroutine() { 165 200 coroutine_desc * src = TL_GET( this_coroutine ); // optimization 201 coroutine_desc * starter = src->cancellation != 0 ? src->last : src->starter; 166 202 167 203 src->state = Halted; 168 204 169 assertf( s rc->starter != 0,205 assertf( starter != 0, 170 206 "Attempt to suspend/leave coroutine \"%.256s\" (%p) that has never been resumed.\n" 171 207 "Possible cause is a suspend executed in a member called by a coroutine user rather than by the coroutine main.", 172 208 src->name, src ); 173 assertf( s rc->starter->state != Halted,209 assertf( starter->state != Halted, 174 210 "Attempt by coroutine \"%.256s\" (%p) to suspend/leave back to terminated coroutine \"%.256s\" (%p).\n" 175 211 "Possible cause is terminated coroutine's main routine has already returned.", 176 src->name, src, s rc->starter->name, src->starter );177 178 CoroutineCtxSwitch( src, s rc->starter );212 src->name, src, starter->name, starter ); 213 214 CoroutineCtxSwitch( src, starter ); 179 215 } 180 216 } -
libcfa/src/concurrency/invoke.c
rf23b685 r76e069f 17 17 #include <stdlib.h> 18 18 #include <stdio.h> 19 #include <unwind.h> 19 20 20 21 #include "invoke.h" … … 53 54 __leave_coroutine(); 54 55 __cabi_abort( "Resumed dead coroutine" ); 56 } 57 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 __attribute((__unused__)) void * param 65 ) { 66 if( actions & _UA_END_OF_STACK ) { 67 // We finished unwinding the coroutine, 68 // leave it 69 __leave_coroutine(); 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) __attribute__ ((__noreturn__)); 78 void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage) { 79 _Unwind_Reason_Code ret = _Unwind_ForcedUnwind( storage, _CtxCoroutine_UnwindStop, NULL ); 80 printf("UNWIND ERROR %d after force unwind\n", ret); 81 abort(); 55 82 } 56 83 -
libcfa/src/concurrency/invoke.h
rf23b685 r76e069f 80 80 81 81 struct coroutine_desc { 82 struct coStack_t stack; // stack information of the coroutine 83 const char * name; // textual name for coroutine/task, initialized by uC++ generated code 84 int errno_; // copy of global UNIX variable errno 85 enum coroutine_state state; // current execution status for coroutine 86 struct coroutine_desc * starter; // first coroutine to resume this one 87 struct coroutine_desc * last; // last coroutine to resume this one 82 // stack information of the coroutine 83 struct coStack_t stack; 84 85 // textual name for coroutine/task, initialized by uC++ generated code 86 const char * name; 87 88 // copy of global UNIX variable errno 89 int errno_; 90 91 // current execution status for coroutine 92 enum coroutine_state state; 93 // first coroutine to resume this one 94 struct coroutine_desc * starter; 95 96 // last coroutine to resume this one 97 struct coroutine_desc * last; 98 99 // If non-null stack must be unwound with this exception 100 struct _Unwind_Exception * cancellation; 101 88 102 }; 89 103
Note: See TracChangeset
for help on using the changeset viewer.