Ignore:
File:
1 edited

Legend:

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

    r4aa2fb2 r0b33412  
    5959// Global state
    6060
    61 thread_local processor * this_processor;
     61volatile thread_local processor * this_processor;
     62volatile thread_local unsigned short disable_preempt_count;
    6263
    6364coroutine_desc * this_coroutine(void) {
     
    142143        this->preemption_alarm = NULL;
    143144        this->preemption = default_preemption();
    144         this->disable_preempt_count = 1;                //Start with interrupts disabled
    145145        this->pending_preemption = false;
    146146
     
    154154        (&this->terminated){};
    155155        this->is_terminated = false;
    156         this->disable_preempt_count = 0;
     156        this->preemption_alarm = NULL;
     157        this->preemption = default_preemption();
    157158        this->pending_preemption = false;
     159        this->kernel_thread = pthread_self();
    158160
    159161        this->runner = runner;
    160         LIB_DEBUG_PRINT_SAFE("Kernel : constructing processor context %p\n", runner);
     162        LIB_DEBUG_PRINT_SAFE("Kernel : constructing system processor context %p\n", runner);
    161163        runner{ this };
    162164}
     165
     166LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )
    163167
    164168void ?{}(system_proc_t * this, cluster * cltr, processorCtx_t * runner) {
     
    168172
    169173        (&this->proc){ cltr, runner };
     174
     175        verify( validate( &this->alarms ) );
    170176}
    171177
     
    209215                        if(readyThread)
    210216                        {
     217                                verify( disable_preempt_count > 0 );
     218
    211219                                runThread(this, readyThread);
     220
     221                                verify( disable_preempt_count > 0 );
    212222
    213223                                //Some actions need to be taken from the kernel
     
    289299        processor * proc = (processor *) arg;
    290300        this_processor = proc;
     301        disable_preempt_count = 1;
    291302        // SKULLDUGGERY: We want to create a context for the processor coroutine
    292303        // which is needed for the 2-step context switch. However, there is no reason
     
    322333void start(processor * this) {
    323334        LIB_DEBUG_PRINT_SAFE("Kernel : Starting core %p\n", this);
    324        
     335
     336        // SIGALRM must only be caught by the system processor
     337        sigset_t old_mask;
     338        bool is_system_proc = this_processor == &systemProcessor->proc;
     339        if ( is_system_proc ) {
     340                // Child kernel-thread inherits the signal mask from the parent kernel-thread. So one special case for the
     341                // system processor creating the user processor => toggle the blocking SIGALRM on system processor, create user
     342                // processor, and toggle back (below) previous signal mask of the system processor.
     343
     344                sigset_t new_mask;
     345                sigemptyset( &new_mask );
     346                sigemptyset( &old_mask );
     347                sigaddset( &new_mask, SIGALRM );
     348
     349                if ( sigprocmask( SIG_BLOCK, &new_mask, &old_mask ) == -1 ) {
     350                        abortf( "internal error, sigprocmask" );
     351                }
     352
     353                assert( ! sigismember( &old_mask, SIGALRM ) );
     354        }
     355
    325356        pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this );
     357
     358        // Toggle back previous signal mask of system processor.
     359        if ( is_system_proc ) {
     360                if ( sigprocmask( SIG_SETMASK, &old_mask, NULL ) == -1 ) {
     361                        abortf( "internal error, sigprocmask" );
     362                } // if
     363        } // if
    326364
    327365        LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this);       
     
    347385}
    348386
    349 void ScheduleInternal() {
     387void BlockInternal() {
     388        disable_interrupts();
     389        verify( disable_preempt_count > 0 );
    350390        suspend();
    351 }
    352 
    353 void ScheduleInternal( spinlock * lock ) {
     391        verify( disable_preempt_count > 0 );
     392        enable_interrupts( __PRETTY_FUNCTION__ );
     393}
     394
     395void BlockInternal( spinlock * lock ) {
     396        disable_interrupts();
    354397        this_processor->finish.action_code = Release;
    355398        this_processor->finish.lock = lock;
     399
     400        verify( disable_preempt_count > 0 );
    356401        suspend();
    357 }
    358 
    359 void ScheduleInternal( thread_desc * thrd ) {
     402        verify( disable_preempt_count > 0 );
     403
     404        enable_interrupts( __PRETTY_FUNCTION__ );
     405}
     406
     407void BlockInternal( thread_desc * thrd ) {
     408        disable_interrupts();
    360409        this_processor->finish.action_code = Schedule;
    361410        this_processor->finish.thrd = thrd;
     411
     412        verify( disable_preempt_count > 0 );
    362413        suspend();
    363 }
    364 
    365 void ScheduleInternal( spinlock * lock, thread_desc * thrd ) {
     414        verify( disable_preempt_count > 0 );
     415
     416        enable_interrupts( __PRETTY_FUNCTION__ );
     417}
     418
     419void BlockInternal( spinlock * lock, thread_desc * thrd ) {
     420        disable_interrupts();
    366421        this_processor->finish.action_code = Release_Schedule;
    367422        this_processor->finish.lock = lock;
    368423        this_processor->finish.thrd = thrd;
     424
     425        verify( disable_preempt_count > 0 );
    369426        suspend();
    370 }
    371 
    372 void ScheduleInternal(spinlock ** locks, unsigned short count) {
     427        verify( disable_preempt_count > 0 );
     428
     429        enable_interrupts( __PRETTY_FUNCTION__ );
     430}
     431
     432void BlockInternal(spinlock ** locks, unsigned short count) {
     433        disable_interrupts();
    373434        this_processor->finish.action_code = Release_Multi;
    374435        this_processor->finish.locks = locks;
    375436        this_processor->finish.lock_count = count;
     437
     438        verify( disable_preempt_count > 0 );
    376439        suspend();
    377 }
    378 
    379 void ScheduleInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
     440        verify( disable_preempt_count > 0 );
     441
     442        enable_interrupts( __PRETTY_FUNCTION__ );
     443}
     444
     445void BlockInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
     446        disable_interrupts();
    380447        this_processor->finish.action_code = Release_Multi_Schedule;
    381448        this_processor->finish.locks = locks;
     
    383450        this_processor->finish.thrds = thrds;
    384451        this_processor->finish.thrd_count = thrd_count;
     452
     453        verify( disable_preempt_count > 0 );
    385454        suspend();
     455        verify( disable_preempt_count > 0 );
     456
     457        enable_interrupts( __PRETTY_FUNCTION__ );
    386458}
    387459
     
    403475        LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n");
    404476
    405         // Enable preemption
    406         kernel_start_preemption();
    407 
    408477        // Initialize the system cluster
    409478        systemCluster = (cluster *)&systemCluster_storage;
     
    425494        this_processor->current_thread = mainThread;
    426495        this_processor->current_coroutine = &mainThread->cor;
     496        disable_preempt_count = 1;
     497
     498        // Enable preemption
     499        kernel_start_preemption();
    427500
    428501        // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX
     
    435508        // THE SYSTEM IS NOW COMPLETELY RUNNING
    436509        LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n");
     510
     511        enable_interrupts( __PRETTY_FUNCTION__ );
    437512}
    438513
    439514void kernel_shutdown(void) {
    440515        LIB_DEBUG_PRINT_SAFE("\n--------------------------------------------------\nKernel : Shutting down\n");
     516
     517        disable_interrupts();
    441518
    442519        // SKULLDUGGERY: Notify the systemProcessor it needs to terminates.
     
    447524
    448525        // THE SYSTEM IS NOW COMPLETELY STOPPED
     526
     527        // Disable preemption
     528        kernel_stop_preemption();
    449529
    450530        // Destroy the system processor and its context in reverse order of construction
     
    550630        if( !this->cond ) {
    551631                append( &this->blocked, this_thread() );
    552                 ScheduleInternal( &this->lock );
    553                 lock( &this->lock );
    554         }
    555         unlock( &this->lock );
     632                BlockInternal( &this->lock );
     633        }
     634        else {
     635                unlock( &this->lock );
     636        }
    556637}
    557638
     
    561642                this->cond = true;
    562643
     644                disable_interrupts();
    563645                thread_desc * it;
    564646                while( it = pop_head( &this->blocked) ) {
    565647                        ScheduleThread( it );
    566648                }
     649                enable_interrupts( __PRETTY_FUNCTION__ );
    567650        }
    568651        unlock( &this->lock );
Note: See TracChangeset for help on using the changeset viewer.