Ignore:
File:
1 edited

Legend:

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

    r58688bf rb4b63e8  
    108108static $thread * __next_thread_slow(cluster * this);
    109109static void __run_thread(processor * this, $thread * dst);
    110 static void __wake_one(cluster * cltr);
     110static void __wake_one(struct __processor_id_t * id, cluster * cltr);
    111111
    112112static void push  (__cluster_idles & idles, processor & proc);
     
    252252                /* paranoid */ verify( kernelTLS.this_thread == thrd_dst );
    253253                /* paranoid */ verify( thrd_dst->context.SP );
    254                 /* paranoid */ verify( thrd_dst->state != Halted );
    255254                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ) || thrd_dst->curr_cor == proc_cor, "ERROR : Destination $thread %p has been corrupted.\n StackPointer too small.\n", thrd_dst ); // add escape condition if we are setting up the processor
    256255                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit) || thrd_dst->curr_cor == proc_cor, "ERROR : Destination $thread %p has been corrupted.\n StackPointer too large.\n", thrd_dst ); // add escape condition if we are setting up the processor
     
    282281                if(unlikely(thrd_dst->preempted != __NO_PREEMPTION)) {
    283282                        // The thread was preempted, reschedule it and reset the flag
    284                         __schedule_thread( thrd_dst );
     283                        __schedule_thread( (__processor_id_t*)this, thrd_dst );
    285284                        break RUNNING;
    286285                }
     
    288287                if(unlikely(thrd_dst->state == Halted)) {
    289288                        // The thread has halted, it should never be scheduled/run again
    290                         // finish the thread
    291                         __thread_finish( thrd_dst );
     289                        // We may need to wake someone up here since
     290                        unpark( this->destroyer );
     291                        this->destroyer = 0p;
    292292                        break RUNNING;
    293293                }
     
    299299                int old_ticket = __atomic_fetch_sub(&thrd_dst->ticket, 1, __ATOMIC_SEQ_CST);
    300300                switch(old_ticket) {
    301                         case TICKET_RUNNING:
     301                        case 1:
    302302                                // This is case 1, the regular case, nothing more is needed
    303303                                break RUNNING;
    304                         case TICKET_UNBLOCK:
     304                        case 2:
    305305                                // This is case 2, the racy case, someone tried to run this thread before it finished blocking
    306306                                // In this case, just run it again.
     
    358358// Scheduler routines
    359359// KERNEL ONLY
    360 void __schedule_thread( $thread * thrd ) {
     360void __schedule_thread( struct __processor_id_t * id, $thread * thrd ) {
    361361        /* paranoid */ verify( thrd );
    362362        /* paranoid */ verify( thrd->state != Halted );
    363363        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    364         /* paranoid */ verify( kernelTLS.this_proc_id );
    365364        /* paranoid */ #if defined( __CFA_WITH_VERIFY__ )
    366365        /* paranoid */  if( thrd->state == Blocked || thrd->state == Start ) assertf( thrd->preempted == __NO_PREEMPTION,
     
    375374        if (thrd->preempted == __NO_PREEMPTION) thrd->state = Ready;
    376375
    377         ready_schedule_lock();
     376        ready_schedule_lock  ( id );
    378377                push( thrd->curr_cluster, thrd );
    379                 __wake_one(thrd->curr_cluster);
    380         ready_schedule_unlock();
     378                __wake_one(id, thrd->curr_cluster);
     379        ready_schedule_unlock( id );
    381380
    382381        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     
    385384// KERNEL ONLY
    386385static inline $thread * __next_thread(cluster * this) with( *this ) {
    387         /* paranoid */ verify( kernelTLS.this_proc_id );
    388         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    389 
    390         ready_schedule_lock();
     386        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     387
     388        ready_schedule_lock  ( (__processor_id_t*)kernelTLS.this_processor );
    391389                $thread * thrd = pop( this );
    392         ready_schedule_unlock();
    393 
    394         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    395         /* paranoid */ verify( kernelTLS.this_proc_id );
     390        ready_schedule_unlock( (__processor_id_t*)kernelTLS.this_processor );
     391
     392        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    396393        return thrd;
    397394}
     
    399396// KERNEL ONLY
    400397static inline $thread * __next_thread_slow(cluster * this) with( *this ) {
    401         /* paranoid */ verify( kernelTLS.this_proc_id );
    402         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    403 
    404         ready_schedule_lock();
     398        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     399
     400        ready_schedule_lock  ( (__processor_id_t*)kernelTLS.this_processor );
    405401                $thread * thrd = pop_slow( this );
    406         ready_schedule_unlock();
    407 
    408         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    409         /* paranoid */ verify( kernelTLS.this_proc_id );
     402        ready_schedule_unlock( (__processor_id_t*)kernelTLS.this_processor );
     403
     404        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    410405        return thrd;
    411406}
    412407
    413 void unpark( $thread * thrd ) {
    414         if( !thrd ) return;
    415 
    416         /* paranoid */ verify( kernelTLS.this_proc_id );
    417         bool full = kernelTLS.this_proc_id->full_proc;
    418         if(full) disable_interrupts();
    419 
    420         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     408// KERNEL ONLY unpark with out disabling interrupts
     409void __unpark(  struct __processor_id_t * id, $thread * thrd ) {
    421410        int old_ticket = __atomic_fetch_add(&thrd->ticket, 1, __ATOMIC_SEQ_CST);
    422411        switch(old_ticket) {
    423                 case TICKET_RUNNING:
     412                case 1:
    424413                        // Wake won the race, the thread will reschedule/rerun itself
    425414                        break;
    426                 case TICKET_BLOCKED:
     415                case 0:
    427416                        /* paranoid */ verify( ! thrd->preempted != __NO_PREEMPTION );
    428417                        /* paranoid */ verify( thrd->state == Blocked );
    429418
    430419                        // Wake lost the race,
    431                         __schedule_thread( thrd );
     420                        __schedule_thread( id, thrd );
    432421                        break;
    433422                default:
    434423                        // This makes no sense, something is wrong abort
    435                         abort("Thread %p (%s) has mismatch park/unpark\n", thrd, thrd->self_cor.name);
    436         }
    437         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    438 
    439         if(full) enable_interrupts( __cfaabi_dbg_ctx );
    440         /* paranoid */ verify( kernelTLS.this_proc_id );
     424                        abort();
     425        }
     426}
     427
     428void unpark( $thread * thrd ) {
     429        if( !thrd ) return;
     430
     431        disable_interrupts();
     432        __unpark( (__processor_id_t*)kernelTLS.this_processor, thrd );
     433        enable_interrupts( __cfaabi_dbg_ctx );
    441434}
    442435
     
    455448}
    456449
    457 extern "C" {
    458         // Leave the thread monitor
    459         // last routine called by a thread.
    460         // Should never return
    461         void __cfactx_thrd_leave() {
    462                 $thread * thrd = TL_GET( this_thread );
    463                 $monitor * this = &thrd->self_mon;
    464 
    465                 // Lock the monitor now
    466                 lock( this->lock __cfaabi_dbg_ctx2 );
    467 
    468                 disable_interrupts();
    469 
    470                 thrd->state = Halted;
    471                 if( TICKET_RUNNING != thrd->ticket ) { abort( "Thread terminated with pending unpark" ); }
    472                 if( thrd != this->owner || this->recursion != 1) { abort( "Thread internal monitor has unbalanced recursion" ); }
    473 
    474                 // Leave the thread
    475                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    476                 returnToKernel();
    477                 abort();
    478 
    479                 // Control flow should never reach here!
    480         }
     450// KERNEL ONLY
     451void __leave_thread() {
     452        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     453        returnToKernel();
     454        abort();
    481455}
    482456
     
    512486//=============================================================================================
    513487// Wake a thread from the front if there are any
    514 static void __wake_one(cluster * this) {
    515         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    516         /* paranoid */ verify( ready_schedule_islocked() );
     488static void __wake_one(struct __processor_id_t * id, cluster * this) {
     489        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     490        /* paranoid */ verify( ready_schedule_islocked( id ) );
    517491
    518492        // Check if there is a sleeping processor
     
    532506        #endif
    533507
    534         /* paranoid */ verify( ready_schedule_islocked() );
     508        /* paranoid */ verify( ready_schedule_islocked( id ) );
    535509        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    536510
     
    735709                this.print_halts = true;
    736710        }
    737 
    738         void print_stats_now( cluster & this, int flags ) {
    739                 __print_stats( this.stats, this.print_stats, true, this.name, (void*)&this );
    740         }
    741711#endif
    742712// Local Variables: //
Note: See TracChangeset for help on using the changeset viewer.