- File:
-
- 1 edited
-
libcfa/src/concurrency/thread.cfa (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/thread.cfa
rac5816d r09f357ec 19 19 20 20 #include "kernel_private.hfa" 21 #include "exception.hfa"22 21 23 22 #define __CFA_INVOKE_PRIVATE__ 24 23 #include "invoke.h" 25 24 25 extern "C" { 26 #include <fenv.h> 27 #include <stddef.h> 28 } 29 30 //extern volatile thread_local processor * this_processor; 31 26 32 //----------------------------------------------------------------------------- 27 33 // Thread ctors and dtors 28 void ?{}( $thread& this, const char * const name, cluster & cl, void * storage, size_t storageSize ) with( this ) {34 void ?{}(thread_desc & this, const char * const name, cluster & cl, void * storage, size_t storageSize ) with( this ) { 29 35 context{ 0p, 0p }; 30 36 self_cor{ name, storage, storageSize }; 31 ticket = TICKET_RUNNING;32 37 state = Start; 33 preempted = __NO_PREEMPTION;34 38 curr_cor = &self_cor; 35 39 self_mon.owner = &this; … … 37 41 self_mon_p = &self_mon; 38 42 curr_cluster = &cl; 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; 43 next = 0p; 48 44 49 45 node.next = 0p; … … 54 50 } 55 51 56 void ^?{}($thread& this) with( this ) { 57 #if defined( __CFA_WITH_VERIFY__ ) 58 canary = 0xDEADDEADDEADDEADp; 59 #endif 52 void ^?{}(thread_desc& this) with( this ) { 60 53 unregister(curr_cluster, this); 61 54 ^self_cor{}; 62 55 } 63 56 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 guard90 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 threads127 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 keyword143 57 forall( dtype T | sized(T) | is_thread(T) | { void ?{}(T&); } ) 144 58 void ?{}( scoped(T)& this ) with( this ) { … … 159 73 160 74 //----------------------------------------------------------------------------- 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; 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 ); 165 90 } 166 91 167 uint64_t thread_rand() { 168 disable_interrupts(); 169 uint64_t ret = __tls_rand(); 170 enable_interrupts( __cfaabi_dbg_ctx ); 171 return ret; 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 } 172 104 } 173 105
Note:
See TracChangeset
for help on using the changeset viewer.