Ignore:
Timestamp:
Jan 7, 2021, 2:55:57 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
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.
Message:

Merge branch 'master' into dkobets-vector

File:
1 edited

Legend:

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

    rbdfc032 reef8dfb  
    1919
    2020#include "kernel_private.hfa"
     21#include "exception.hfa"
    2122
    2223#define __CFA_INVOKE_PRIVATE__
    2324#include "invoke.h"
    2425
    25 extern "C" {
    26         #include <fenv.h>
    27         #include <stddef.h>
    28 }
    29 
    30 //extern volatile thread_local processor * this_processor;
    31 
    3226//-----------------------------------------------------------------------------
    3327// Thread ctors and dtors
    34 void ?{}(thread_desc & this, const char * const name, cluster & cl, void * storage, size_t storageSize ) with( this ) {
     28void ?{}($thread & this, const char * const name, cluster & cl, void * storage, size_t storageSize ) with( this ) {
    3529        context{ 0p, 0p };
    3630        self_cor{ name, storage, storageSize };
     31        ticket = TICKET_RUNNING;
    3732        state = Start;
     33        preempted = __NO_PREEMPTION;
    3834        curr_cor = &self_cor;
    3935        self_mon.owner = &this;
     
    4137        self_mon_p = &self_mon;
    4238        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;
    4448
    4549        node.next = 0p;
     
    5054}
    5155
    52 void ^?{}(thread_desc& this) with( this ) {
     56void ^?{}($thread& this) with( this ) {
     57        #if defined( __CFA_WITH_VERIFY__ )
     58                canary = 0xDEADDEADDEADDEADp;
     59        #endif
    5360        unregister(curr_cluster, this);
    5461        ^self_cor{};
    5562}
    5663
     64FORALL_DATA_INSTANCE(ThreadCancelled, (dtype thread_t), (thread_t))
     65
     66forall(dtype T)
     67void 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
     73forall(dtype T)
     74const char * msg(ThreadCancelled(T) *) {
     75        return "ThreadCancelled";
     76}
     77
     78forall(dtype T)
     79static void default_thread_cancel_handler(ThreadCancelled(T) & ) {
     80        abort( "Unhandled thread cancellation.\n" );
     81}
     82
     83forall(dtype T | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T)))
     84void ?{}( 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
     121void ^?{}( thread_dtor_guard_t & this ) {
     122        ^(this.mg){};
     123}
     124
     125//-----------------------------------------------------------------------------
     126// Starting and stopping threads
     127forall( dtype T | is_thread(T) )
     128void __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
    57143forall( dtype T | sized(T) | is_thread(T) | { void ?{}(T&); } )
    58144void ?{}( scoped(T)& this ) with( this ) {
     
    73159
    74160//-----------------------------------------------------------------------------
    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 );
     161forall(dtype T | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T)))
     162T & join( T & this ) {
     163        thread_dtor_guard_t guard = { this, defaultResumptionHandler };
     164        return this;
    90165}
    91166
    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         }
     167uint64_t thread_rand() {
     168        disable_interrupts();
     169        uint64_t ret = __tls_rand();
     170        enable_interrupts( __cfaabi_dbg_ctx );
     171        return ret;
    104172}
    105173
Note: See TracChangeset for help on using the changeset viewer.