Ignore:
File:
1 edited

Legend:

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

    rc40e7c5 rb69ea6b  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  6 21:51:26 2018
    13 // Update Count     : 4
     12// Last Modified On : Thu Feb  8 23:52:19 2018
     13// Update Count     : 5
    1414//
    1515
    1616//C Includes
    1717#include <stddef.h>
    18 #define ftype `ftype`
    1918extern "C" {
    2019#include <stdio.h>
     
    2423#include <unistd.h>
    2524}
    26 #undef ftype
    2725
    2826//CFA Includes
     
    5856thread_local processor *      volatile this_processor;
    5957
    60 volatile thread_local bool preemption_in_progress = 0;
    61 volatile thread_local bool preemption_enabled = false;
    62 volatile thread_local unsigned short disable_preempt_count = 1;
     58// volatile thread_local bool preemption_in_progress = 0;
     59// volatile thread_local bool preemption_enabled = false;
     60// volatile thread_local unsigned short disable_preempt_count = 1;
     61
     62volatile thread_local __cfa_kernel_preemption_data_t preemption = { false, false, 1 };
    6363
    6464//-----------------------------------------------------------------------------
     
    209209                        if(readyThread)
    210210                        {
    211                                 verify( !preemption_enabled );
     211                                verify( !preemption.enabled );
    212212
    213213                                runThread(this, readyThread);
    214214
    215                                 verify( !preemption_enabled );
     215                                verify( !preemption.enabled );
    216216
    217217                                //Some actions need to be taken from the kernel
     
    262262void finishRunning(processor * this) with( this->finish ) {
    263263        if( action_code == Release ) {
    264                 verify( !preemption_enabled );
     264                verify( !preemption.enabled );
    265265                unlock( *lock );
    266266        }
     
    269269        }
    270270        else if( action_code == Release_Schedule ) {
    271                 verify( !preemption_enabled );
     271                verify( !preemption.enabled );
    272272                unlock( *lock );
    273273                ScheduleThread( thrd );
    274274        }
    275275        else if( action_code == Release_Multi ) {
    276                 verify( !preemption_enabled );
     276                verify( !preemption.enabled );
    277277                for(int i = 0; i < lock_count; i++) {
    278278                        unlock( *locks[i] );
     
    306306        this_coroutine = NULL;
    307307        this_thread = NULL;
    308         preemption_enabled = false;
    309         disable_preempt_count = 1;
     308        preemption.enabled = false;
     309        preemption.disable_count = 1;
    310310        // SKULLDUGGERY: We want to create a context for the processor coroutine
    311311        // which is needed for the 2-step context switch. However, there is no reason
     
    347347}
    348348
     349void kernel_first_resume(processor * this) {
     350        coroutine_desc * src = this_coroutine;
     351        coroutine_desc * dst = get_coroutine(*this->runner);
     352
     353        verify( !preemption.enabled );
     354
     355        create_stack(&dst->stack, dst->stack.size);
     356        CtxStart(this->runner, CtxInvokeCoroutine);
     357
     358        verify( !preemption.enabled );
     359
     360        dst->last = src;
     361        dst->starter = dst->starter ? dst->starter : src;
     362
     363        // set state of current coroutine to inactive
     364        src->state = src->state == Halted ? Halted : Inactive;
     365
     366        // set new coroutine that task is executing
     367        this_coroutine = dst;
     368
     369        // SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch.
     370        // Therefore, when first creating a coroutine, interrupts are enable before calling the main.
     371        // This is consistent with thread creation. However, when creating the main processor coroutine,
     372        // we wan't interrupts to be disabled. Therefore, we double-disable interrupts here so they will
     373        // stay disabled.
     374        disable_interrupts();
     375
     376        // context switch to specified coroutine
     377        assert( src->stack.context );
     378        CtxSwitch( src->stack.context, dst->stack.context );
     379        // when CtxSwitch returns we are back in the src coroutine
     380
     381        // set state of new coroutine to active
     382        src->state = Active;
     383
     384        verify( !preemption.enabled );
     385}
     386
    349387//-----------------------------------------------------------------------------
    350388// Scheduler routines
     
    354392        verify( thrd->self_cor.state != Halted );
    355393
    356         verify( !preemption_enabled );
     394        verify( !preemption.enabled );
    357395
    358396        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
     
    364402        }
    365403
    366         verify( !preemption_enabled );
     404        verify( !preemption.enabled );
    367405}
    368406
    369407thread_desc * nextThread(cluster * this) with( *this ) {
    370         verify( !preemption_enabled );
     408        verify( !preemption.enabled );
    371409        lock( ready_queue_lock __cfaabi_dbg_ctx2 );
    372410        thread_desc * head = pop_head( ready_queue );
    373411        unlock( ready_queue_lock );
    374         verify( !preemption_enabled );
     412        verify( !preemption.enabled );
    375413        return head;
    376414}
     
    378416void BlockInternal() {
    379417        disable_interrupts();
    380         verify( !preemption_enabled );
     418        verify( !preemption.enabled );
    381419        returnToKernel();
    382         verify( !preemption_enabled );
     420        verify( !preemption.enabled );
    383421        enable_interrupts( __cfaabi_dbg_ctx );
    384422}
     
    389427        this_processor->finish.lock        = lock;
    390428
    391         verify( !preemption_enabled );
     429        verify( !preemption.enabled );
    392430        returnToKernel();
    393         verify( !preemption_enabled );
     431        verify( !preemption.enabled );
    394432
    395433        enable_interrupts( __cfaabi_dbg_ctx );
     
    401439        this_processor->finish.thrd        = thrd;
    402440
    403         verify( !preemption_enabled );
     441        verify( !preemption.enabled );
    404442        returnToKernel();
    405         verify( !preemption_enabled );
     443        verify( !preemption.enabled );
    406444
    407445        enable_interrupts( __cfaabi_dbg_ctx );
     
    415453        this_processor->finish.thrd        = thrd;
    416454
    417         verify( !preemption_enabled );
     455        verify( !preemption.enabled );
    418456        returnToKernel();
    419         verify( !preemption_enabled );
     457        verify( !preemption.enabled );
    420458
    421459        enable_interrupts( __cfaabi_dbg_ctx );
     
    428466        this_processor->finish.lock_count  = count;
    429467
    430         verify( !preemption_enabled );
     468        verify( !preemption.enabled );
    431469        returnToKernel();
    432         verify( !preemption_enabled );
     470        verify( !preemption.enabled );
    433471
    434472        enable_interrupts( __cfaabi_dbg_ctx );
     
    443481        this_processor->finish.thrd_count  = thrd_count;
    444482
    445         verify( !preemption_enabled );
     483        verify( !preemption.enabled );
    446484        returnToKernel();
    447         verify( !preemption_enabled );
     485        verify( !preemption.enabled );
    448486
    449487        enable_interrupts( __cfaabi_dbg_ctx );
     
    451489
    452490void LeaveThread(__spinlock_t * lock, thread_desc * thrd) {
    453         verify( !preemption_enabled );
     491        verify( !preemption.enabled );
    454492        this_processor->finish.action_code = thrd ? Release_Schedule : Release;
    455493        this_processor->finish.lock        = lock;
     
    465503// Kernel boot procedures
    466504void kernel_startup(void) {
     505        verify( !preemption.enabled );
    467506        __cfaabi_dbg_print_safe("Kernel : Starting\n");
    468507
     
    502541        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
    503542        // mainThread is on the ready queue when this call is made.
    504         resume( *mainProcessor->runner );
     543        kernel_first_resume( this_processor );
    505544
    506545
     
    509548        __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n");
    510549
     550        verify( !preemption.enabled );
    511551        enable_interrupts( __cfaabi_dbg_ctx );
     552        verify( preemption.enabled );
    512553}
    513554
     
    515556        __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n");
    516557
     558        verify( preemption.enabled );
    517559        disable_interrupts();
     560        verify( !preemption.enabled );
    518561
    519562        // SKULLDUGGERY: Notify the mainProcessor it needs to terminates.
Note: See TracChangeset for help on using the changeset viewer.