Ignore:
File:
1 edited

Legend:

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

    rc81ebf9 r82ff5845  
    154154        (&this->terminated){};
    155155        this->is_terminated = false;
    156         this->disable_preempt_count = 0;
     156        this->preemption_alarm = NULL;
     157        this->preemption = default_preemption();
     158        this->disable_preempt_count = 1;
    157159        this->pending_preemption = false;
     160        this->kernel_thread = pthread_self();
    158161
    159162        this->runner = runner;
    160         LIB_DEBUG_PRINT_SAFE("Kernel : constructing processor context %p\n", runner);
     163        LIB_DEBUG_PRINT_SAFE("Kernel : constructing system processor context %p\n", runner);
    161164        runner{ this };
    162165}
     
    240243        //Update global state
    241244        this->current_thread = dst;
     245
     246        LIB_DEBUG_PRINT_SAFE("Kernel : running %p\n", dst);
    242247
    243248        // Context Switch to the thread
     
    322327void start(processor * this) {
    323328        LIB_DEBUG_PRINT_SAFE("Kernel : Starting core %p\n", this);
    324        
     329
     330        // SIGALRM must only be caught by the system processor
     331        sigset_t old_mask;
     332        bool is_system_proc = this_processor == &systemProcessor->proc;
     333        if ( is_system_proc ) {
     334                // Child kernel-thread inherits the signal mask from the parent kernel-thread. So one special case for the
     335                // system processor creating the user processor => toggle the blocking SIGALRM on system processor, create user
     336                // processor, and toggle back (below) previous signal mask of the system processor.
     337
     338                sigset_t new_mask;
     339                sigemptyset( &new_mask );
     340                sigemptyset( &old_mask );
     341                sigaddset( &new_mask, SIGALRM );
     342
     343                if ( sigprocmask( SIG_BLOCK, &new_mask, &old_mask ) == -1 ) {
     344                        abortf( "internal error, sigprocmask" );
     345                }
     346
     347                assert( ! sigismember( &old_mask, SIGALRM ) );
     348        }
     349
    325350        pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this );
     351
     352        // Toggle back previous signal mask of system processor.
     353        if ( is_system_proc ) {
     354                if ( sigprocmask( SIG_SETMASK, &old_mask, NULL ) == -1 ) {
     355                        abortf( "internal error, sigprocmask" );
     356                } // if
     357        } // if
    326358
    327359        LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this);       
     
    347379}
    348380
    349 void ScheduleInternal() {
     381void BlockInternal() {
     382        disable_interrupts();
    350383        suspend();
    351 }
    352 
    353 void ScheduleInternal( spinlock * lock ) {
     384        enable_interrupts();
     385}
     386
     387void BlockInternal( spinlock * lock ) {
     388        disable_interrupts();
    354389        this_processor->finish.action_code = Release;
    355390        this_processor->finish.lock = lock;
    356391        suspend();
    357 }
    358 
    359 void ScheduleInternal( thread_desc * thrd ) {
     392        enable_interrupts();
     393}
     394
     395void BlockInternal( thread_desc * thrd ) {
     396        disable_interrupts();
    360397        this_processor->finish.action_code = Schedule;
    361398        this_processor->finish.thrd = thrd;
    362399        suspend();
    363 }
    364 
    365 void ScheduleInternal( spinlock * lock, thread_desc * thrd ) {
     400        enable_interrupts();
     401}
     402
     403void BlockInternal( spinlock * lock, thread_desc * thrd ) {
     404        disable_interrupts();
    366405        this_processor->finish.action_code = Release_Schedule;
    367406        this_processor->finish.lock = lock;
    368407        this_processor->finish.thrd = thrd;
    369408        suspend();
    370 }
    371 
    372 void ScheduleInternal(spinlock ** locks, unsigned short count) {
     409        enable_interrupts();
     410}
     411
     412void BlockInternal(spinlock ** locks, unsigned short count) {
     413        disable_interrupts();
    373414        this_processor->finish.action_code = Release_Multi;
    374415        this_processor->finish.locks = locks;
    375416        this_processor->finish.lock_count = count;
    376417        suspend();
    377 }
    378 
    379 void ScheduleInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
     418        enable_interrupts();
     419}
     420
     421void BlockInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
     422        disable_interrupts();
    380423        this_processor->finish.action_code = Release_Multi_Schedule;
    381424        this_processor->finish.locks = locks;
     
    384427        this_processor->finish.thrd_count = thrd_count;
    385428        suspend();
     429        enable_interrupts();
    386430}
    387431
     
    403447        LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n");
    404448
    405         // Enable preemption
    406         kernel_start_preemption();
    407 
    408449        // Initialize the system cluster
    409450        systemCluster = (cluster *)&systemCluster_storage;
     
    426467        this_processor->current_coroutine = &mainThread->cor;
    427468
     469        // Enable preemption
     470        kernel_start_preemption();
     471
    428472        // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX
    429473        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
     
    435479        // THE SYSTEM IS NOW COMPLETELY RUNNING
    436480        LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n");
     481
     482        enable_interrupts();
    437483}
    438484
     
    447493
    448494        // THE SYSTEM IS NOW COMPLETELY STOPPED
     495
     496        // Disable preemption
     497        kernel_stop_preemption();
    449498
    450499        // Destroy the system processor and its context in reverse order of construction
     
    550599        if( !this->cond ) {
    551600                append( &this->blocked, this_thread() );
    552                 ScheduleInternal( &this->lock );
     601                BlockInternal( &this->lock );
    553602                lock( &this->lock );
    554603        }
Note: See TracChangeset for help on using the changeset viewer.