Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/thread.cfa

    rac5816d r09f357ec  
    1919
    2020#include "kernel_private.hfa"
    21 #include "exception.hfa"
    2221
    2322#define __CFA_INVOKE_PRIVATE__
    2423#include "invoke.h"
    2524
     25extern "C" {
     26        #include <fenv.h>
     27        #include <stddef.h>
     28}
     29
     30//extern volatile thread_local processor * this_processor;
     31
    2632//-----------------------------------------------------------------------------
    2733// Thread ctors and dtors
    28 void ?{}($thread & this, const char * const name, cluster & cl, void * storage, size_t storageSize ) with( this ) {
     34void ?{}(thread_desc & this, const char * const name, cluster & cl, void * storage, size_t storageSize ) with( this ) {
    2935        context{ 0p, 0p };
    3036        self_cor{ name, storage, storageSize };
    31         ticket = TICKET_RUNNING;
    3237        state = Start;
    33         preempted = __NO_PREEMPTION;
    3438        curr_cor = &self_cor;
    3539        self_mon.owner = &this;
     
    3741        self_mon_p = &self_mon;
    3842        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;
    4844
    4945        node.next = 0p;
     
    5450}
    5551
    56 void ^?{}($thread& this) with( this ) {
    57         #if defined( __CFA_WITH_VERIFY__ )
    58                 canary = 0xDEADDEADDEADDEADp;
    59         #endif
     52void ^?{}(thread_desc& this) with( this ) {
    6053        unregister(curr_cluster, this);
    6154        ^self_cor{};
    6255}
    6356
    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
    14357forall( dtype T | sized(T) | is_thread(T) | { void ?{}(T&); } )
    14458void ?{}( scoped(T)& this ) with( this ) {
     
    15973
    16074//-----------------------------------------------------------------------------
    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
     76forall( dtype T | is_thread(T) )
     77void __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 );
    16590}
    16691
    167 uint64_t thread_rand() {
    168         disable_interrupts();
    169         uint64_t ret = __tls_rand();
    170         enable_interrupts( __cfaabi_dbg_ctx );
    171         return ret;
     92void 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
     100void yield( unsigned times ) {
     101        for( unsigned i = 0; i < times; i++ ) {
     102                yield();
     103        }
    172104}
    173105
Note: See TracChangeset for help on using the changeset viewer.