Ignore:
File:
1 edited

Legend:

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

    r4aa2fb2 r4e6fb8e  
    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        LIB_DEBUG_DO( assert( validate( &this->alarms ) ) );
    170176}
    171177
     
    209215                        if(readyThread)
    210216                        {
     217                                assert( disable_preempt_count > 0 );
     218
    211219                                runThread(this, readyThread);
     220
     221                                assert( 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
     
    311322        // appropriate stack.
    312323        proc_cor_storage.__cor.state = Active;
    313         main( &proc_cor_storage );
    314         proc_cor_storage.__cor.state = Halted;
     324      main( &proc_cor_storage );
     325      proc_cor_storage.__cor.state = Halted;
    315326
    316327        // Main routine of the core returned, the core is now fully terminated
     
    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);       
     
    333371        if( !thrd ) return;
    334372
    335         verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
     373        assertf( thrd->next == NULL, "Expected null got %p", thrd->next );
    336374       
    337375        lock( &systemProcessor->proc.cltr->lock );
     
    347385}
    348386
    349 void ScheduleInternal() {
     387void BlockInternal() {
     388        disable_interrupts();
     389        assert( disable_preempt_count > 0 );
    350390        suspend();
    351 }
    352 
    353 void ScheduleInternal( spinlock * lock ) {
     391        assert( 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        assert( disable_preempt_count > 0 );
    356400        suspend();
    357 }
    358 
    359 void ScheduleInternal( thread_desc * thrd ) {
     401        assert( disable_preempt_count > 0 );
     402        enable_interrupts( __PRETTY_FUNCTION__ );
     403}
     404
     405void BlockInternal( thread_desc * thrd ) {
     406        disable_interrupts();
    360407        this_processor->finish.action_code = Schedule;
    361408        this_processor->finish.thrd = thrd;
     409        assert( disable_preempt_count > 0 );
    362410        suspend();
    363 }
    364 
    365 void ScheduleInternal( spinlock * lock, thread_desc * thrd ) {
     411        assert( disable_preempt_count > 0 );
     412        enable_interrupts( __PRETTY_FUNCTION__ );
     413}
     414
     415void BlockInternal( spinlock * lock, thread_desc * thrd ) {
     416        disable_interrupts();
    366417        this_processor->finish.action_code = Release_Schedule;
    367418        this_processor->finish.lock = lock;
    368419        this_processor->finish.thrd = thrd;
     420        assert( disable_preempt_count > 0 );
    369421        suspend();
    370 }
    371 
    372 void ScheduleInternal(spinlock ** locks, unsigned short count) {
     422        assert( disable_preempt_count > 0 );
     423        enable_interrupts( __PRETTY_FUNCTION__ );
     424}
     425
     426void BlockInternal(spinlock ** locks, unsigned short count) {
     427        disable_interrupts();
    373428        this_processor->finish.action_code = Release_Multi;
    374429        this_processor->finish.locks = locks;
    375430        this_processor->finish.lock_count = count;
     431        assert( disable_preempt_count > 0 );
    376432        suspend();
    377 }
    378 
    379 void ScheduleInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
     433        assert( disable_preempt_count > 0 );
     434        enable_interrupts( __PRETTY_FUNCTION__ );
     435}
     436
     437void BlockInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
     438        disable_interrupts();
    380439        this_processor->finish.action_code = Release_Multi_Schedule;
    381440        this_processor->finish.locks = locks;
     
    383442        this_processor->finish.thrds = thrds;
    384443        this_processor->finish.thrd_count = thrd_count;
     444        assert( disable_preempt_count > 0 );
    385445        suspend();
     446        assert( disable_preempt_count > 0 );
     447        enable_interrupts( __PRETTY_FUNCTION__ );
    386448}
    387449
     
    403465        LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n");
    404466
    405         // Enable preemption
    406         kernel_start_preemption();
    407 
    408467        // Initialize the system cluster
    409468        systemCluster = (cluster *)&systemCluster_storage;
     
    425484        this_processor->current_thread = mainThread;
    426485        this_processor->current_coroutine = &mainThread->cor;
     486        disable_preempt_count = 1;
     487
     488        // Enable preemption
     489        kernel_start_preemption();
    427490
    428491        // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX
     
    435498        // THE SYSTEM IS NOW COMPLETELY RUNNING
    436499        LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n");
     500
     501        enable_interrupts( __PRETTY_FUNCTION__ );
    437502}
    438503
    439504void kernel_shutdown(void) {
    440505        LIB_DEBUG_PRINT_SAFE("\n--------------------------------------------------\nKernel : Shutting down\n");
     506
     507        disable_interrupts();
    441508
    442509        // SKULLDUGGERY: Notify the systemProcessor it needs to terminates.
     
    447514
    448515        // THE SYSTEM IS NOW COMPLETELY STOPPED
     516
     517        // Disable preemption
     518        kernel_stop_preemption();
    449519
    450520        // Destroy the system processor and its context in reverse order of construction
     
    550620        if( !this->cond ) {
    551621                append( &this->blocked, this_thread() );
    552                 ScheduleInternal( &this->lock );
    553                 lock( &this->lock );
    554         }
    555         unlock( &this->lock );
     622                BlockInternal( &this->lock );
     623        }
     624        else {
     625                unlock( &this->lock );
     626        }
    556627}
    557628
     
    561632                this->cond = true;
    562633
     634                disable_interrupts();
    563635                thread_desc * it;
    564636                while( it = pop_head( &this->blocked) ) {
    565637                        ScheduleThread( it );
    566638                }
     639                enable_interrupts( __PRETTY_FUNCTION__ );
    567640        }
    568641        unlock( &this->lock );
     
    577650
    578651void append( __thread_queue_t * this, thread_desc * t ) {
    579         verify(this->tail != NULL);
     652        assert(this->tail != NULL);
    580653        *this->tail = t;
    581654        this->tail = &t->next;
     
    599672
    600673void push( __condition_stack_t * this, __condition_criterion_t * t ) {
    601         verify( !t->next );
     674        assert( !t->next );
    602675        t->next = this->top;
    603676        this->top = t;
Note: See TracChangeset for help on using the changeset viewer.