Changeset ff79d5e
- Timestamp:
- Jun 12, 2020, 5:01:21 PM (3 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 2649ff9
- Parents:
- cb196f2
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/invoke.h
rcb196f2 rff79d5e 92 92 }; 93 93 94 enum coroutine_state { Halted, Start, Primed, Blocked, Ready, Active, Rerun};94 enum __Coroutine_State { Halted, Start, Primed, Blocked, Ready, Active }; 95 95 enum __Preemption_Reason { __NO_PREEMPTION, __ALARM_PREEMPTION, __POLL_PREEMPTION, __MANUAL_PREEMPTION }; 96 96 … … 106 106 107 107 // current execution status for coroutine 108 enum coroutine_state state;108 enum __Coroutine_State state; 109 109 110 110 // first coroutine to resume this one … … 175 175 176 176 // 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; 179 180 180 181 //SKULLDUGGERY errno is not save in the thread data structure because returnToKernel appears to be the only function to require saving and restoring it … … 210 211 // previous function to park/unpark the thread 211 212 const char * park_caller; 212 enum coroutine_state park_result; 213 int park_result; 214 enum __Coroutine_State park_state; 213 215 bool park_stale; 214 216 const char * unpark_caller; 215 enum coroutine_state unpark_result; 217 int unpark_result; 218 enum __Coroutine_State unpark_state; 216 219 bool unpark_stale; 217 220 #endif -
libcfa/src/concurrency/kernel.cfa
rcb196f2 rff79d5e 192 192 193 193 void ?{}( $thread & this, current_stack_info_t * info) with( this ) { 194 ticket = 1; 194 195 state = Start; 195 196 self_cor{ info }; … … 378 379 // Actually run the thread 379 380 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; 387 383 388 384 __cfaabi_dbg_debug_do( … … 420 416 } 421 417 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 422 429 // 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: 436 434 // This is case 1, the regular case, nothing more is needed 437 435 break RUNNING; 438 case Rerun:436 case 2: 439 437 // This is case 2, the racy case, someone tried to run this thread before it finished blocking 440 438 // In this case, just run it again. … … 442 440 default: 443 441 // 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(); 445 443 } 446 444 } … … 616 614 /* paranoid */ if( thrd->state == Blocked || thrd->state == Start ) assertf( thrd->preempted == __NO_PREEMPTION, 617 615 "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, 619 617 "Error preempted thread marked as not currently running, state %d, preemption %d\n", thrd->state, thrd->preempted ); 620 618 /* paranoid */ #endif … … 646 644 // KERNEL ONLY unpark with out disabling interrupts 647 645 void __unpark( struct __processor_id_t * id, $thread * thrd __cfaabi_dbg_ctx_param2 ) { 648 static_assert(sizeof(thrd->state) == sizeof(int));649 650 646 // record activity 651 647 __cfaabi_dbg_debug_do( char * old_caller = thrd->unpark_caller; ) 652 648 __cfaabi_dbg_record_thrd( *thrd, false, caller ); 653 649 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: 658 654 // Wake won the race, the thread will reschedule/rerun itself 659 655 break; 660 case Blocked:656 case 0: 661 657 /* paranoid */ verify( ! thrd->preempted != __NO_PREEMPTION ); 658 /* paranoid */ verify( thrd->state == Blocked ); 662 659 663 660 // Wake lost the race, 664 thrd->state = Blocked;665 661 __schedule_thread( id, thrd ); 666 662 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:673 663 default: 674 664 // This makes no sense, something is wrong abort … … 716 706 717 707 $thread * thrd = kernelTLS.this_thread; 718 /* paranoid */ verify(thrd->state == Active || thrd->state == Rerun);708 /* paranoid */ verify(thrd->state == Active); 719 709 720 710 // SKULLDUGGERY: It is possible that we are preempting this thread just before -
libcfa/src/concurrency/thread.cfa
rcb196f2 rff79d5e 28 28 context{ 0p, 0p }; 29 29 self_cor{ name, storage, storageSize }; 30 ticket = 1; 30 31 state = Start; 31 32 preempted = __NO_PREEMPTION; -
tools/gdb/utils-gdb.py
rcb196f2 rff79d5e 59 59 thread_ptr = gdb.lookup_type('struct $thread').pointer(), 60 60 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')) 62 62 63 63 def get_addr(addr):
Note: See TracChangeset
for help on using the changeset viewer.