Changeset eef8dfb for libcfa/src/concurrency/thread.cfa
- Timestamp:
- Jan 7, 2021, 2:55:57 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 58fe85a
- Parents:
- bdfc032 (diff), 44e37ef (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
-
libcfa/src/concurrency/thread.cfa
rbdfc032 reef8dfb 19 19 20 20 #include "kernel_private.hfa" 21 #include "exception.hfa" 21 22 22 23 #define __CFA_INVOKE_PRIVATE__ 23 24 #include "invoke.h" 24 25 25 extern "C" {26 #include <fenv.h>27 #include <stddef.h>28 }29 30 //extern volatile thread_local processor * this_processor;31 32 26 //----------------------------------------------------------------------------- 33 27 // Thread ctors and dtors 34 void ?{}( thread_desc& this, const char * const name, cluster & cl, void * storage, size_t storageSize ) with( this ) {28 void ?{}($thread & this, const char * const name, cluster & cl, void * storage, size_t storageSize ) with( this ) { 35 29 context{ 0p, 0p }; 36 30 self_cor{ name, storage, storageSize }; 31 ticket = TICKET_RUNNING; 37 32 state = Start; 33 preempted = __NO_PREEMPTION; 38 34 curr_cor = &self_cor; 39 35 self_mon.owner = &this; … … 41 37 self_mon_p = &self_mon; 42 38 curr_cluster = &cl; 43 next = 0p; 39 link.next = 0p; 40 link.prev = 0p; 41 link.preferred = -1; 42 #if defined( __CFA_WITH_VERIFY__ ) 43 canary = 0x0D15EA5E0D15EA5Ep; 44 #endif 45 46 seqable.next = 0p; 47 seqable.back = 0p; 44 48 45 49 node.next = 0p; … … 50 54 } 51 55 52 void ^?{}(thread_desc& this) with( this ) { 56 void ^?{}($thread& this) with( this ) { 57 #if defined( __CFA_WITH_VERIFY__ ) 58 canary = 0xDEADDEADDEADDEADp; 59 #endif 53 60 unregister(curr_cluster, this); 54 61 ^self_cor{}; 55 62 } 56 63 64 FORALL_DATA_INSTANCE(ThreadCancelled, (dtype thread_t), (thread_t)) 65 66 forall(dtype T) 67 void copy(ThreadCancelled(T) * dst, ThreadCancelled(T) * src) { 68 dst->virtual_table = src->virtual_table; 69 dst->the_thread = src->the_thread; 70 dst->the_exception = src->the_exception; 71 } 72 73 forall(dtype T) 74 const char * msg(ThreadCancelled(T) *) { 75 return "ThreadCancelled"; 76 } 77 78 forall(dtype T) 79 static void default_thread_cancel_handler(ThreadCancelled(T) & ) { 80 abort( "Unhandled thread cancellation.\n" ); 81 } 82 83 forall(dtype T | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T))) 84 void ?{}( thread_dtor_guard_t & this, 85 T & thrd, void(*defaultResumptionHandler)(ThreadCancelled(T) &)) { 86 $monitor * m = get_monitor(thrd); 87 $thread * desc = get_thread(thrd); 88 89 // Setup the monitor guard 90 void (*dtor)(T& mutex this) = ^?{}; 91 bool join = defaultResumptionHandler != (void(*)(ThreadCancelled(T)&))0; 92 (this.mg){&m, (void(*)())dtor, join}; 93 94 95 /* paranoid */ verifyf( Halted == desc->state || Cancelled == desc->state, "Expected thread to be Halted or Cancelled, was %d\n", (int)desc->state ); 96 97 // After the guard set-up and any wait, check for cancellation. 98 struct _Unwind_Exception * cancellation = desc->self_cor.cancellation; 99 if ( likely( 0p == cancellation ) ) { 100 return; 101 } else if ( Cancelled == desc->state ) { 102 return; 103 } 104 desc->state = Cancelled; 105 if (!join) { 106 defaultResumptionHandler = default_thread_cancel_handler; 107 } 108 109 ThreadCancelled(T) except; 110 // TODO: Remove explitate vtable set once trac#186 is fixed. 111 except.virtual_table = &get_exception_vtable(&except); 112 except.the_thread = &thrd; 113 except.the_exception = __cfaehm_cancellation_exception( cancellation ); 114 throwResume except; 115 116 except.the_exception->virtual_table->free( except.the_exception ); 117 free( cancellation ); 118 desc->self_cor.cancellation = 0p; 119 } 120 121 void ^?{}( thread_dtor_guard_t & this ) { 122 ^(this.mg){}; 123 } 124 125 //----------------------------------------------------------------------------- 126 // Starting and stopping threads 127 forall( dtype T | is_thread(T) ) 128 void __thrd_start( T & this, void (*main_p)(T &) ) { 129 $thread * this_thrd = get_thread(this); 130 131 disable_interrupts(); 132 __cfactx_start(main_p, get_coroutine(this), this, __cfactx_invoke_thread); 133 134 this_thrd->context.[SP, FP] = this_thrd->self_cor.context.[SP, FP]; 135 /* paranoid */ verify( this_thrd->context.SP ); 136 137 __schedule_thread( this_thrd ); 138 enable_interrupts( __cfaabi_dbg_ctx ); 139 } 140 141 //----------------------------------------------------------------------------- 142 // Support for threads that don't ues the thread keyword 57 143 forall( dtype T | sized(T) | is_thread(T) | { void ?{}(T&); } ) 58 144 void ?{}( scoped(T)& this ) with( this ) { … … 73 159 74 160 //----------------------------------------------------------------------------- 75 // Starting and stopping threads 76 forall( dtype T | is_thread(T) ) 77 void __thrd_start( T & this, void (*main_p)(T &) ) { 78 thread_desc * this_thrd = get_thread(this); 79 thread_desc * curr_thrd = TL_GET( this_thread ); 80 81 disable_interrupts(); 82 CtxStart(main_p, get_coroutine(this), this, CtxInvokeThread); 83 84 this_thrd->context.[SP, FP] = this_thrd->self_cor.context.[SP, FP]; 85 verify( this_thrd->context.SP ); 86 // CtxSwitch( &curr_thrd->context, &this_thrd->context ); 87 88 ScheduleThread(this_thrd); 89 enable_interrupts( __cfaabi_dbg_ctx ); 161 forall(dtype T | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T))) 162 T & join( T & this ) { 163 thread_dtor_guard_t guard = { this, defaultResumptionHandler }; 164 return this; 90 165 } 91 166 92 void yield( void ) { 93 // Safety note : This could cause some false positives due to preemption 94 verify( TL_GET( preemption_state.enabled ) ); 95 BlockInternal( TL_GET( this_thread ) ); 96 // Safety note : This could cause some false positives due to preemption 97 verify( TL_GET( preemption_state.enabled ) ); 98 } 99 100 void yield( unsigned times ) { 101 for( unsigned i = 0; i < times; i++ ) { 102 yield(); 103 } 167 uint64_t thread_rand() { 168 disable_interrupts(); 169 uint64_t ret = __tls_rand(); 170 enable_interrupts( __cfaabi_dbg_ctx ); 171 return ret; 104 172 } 105 173
Note:
See TracChangeset
for help on using the changeset viewer.