Ignore:
File:
1 edited

Legend:

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

    rb4b63e8 r58688bf  
    108108static $thread * __next_thread_slow(cluster * this);
    109109static void __run_thread(processor * this, $thread * dst);
    110 static void __wake_one(struct __processor_id_t * id, cluster * cltr);
     110static void __wake_one(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 );
    254255                /* 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
    255256                /* 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
     
    281282                if(unlikely(thrd_dst->preempted != __NO_PREEMPTION)) {
    282283                        // The thread was preempted, reschedule it and reset the flag
    283                         __schedule_thread( (__processor_id_t*)this, thrd_dst );
     284                        __schedule_thread( thrd_dst );
    284285                        break RUNNING;
    285286                }
     
    287288                if(unlikely(thrd_dst->state == Halted)) {
    288289                        // The thread has halted, it should never be scheduled/run again
    289                         // We may need to wake someone up here since
    290                         unpark( this->destroyer );
    291                         this->destroyer = 0p;
     290                        // finish the thread
     291                        __thread_finish( thrd_dst );
    292292                        break RUNNING;
    293293                }
     
    299299                int old_ticket = __atomic_fetch_sub(&thrd_dst->ticket, 1, __ATOMIC_SEQ_CST);
    300300                switch(old_ticket) {
    301                         case 1:
     301                        case TICKET_RUNNING:
    302302                                // This is case 1, the regular case, nothing more is needed
    303303                                break RUNNING;
    304                         case 2:
     304                        case TICKET_UNBLOCK:
    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( struct __processor_id_t * id, $thread * thrd ) {
     360void __schedule_thread( $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 );
    364365        /* paranoid */ #if defined( __CFA_WITH_VERIFY__ )
    365366        /* paranoid */  if( thrd->state == Blocked || thrd->state == Start ) assertf( thrd->preempted == __NO_PREEMPTION,
     
    374375        if (thrd->preempted == __NO_PREEMPTION) thrd->state = Ready;
    375376
    376         ready_schedule_lock  ( id );
     377        ready_schedule_lock();
    377378                push( thrd->curr_cluster, thrd );
    378                 __wake_one(id, thrd->curr_cluster);
    379         ready_schedule_unlock( id );
     379                __wake_one(thrd->curr_cluster);
     380        ready_schedule_unlock();
    380381
    381382        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     
    384385// KERNEL ONLY
    385386static inline $thread * __next_thread(cluster * this) with( *this ) {
    386         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    387 
    388         ready_schedule_lock  ( (__processor_id_t*)kernelTLS.this_processor );
     387        /* paranoid */ verify( kernelTLS.this_proc_id );
     388        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     389
     390        ready_schedule_lock();
    389391                $thread * thrd = pop( this );
    390         ready_schedule_unlock( (__processor_id_t*)kernelTLS.this_processor );
    391 
    392         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     392        ready_schedule_unlock();
     393
     394        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     395        /* paranoid */ verify( kernelTLS.this_proc_id );
    393396        return thrd;
    394397}
     
    396399// KERNEL ONLY
    397400static inline $thread * __next_thread_slow(cluster * this) with( *this ) {
    398         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    399 
    400         ready_schedule_lock  ( (__processor_id_t*)kernelTLS.this_processor );
     401        /* paranoid */ verify( kernelTLS.this_proc_id );
     402        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     403
     404        ready_schedule_lock();
    401405                $thread * thrd = pop_slow( this );
    402         ready_schedule_unlock( (__processor_id_t*)kernelTLS.this_processor );
    403 
    404         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     406        ready_schedule_unlock();
     407
     408        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     409        /* paranoid */ verify( kernelTLS.this_proc_id );
    405410        return thrd;
    406411}
    407412
    408 // KERNEL ONLY unpark with out disabling interrupts
    409 void __unpark(  struct __processor_id_t * id, $thread * thrd ) {
     413void 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 );
    410421        int old_ticket = __atomic_fetch_add(&thrd->ticket, 1, __ATOMIC_SEQ_CST);
    411422        switch(old_ticket) {
    412                 case 1:
     423                case TICKET_RUNNING:
    413424                        // Wake won the race, the thread will reschedule/rerun itself
    414425                        break;
    415                 case 0:
     426                case TICKET_BLOCKED:
    416427                        /* paranoid */ verify( ! thrd->preempted != __NO_PREEMPTION );
    417428                        /* paranoid */ verify( thrd->state == Blocked );
    418429
    419430                        // Wake lost the race,
    420                         __schedule_thread( id, thrd );
     431                        __schedule_thread( thrd );
    421432                        break;
    422433                default:
    423434                        // This makes no sense, something is wrong abort
    424                         abort();
    425         }
    426 }
    427 
    428 void 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 );
     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 );
    434441}
    435442
     
    448455}
    449456
    450 // KERNEL ONLY
    451 void __leave_thread() {
    452         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    453         returnToKernel();
    454         abort();
     457extern "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        }
    455481}
    456482
     
    486512//=============================================================================================
    487513// Wake a thread from the front if there are any
    488 static void __wake_one(struct __processor_id_t * id, cluster * this) {
    489         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    490         /* paranoid */ verify( ready_schedule_islocked( id ) );
     514static void __wake_one(cluster * this) {
     515        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     516        /* paranoid */ verify( ready_schedule_islocked() );
    491517
    492518        // Check if there is a sleeping processor
     
    506532        #endif
    507533
    508         /* paranoid */ verify( ready_schedule_islocked( id ) );
     534        /* paranoid */ verify( ready_schedule_islocked() );
    509535        /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    510536
     
    709735                this.print_halts = true;
    710736        }
     737
     738        void print_stats_now( cluster & this, int flags ) {
     739                __print_stats( this.stats, this.print_stats, true, this.name, (void*)&this );
     740        }
    711741#endif
    712742// Local Variables: //
Note: See TracChangeset for help on using the changeset viewer.