Changeset ff79d5e


Ignore:
Timestamp:
Jun 12, 2020, 5:01:21 PM (16 months ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
arm-eh, jacob/cs343-translation, master, new-ast, new-ast-unique-expr
Children:
2649ff9
Parents:
cb196f2
Message:

Fixed park unpark to support park as first step of main()
Fixes #170?

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/invoke.h

    rcb196f2 rff79d5e  
    9292        };
    9393
    94         enum coroutine_state { Halted, Start, Primed, Blocked, Ready, Active, Rerun };
     94        enum __Coroutine_State { Halted, Start, Primed, Blocked, Ready, Active };
    9595        enum __Preemption_Reason { __NO_PREEMPTION, __ALARM_PREEMPTION, __POLL_PREEMPTION, __MANUAL_PREEMPTION };
    9696
     
    106106
    107107                // current execution status for coroutine
    108                 enum coroutine_state state;
     108                enum __Coroutine_State state;
    109109
    110110                // first coroutine to resume this one
     
    175175
    176176                // current execution status for coroutine
    177                 volatile int state;
    178                 enum __Preemption_Reason preempted;
     177                volatile int ticket;
     178                enum __Coroutine_State state:8;
     179                enum __Preemption_Reason preempted:8;
    179180
    180181                //SKULLDUGGERY errno is not save in the thread data structure because returnToKernel appears to be the only function to require saving and restoring it
     
    210211                        // previous function to park/unpark the thread
    211212                        const char * park_caller;
    212                         enum coroutine_state park_result;
     213                        int park_result;
     214                        enum __Coroutine_State park_state;
    213215                        bool park_stale;
    214216                        const char * unpark_caller;
    215                         enum coroutine_state unpark_result;
     217                        int unpark_result;
     218                        enum __Coroutine_State unpark_state;
    216219                        bool unpark_stale;
    217220                #endif
  • libcfa/src/concurrency/kernel.cfa

    rcb196f2 rff79d5e  
    192192
    193193void ?{}( $thread & this, current_stack_info_t * info) with( this ) {
     194        ticket = 1;
    194195        state = Start;
    195196        self_cor{ info };
     
    378379        // Actually run the thread
    379380        RUNNING:  while(true) {
    380                 if(unlikely(thrd_dst->preempted)) {
    381                         thrd_dst->preempted = __NO_PREEMPTION;
    382                         verify(thrd_dst->state == Active  || thrd_dst->state == Rerun);
    383                 } else {
    384                         verify(thrd_dst->state == Blocked || thrd_dst->state == Ready); // Ready means scheduled normally, blocked means rerun
    385                         thrd_dst->state = Active;
    386                 }
     381                thrd_dst->preempted = __NO_PREEMPTION;
     382                thrd_dst->state = Active;
    387383
    388384                __cfaabi_dbg_debug_do(
     
    420416                }
    421417
     418                if(unlikely(thrd_dst->state == Halted)) {
     419                        // The thread has halted, it should never be scheduled/run again
     420                        // We may need to wake someone up here since
     421                        unpark( this->destroyer __cfaabi_dbg_ctx2 );
     422                        this->destroyer = 0p;
     423                        break RUNNING;
     424                }
     425
     426                /* paranoid */ verify( thrd_dst->state == Active );
     427                thrd_dst->state = Blocked;
     428
    422429                // set state of processor coroutine to active and the thread to inactive
    423                 static_assert(sizeof(thrd_dst->state) == sizeof(int));
    424                 enum coroutine_state old_state = __atomic_exchange_n(&thrd_dst->state, Blocked, __ATOMIC_SEQ_CST);
    425                 __cfaabi_dbg_debug_do( thrd_dst->park_result = old_state; )
    426                 switch(old_state) {
    427                         case Halted:
    428                                 // The thread has halted, it should never be scheduled/run again, leave it back to Halted and move on
    429                                 thrd_dst->state = Halted;
    430 
    431                                 // We may need to wake someone up here since
    432                                 unpark( this->destroyer __cfaabi_dbg_ctx2 );
    433                                 this->destroyer = 0p;
    434                                 break RUNNING;
    435                         case Active:
     430                int old_ticket = __atomic_fetch_sub(&thrd_dst->ticket, 1, __ATOMIC_SEQ_CST);
     431                __cfaabi_dbg_debug_do( thrd_dst->park_result = old_ticket; )
     432                switch(old_ticket) {
     433                        case 1:
    436434                                // This is case 1, the regular case, nothing more is needed
    437435                                break RUNNING;
    438                         case Rerun:
     436                        case 2:
    439437                                // This is case 2, the racy case, someone tried to run this thread before it finished blocking
    440438                                // In this case, just run it again.
     
    442440                        default:
    443441                                // This makes no sense, something is wrong abort
    444                                 abort("Finished running a thread that was Blocked/Start/Primed %d\n", old_state);
     442                                abort();
    445443                }
    446444        }
     
    616614        /* paranoid */  if( thrd->state == Blocked || thrd->state == Start ) assertf( thrd->preempted == __NO_PREEMPTION,
    617615                                        "Error inactive thread marked as preempted, state %d, preemption %d\n", thrd->state, thrd->preempted );
    618         /* paranoid */  if( thrd->preempted != __NO_PREEMPTION ) assertf(thrd->state == Active || thrd->state == Rerun,
     616        /* paranoid */  if( thrd->preempted != __NO_PREEMPTION ) assertf(thrd->state == Active,
    619617                                        "Error preempted thread marked as not currently running, state %d, preemption %d\n", thrd->state, thrd->preempted );
    620618        /* paranoid */ #endif
     
    646644// KERNEL ONLY unpark with out disabling interrupts
    647645void __unpark(  struct __processor_id_t * id, $thread * thrd __cfaabi_dbg_ctx_param2 ) {
    648         static_assert(sizeof(thrd->state) == sizeof(int));
    649 
    650646        // record activity
    651647        __cfaabi_dbg_debug_do( char * old_caller = thrd->unpark_caller; )
    652648        __cfaabi_dbg_record_thrd( *thrd, false, caller );
    653649
    654         enum coroutine_state old_state = __atomic_exchange_n(&thrd->state, Rerun, __ATOMIC_SEQ_CST);
    655         __cfaabi_dbg_debug_do( thrd->unpark_result = old_state; )
    656         switch(old_state) {
    657                 case Active:
     650        int old_ticket = __atomic_fetch_add(&thrd->ticket, 1, __ATOMIC_SEQ_CST);
     651        __cfaabi_dbg_debug_do( thrd->unpark_result = old_ticket; thrd->unpark_state = thrd->state; )
     652        switch(old_ticket) {
     653                case 1:
    658654                        // Wake won the race, the thread will reschedule/rerun itself
    659655                        break;
    660                 case Blocked:
     656                case 0:
    661657                        /* paranoid */ verify( ! thrd->preempted != __NO_PREEMPTION );
     658                        /* paranoid */ verify( thrd->state == Blocked );
    662659
    663660                        // Wake lost the race,
    664                         thrd->state = Blocked;
    665661                        __schedule_thread( id, thrd );
    666662                        break;
    667                 case Rerun:
    668                         abort("More than one thread attempted to schedule thread %p\n", thrd);
    669                         break;
    670                 case Halted:
    671                 case Start:
    672                 case Primed:
    673663                default:
    674664                        // This makes no sense, something is wrong abort
     
    716706
    717707        $thread * thrd = kernelTLS.this_thread;
    718         /* paranoid */ verify(thrd->state == Active || thrd->state == Rerun);
     708        /* paranoid */ verify(thrd->state == Active);
    719709
    720710        // SKULLDUGGERY: It is possible that we are preempting this thread just before
  • libcfa/src/concurrency/thread.cfa

    rcb196f2 rff79d5e  
    2828        context{ 0p, 0p };
    2929        self_cor{ name, storage, storageSize };
     30        ticket = 1;
    3031        state = Start;
    3132        preempted = __NO_PREEMPTION;
  • tools/gdb/utils-gdb.py

    rcb196f2 rff79d5e  
    5959                                         thread_ptr = gdb.lookup_type('struct $thread').pointer(),
    6060                                                int_ptr = gdb.lookup_type('int').pointer(),
    61                                    thread_state = gdb.lookup_type('enum coroutine_state'))
     61                                   thread_state = gdb.lookup_type('enum __Coroutine_State'))
    6262
    6363def get_addr(addr):
Note: See TracChangeset for help on using the changeset viewer.