Changeset de6319f


Ignore:
Timestamp:
Apr 26, 2018, 5:23:15 PM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, with_gc
Children:
b9f383f
Parents:
22bdc34
Message:

Implemented clusters and added many constructors for threads/coroutines/processors

Location:
src/libcfa/concurrency
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/coroutine

    r22bdc34 rde6319f  
    3232//-----------------------------------------------------------------------------
    3333// Ctors and dtors
    34 void ?{}(coStack_t & this);
    35 void ?{}(coroutine_desc & this);
    36 void ?{}(coroutine_desc & this, const char * name);
    37 void ^?{}(coStack_t & this);
    38 void ^?{}(coroutine_desc & this);
     34// void ?{}( coStack_t & this );
     35// void ^?{}( coStack_t & this );
     36
     37void ?{}( coroutine_desc & this, const char * name, void * storage, size_t storageSize );
     38void ^?{}( coroutine_desc & this );
     39
     40static inline void ?{}( coroutine_desc & this)                                       { this{ "Anonymous Coroutine", NULL, 0 }; }
     41static inline void ?{}( coroutine_desc & this, size_t stackSize)                     { this{ "Anonymous Coroutine", NULL, stackSize }; }
     42static inline void ?{}( coroutine_desc & this, void * storage, size_t storageSize )  { this{ "Anonymous Coroutine", storage, storageSize }; }
     43static inline void ?{}( coroutine_desc & this, const char * name)                    { this{ name, NULL, 0 }; }
     44static inline void ?{}( coroutine_desc & this, const char * name, size_t stackSize ) { this{ name, NULL, stackSize }; }
    3945
    4046//-----------------------------------------------------------------------------
  • src/libcfa/concurrency/coroutine.c

    r22bdc34 rde6319f  
    3939//-----------------------------------------------------------------------------
    4040// Coroutine ctors and dtors
    41 void ?{}(coStack_t& this) with( this ) {
    42         size            = 65000;        // size of stack
    43         storage = NULL; // pointer to stack
    44         limit           = NULL; // stack grows towards stack limit
    45         base            = NULL; // base of stack
    46         context = NULL; // address of cfa_context_t
    47         top             = NULL; // address of top of storage
    48         userStack       = false;
    49 }
    50 
    51 void ?{}(coStack_t& this, size_t size) {
    52         this{};
    53         this.size = size;
    54 
    55         create_stack(&this, this.size);
    56 }
    57 
    58 void ?{}(coroutine_desc& this) {
    59         this{ "Anonymous Coroutine" };
    60 }
    61 
    62 void ?{}(coroutine_desc& this, const char * name) with( this ) {
    63         this.name = name;
    64         errno_ = 0;
    65         state = Start;
    66         starter = NULL;
    67         last = NULL;
    68 }
    69 
    70 void ?{}(coroutine_desc& this, size_t size) {
    71         this{};
    72         (this.stack){size};
     41void ?{}( coStack_t & this, void * storage, size_t storageSize ) with( this ) {
     42      size               = storageSize == 0 ? 65000 : storageSize; // size of stack
     43      this.storage = storage;                                // pointer to stack
     44      limit              = NULL;                                   // stack grows towards stack limit
     45      base               = NULL;                                   // base of stack
     46      context    = NULL;                                   // address of cfa_context_t
     47      top                = NULL;                                   // address of top of storage
     48      userStack  = storage != NULL;
    7349}
    7450
    7551void ^?{}(coStack_t & this) {
    76         if ( ! this.userStack && this.storage ) {
    77                 __cfaabi_dbg_debug_do(
    78                         if ( mprotect( this.storage, pageSize, PROT_READ | PROT_WRITE ) == -1 ) {
    79                                 abort( "(coStack_t *)%p.^?{}() : internal error, mprotect failure, error(%d) %s.", &this, errno, strerror( errno ) );
    80                         }
    81                 );
    82                 free( this.storage );
    83         }
     52      if ( ! this.userStack && this.storage ) {
     53            __cfaabi_dbg_debug_do(
     54                  if ( mprotect( this.storage, pageSize, PROT_READ | PROT_WRITE ) == -1 ) {
     55                        abort( "(coStack_t *)%p.^?{}() : internal error, mprotect failure, error(%d) %s.", &this, errno, strerror( errno ) );
     56                  }
     57            );
     58            free( this.storage );
     59      }
     60}
     61
     62void ?{}( coroutine_desc & this, const char * name, void * storage, size_t storageSize ) with( this ) {
     63      (this.stack){storage, storageSize};
     64      this.name = name;
     65      errno_ = 0;
     66      state = Start;
     67      starter = NULL;
     68      last = NULL;
    8469}
    8570
     
    9075forall(dtype T | is_coroutine(T))
    9176void prime(T& cor) {
    92         coroutine_desc* this = get_coroutine(cor);
    93         assert(this->state == Start);
     77      coroutine_desc* this = get_coroutine(cor);
     78      assert(this->state == Start);
    9479
    95         this->state = Primed;
    96         resume(cor);
     80      this->state = Primed;
     81      resume(cor);
    9782}
    9883
    9984// Wrapper for co
    10085void CoroutineCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {
    101         verify( TL_GET( preemption_state ).enabled || TL_GET( this_processor )->do_terminate );
    102         disable_interrupts();
     86      verify( TL_GET( preemption_state ).enabled || TL_GET( this_processor )->do_terminate );
     87      disable_interrupts();
    10388
    104         // set state of current coroutine to inactive
    105         src->state = src->state == Halted ? Halted : Inactive;
     89      // set state of current coroutine to inactive
     90      src->state = src->state == Halted ? Halted : Inactive;
    10691
    107         // set new coroutine that task is executing
    108         TL_SET( this_coroutine, dst );
     92      // set new coroutine that task is executing
     93      TL_SET( this_coroutine, dst );
    10994
    110         // context switch to specified coroutine
    111         assert( src->stack.context );
    112         CtxSwitch( src->stack.context, dst->stack.context );
    113         // when CtxSwitch returns we are back in the src coroutine
     95      // context switch to specified coroutine
     96      assert( src->stack.context );
     97      CtxSwitch( src->stack.context, dst->stack.context );
     98      // when CtxSwitch returns we are back in the src coroutine
    11499
    115         // set state of new coroutine to active
    116         src->state = Active;
     100      // set state of new coroutine to active
     101      src->state = Active;
    117102
    118         enable_interrupts( __cfaabi_dbg_ctx );
    119         verify( TL_GET( preemption_state ).enabled || TL_GET( this_processor )->do_terminate );
     103      enable_interrupts( __cfaabi_dbg_ctx );
     104      verify( TL_GET( preemption_state ).enabled || TL_GET( this_processor )->do_terminate );
    120105} //ctxSwitchDirect
    121106
    122107void create_stack( coStack_t* this, unsigned int storageSize ) with( *this ) {
    123         //TEMP HACK do this on proper kernel startup
    124         if(pageSize == 0ul) pageSize = sysconf( _SC_PAGESIZE );
     108      //TEMP HACK do this on proper kernel startup
     109      if(pageSize == 0ul) pageSize = sysconf( _SC_PAGESIZE );
    125110
    126         size_t cxtSize = libCeiling( sizeof(machine_context_t), 8 ); // minimum alignment
     111      size_t cxtSize = libCeiling( sizeof(machine_context_t), 8 ); // minimum alignment
    127112
    128         if ( (intptr_t)storage == 0 ) {
    129                 userStack = false;
    130                 size = libCeiling( storageSize, 16 );
    131                 // use malloc/memalign because "new" raises an exception for out-of-memory
     113      if ( !storage ) {
     114            __cfaabi_dbg_print_safe("Kernel : Creating stack of size %zu for stack obj %p\n", cxtSize + size + 8, this);
    132115
    133                 // assume malloc has 8 byte alignment so add 8 to allow rounding up to 16 byte alignment
    134                 __cfaabi_dbg_debug_do( storage = memalign( pageSize, cxtSize + size + pageSize ) );
    135                 __cfaabi_dbg_no_debug_do( storage = malloc( cxtSize + size + 8 ) );
     116            userStack = false;
     117            size = libCeiling( storageSize, 16 );
     118            // use malloc/memalign because "new" raises an exception for out-of-memory
    136119
    137                 __cfaabi_dbg_debug_do(
    138                         if ( mprotect( storage, pageSize, PROT_NONE ) == -1 ) {
    139                                 abort( "(uMachContext &)%p.createContext() : internal error, mprotect failure, error(%d) %s.", this, (int)errno, strerror( (int)errno ) );
    140                         } // if
    141                 );
     120            // assume malloc has 8 byte alignment so add 8 to allow rounding up to 16 byte alignment
     121            __cfaabi_dbg_debug_do( storage = memalign( pageSize, cxtSize + size + pageSize ) );
     122            __cfaabi_dbg_no_debug_do( storage = malloc( cxtSize + size + 8 ) );
    142123
    143                 if ( (intptr_t)storage == 0 ) {
    144                         abort( "Attempt to allocate %zd bytes of storage for coroutine or task execution-state but insufficient memory available.", size );
    145                 } // if
     124            __cfaabi_dbg_debug_do(
     125                  if ( mprotect( storage, pageSize, PROT_NONE ) == -1 ) {
     126                        abort( "(uMachContext &)%p.createContext() : internal error, mprotect failure, error(%d) %s.", this, (int)errno, strerror( (int)errno ) );
     127                  } // if
     128            );
    146129
    147                 __cfaabi_dbg_debug_do( limit = (char *)storage + pageSize );
    148                 __cfaabi_dbg_no_debug_do( limit = (char *)libCeiling( (unsigned long)storage, 16 ) ); // minimum alignment
     130            if ( (intptr_t)storage == 0 ) {
     131                  abort( "Attempt to allocate %zd bytes of storage for coroutine or task execution-state but insufficient memory available.", size );
     132            } // if
    149133
    150         } else {
    151                 assertf( ((size_t)storage & (libAlign() - 1)) != 0ul, "Stack storage %p for task/coroutine must be aligned on %d byte boundary.", storage, (int)libAlign() );
    152                 userStack = true;
    153                 size = storageSize - cxtSize;
     134            __cfaabi_dbg_debug_do( limit = (char *)storage + pageSize );
     135            __cfaabi_dbg_no_debug_do( limit = (char *)libCeiling( (unsigned long)storage, 16 ) ); // minimum alignment
    154136
    155                 if ( size % 16 != 0u ) size -= 8;
     137      } else {
     138            __cfaabi_dbg_print_safe("Kernel : stack obj %p using user stack %p(%u bytes)\n", this, storage, storageSize);
    156139
    157                 limit = (char *)libCeiling( (unsigned long)storage, 16 ); // minimum alignment
    158         } // if
    159         assertf( size >= MinStackSize, "Stack size %zd provides less than minimum of %d bytes for a stack.", size, MinStackSize );
     140            assertf( ((size_t)storage & (libAlign() - 1)) == 0ul, "Stack storage %p for task/coroutine must be aligned on %d byte boundary.", storage, (int)libAlign() );
     141            userStack = true;
     142            size = storageSize - cxtSize;
    160143
    161         base = (char *)limit + size;
    162         context = base;
    163         top = (char *)context + cxtSize;
     144            if ( size % 16 != 0u ) size -= 8;
     145
     146            limit = (char *)libCeiling( (unsigned long)storage, 16 ); // minimum alignment
     147      } // if
     148      assertf( size >= MinStackSize, "Stack size %zd provides less than minimum of %d bytes for a stack.", size, MinStackSize );
     149
     150      base = (char *)limit + size;
     151      context = base;
     152      top = (char *)context + cxtSize;
    164153}
    165154
     
    167156// is not inline (We can't inline Cforall in C)
    168157extern "C" {
    169         void __suspend_internal(void) {
    170                 suspend();
    171         }
     158      void __suspend_internal(void) {
     159            suspend();
     160      }
    172161
    173         void __leave_coroutine(void) {
    174                 coroutine_desc * src = TL_GET( this_coroutine ); // optimization
     162      void __leave_coroutine(void) {
     163            coroutine_desc * src = TL_GET( this_coroutine ); // optimization
    175164
    176                 assertf( src->starter != 0,
    177                         "Attempt to suspend/leave coroutine \"%.256s\" (%p) that has never been resumed.\n"
    178                         "Possible cause is a suspend executed in a member called by a coroutine user rather than by the coroutine main.",
    179                         src->name, src );
    180                 assertf( src->starter->state != Halted,
    181                         "Attempt by coroutine \"%.256s\" (%p) to suspend/leave back to terminated coroutine \"%.256s\" (%p).\n"
    182                         "Possible cause is terminated coroutine's main routine has already returned.",
    183                         src->name, src, src->starter->name, src->starter );
     165            assertf( src->starter != 0,
     166                  "Attempt to suspend/leave coroutine \"%.256s\" (%p) that has never been resumed.\n"
     167                  "Possible cause is a suspend executed in a member called by a coroutine user rather than by the coroutine main.",
     168                  src->name, src );
     169            assertf( src->starter->state != Halted,
     170                  "Attempt by coroutine \"%.256s\" (%p) to suspend/leave back to terminated coroutine \"%.256s\" (%p).\n"
     171                  "Possible cause is terminated coroutine's main routine has already returned.",
     172                  src->name, src, src->starter->name, src->starter );
    184173
    185                 CoroutineCtxSwitch( src, src->starter );
    186         }
     174            CoroutineCtxSwitch( src, src->starter );
     175      }
    187176}
    188177
  • src/libcfa/concurrency/invoke.h

    r22bdc34 rde6319f  
    125125                // pointer to monitor with sufficient lifetime for current monitors
    126126                struct monitor_desc *  self_mon_p;
     127
     128                // pointer to the cluster on which the thread is running
     129                struct cluster * curr_cluster;
    127130
    128131                // monitors currently held by this thread
  • src/libcfa/concurrency/kernel

    r22bdc34 rde6319f  
    4848        __queue_t(thread_desc) ready_queue;
    4949
     50        // Name of the cluster
     51        const char * name;
     52
    5053        // Preemption rate on this cluster
    5154        Duration preemption_rate;
    5255};
    5356
     57extern struct cluster * mainCluster;
    5458extern Duration default_preemption();
    5559
    56 void ?{} (cluster & this);
     60void ?{} (cluster & this, const char * name, Duration preemption_rate);
    5761void ^?{}(cluster & this);
     62
     63static inline void ?{} (cluster & this)                           { this{"Anonymous Cluster", default_preemption()}; }
     64static inline void ?{} (cluster & this, Duration preemption_rate) { this{"Anonymous Cluster", preemption_rate}; }
     65static inline void ?{} (cluster & this, const char * name)        { this{name, default_preemption()}; }
    5866
    5967//-----------------------------------------------------------------------------
     
    92100        cluster * cltr;
    93101
     102        // Name of the processor
     103        const char * name;
     104
    94105        // Handle to pthreads
    95106        pthread_t kernel_thread;
     
    119130};
    120131
    121 void  ?{}(processor & this);
    122 void  ?{}(processor & this, cluster * cltr);
     132void  ?{}(processor & this, const char * name, cluster & cltr);
    123133void ^?{}(processor & this);
     134
     135static inline void  ?{}(processor & this)                    { this{ "Anonymous Processor", *mainCluster}; }
     136static inline void  ?{}(processor & this, cluster & cltr)    { this{ "Anonymous Processor", cltr}; }
     137static inline void  ?{}(processor & this, const char * name) { this{name, *mainCluster }; }
    124138
    125139// Local Variables: //
  • src/libcfa/concurrency/kernel.c

    r22bdc34 rde6319f  
    4242KERNEL_STORAGE(cluster,           mainCluster);
    4343KERNEL_STORAGE(processor,         mainProcessor);
    44 KERNEL_STORAGE(processorCtx_t,    mainProcessorCtx);
    4544KERNEL_STORAGE(thread_desc,       mainThread);
    4645KERNEL_STORAGE(machine_context_t, mainThreadCtx);
    4746
    48 cluster *    mainCluster;
    49 processor mainProcessor;
     47cluster     * mainCluster;
     48processor   * mainProcessor;
    5049thread_desc * mainThread;
    5150
     
    6564
    6665//-----------------------------------------------------------------------------
    67 // Main thread construction
     66// Struct to steal stack
    6867struct current_stack_info_t {
    6968        machine_context_t ctx;
     
    9089}
    9190
     91//-----------------------------------------------------------------------------
     92// Main thread construction
    9293void ?{}( coStack_t & this, current_stack_info_t * info) with( this ) {
    9394        size      = info->size;
     
    111112        self_cor{ info };
    112113        curr_cor = &self_cor;
     114        curr_cluster = mainCluster;
    113115        self_mon.owner = &this;
    114116        self_mon.recursion = 1;
     
    126128//-----------------------------------------------------------------------------
    127129// Processor coroutine
    128 void ?{}(processorCtx_t & this) {}
    129 
    130 // Construct the processor context of the main processor
    131 void ?{}(processorCtx_t & this, processor * proc) {
    132         (this.__cor){ "Processor" };
    133         this.__cor.starter = NULL;
    134         this.proc = proc;
     130void ?{}(processorCtx_t & this) {
     131
    135132}
    136133
     
    141138}
    142139
    143 void ?{}(processor & this) {
    144         this{ mainCluster };
    145 }
    146 
    147 void ?{}(processor & this, cluster * cltr) with( this ) {
    148         this.cltr = cltr;
     140void ?{}(processor & this, const char * name, cluster & cltr) with( this ) {
     141        this.name = name;
     142        this.cltr = &cltr;
    149143        terminated{ 0 };
    150144        do_terminate = false;
     
    154148
    155149        start( &this );
    156 }
    157 
    158 void ?{}(processor & this, cluster * cltr, processorCtx_t & runner) with( this ) {
    159         this.cltr = cltr;
    160         terminated{ 0 };
    161         do_terminate = false;
    162         preemption_alarm = NULL;
    163         pending_preemption = false;
    164         kernel_thread = pthread_self();
    165         runner.proc = &this;
    166 
    167         __cfaabi_dbg_print_safe("Kernel : constructing main processor context %p\n", &runner);
    168         runner{ &this };
    169150}
    170151
     
    181162}
    182163
    183 void ?{}(cluster & this) with( this ) {
     164void ?{}(cluster & this, const char * name, Duration preemption_rate) with( this ) {
     165        this.name = name;
     166        this.preemption_rate = preemption_rate;
    184167        ready_queue{};
    185168        ready_queue_lock{};
    186 
    187         preemption_rate = default_preemption();
    188169}
    189170
     
    312293        TL_SET( this_coroutine, NULL );
    313294        TL_SET( this_thread, NULL );
    314         TL_GET( preemption_state ).enabled = false;
    315         TL_GET( preemption_state ).disable_count = 1;
     295        TL_GET( preemption_state ).[enabled, disable_count] = [false, 1];
    316296        // SKULLDUGGERY: We want to create a context for the processor coroutine
    317297        // which is needed for the 2-step context switch. However, there is no reason
     
    402382        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
    403383
    404         with( *TL_GET( this_processor )->cltr ) {
     384        with( *thrd->curr_cluster ) {
    405385                lock  ( ready_queue_lock __cfaabi_dbg_ctx2 );
    406386                append( ready_queue, thrd );
     
    430410void BlockInternal( __spinlock_t * lock ) {
    431411        disable_interrupts();
    432         TL_GET( this_processor )->finish.action_code = Release;
    433         TL_GET( this_processor )->finish.lock        = lock;
     412        with( *TL_GET( this_processor ) ) {
     413                finish.action_code = Release;
     414                finish.lock        = lock;
     415        }
    434416
    435417        verify( ! TL_GET( preemption_state ).enabled );
     
    442424void BlockInternal( thread_desc * thrd ) {
    443425        disable_interrupts();
    444         TL_GET( this_processor )->finish.action_code = Schedule;
    445         TL_GET( this_processor )->finish.thrd        = thrd;
     426        with( *TL_GET( this_processor ) ) {
     427                finish.action_code = Schedule;
     428                finish.thrd        = thrd;
     429        }
    446430
    447431        verify( ! TL_GET( preemption_state ).enabled );
     
    455439        assert(thrd);
    456440        disable_interrupts();
    457         TL_GET( this_processor )->finish.action_code = Release_Schedule;
    458         TL_GET( this_processor )->finish.lock        = lock;
    459         TL_GET( this_processor )->finish.thrd        = thrd;
     441        with( *TL_GET( this_processor ) ) {
     442                finish.action_code = Release_Schedule;
     443                finish.lock        = lock;
     444                finish.thrd        = thrd;
     445        }
    460446
    461447        verify( ! TL_GET( preemption_state ).enabled );
     
    468454void BlockInternal(__spinlock_t * locks [], unsigned short count) {
    469455        disable_interrupts();
    470         TL_GET( this_processor )->finish.action_code = Release_Multi;
    471         TL_GET( this_processor )->finish.locks       = locks;
    472         TL_GET( this_processor )->finish.lock_count  = count;
     456        with( *TL_GET( this_processor ) ) {
     457                finish.action_code = Release_Multi;
     458                finish.locks       = locks;
     459                finish.lock_count  = count;
     460        }
    473461
    474462        verify( ! TL_GET( preemption_state ).enabled );
     
    481469void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) {
    482470        disable_interrupts();
    483         TL_GET( this_processor )->finish.action_code = Release_Multi_Schedule;
    484         TL_GET( this_processor )->finish.locks       = locks;
    485         TL_GET( this_processor )->finish.lock_count  = lock_count;
    486         TL_GET( this_processor )->finish.thrds       = thrds;
    487         TL_GET( this_processor )->finish.thrd_count  = thrd_count;
     471        with( *TL_GET( this_processor ) ) {
     472                finish.action_code = Release_Multi_Schedule;
     473                finish.locks       = locks;
     474                finish.lock_count  = lock_count;
     475                finish.thrds       = thrds;
     476                finish.thrd_count  = thrd_count;
     477        }
    488478
    489479        verify( ! TL_GET( preemption_state ).enabled );
     
    496486void LeaveThread(__spinlock_t * lock, thread_desc * thrd) {
    497487        verify( ! TL_GET( preemption_state ).enabled );
    498         TL_GET( this_processor )->finish.action_code = thrd ? Release_Schedule : Release;
    499         TL_GET( this_processor )->finish.lock        = lock;
    500         TL_GET( this_processor )->finish.thrd        = thrd;
     488        with( *TL_GET( this_processor ) ) {
     489                finish.action_code = thrd ? Release_Schedule : Release;
     490                finish.lock        = lock;
     491                finish.thrd        = thrd;
     492        }
    501493
    502494        returnToKernel();
     
    511503        verify( ! TL_GET( preemption_state ).enabled );
    512504        __cfaabi_dbg_print_safe("Kernel : Starting\n");
     505
     506        // Initialize the main cluster
     507        mainCluster = (cluster *)&storage_mainCluster;
     508        (*mainCluster){"Main Cluster"};
     509
     510        __cfaabi_dbg_print_safe("Kernel : Main cluster ready\n");
    513511
    514512        // Start by initializing the main thread
     
    521519        __cfaabi_dbg_print_safe("Kernel : Main thread ready\n");
    522520
    523         // Initialize the main cluster
    524         mainCluster = (cluster *)&storage_mainCluster;
    525         (*mainCluster){};
    526 
    527         __cfaabi_dbg_print_safe("Kernel : main cluster ready\n");
     521
     522
     523        // Construct the processor context of the main processor
     524        void ?{}(processorCtx_t & this, processor * proc) {
     525                (this.__cor){ "Processor" };
     526                this.__cor.starter = NULL;
     527                this.proc = proc;
     528        }
     529
     530        void ?{}(processor & this) with( this ) {
     531                name = "Main Processor";
     532                cltr = mainCluster;
     533                terminated{ 0 };
     534                do_terminate = false;
     535                preemption_alarm = NULL;
     536                pending_preemption = false;
     537                kernel_thread = pthread_self();
     538
     539                runner{ &this };
     540                __cfaabi_dbg_print_safe("Kernel : constructed main processor context %p\n", &runner);
     541        }
    528542
    529543        // Initialize the main processor and the main processor ctx
    530544        // (the coroutine that contains the processing control flow)
    531545        mainProcessor = (processor *)&storage_mainProcessor;
    532         (*mainProcessor){ mainCluster, *(processorCtx_t *)&storage_mainProcessorCtx };
     546        (*mainProcessor){};
    533547
    534548        //initialize the global state variables
  • src/libcfa/concurrency/preemption.c

    r22bdc34 rde6319f  
    149149        // Disable interrupts by incrementing the counter
    150150        void disable_interrupts() {
    151                 TL_GET( preemption_state ).enabled = false;
    152                 __attribute__((unused)) unsigned short new_val = TL_GET( preemption_state ).disable_count + 1;
    153                 TL_GET( preemption_state ).disable_count = new_val;
    154                 verify( new_val < 65_000u );              // If this triggers someone is disabling interrupts without enabling them
     151                with( TL_GET( preemption_state ) ) {
     152                        enabled = false;
     153                        __attribute__((unused)) unsigned short new_val = disable_count + 1;
     154                        disable_count = new_val;
     155                        verify( new_val < 65_000u );              // If this triggers someone is disabling interrupts without enabling them
     156                }
    155157        }
    156158
     
    161163                thread_desc * thrd = TL_GET( this_thread );       // Cache the thread now since interrupts can start happening after the atomic add
    162164
    163                 unsigned short prev = TL_GET( preemption_state ).disable_count;
    164                 TL_GET( preemption_state ).disable_count -= 1;
    165                 verify( prev != 0u );                     // If this triggers someone is enabled already enabled interruptsverify( prev != 0u );
    166 
    167                 // Check if we need to prempt the thread because an interrupt was missed
    168                 if( prev == 1 ) {
    169                         TL_GET( preemption_state ).enabled = true;
    170                         if( proc->pending_preemption ) {
    171                                 proc->pending_preemption = false;
    172                                 BlockInternal( thrd );
     165                with( TL_GET( preemption_state ) ){
     166                        unsigned short prev = disable_count;
     167                        disable_count -= 1;
     168                        verify( prev != 0u );                     // If this triggers someone is enabled already enabled interruptsverify( prev != 0u );
     169
     170                        // Check if we need to prempt the thread because an interrupt was missed
     171                        if( prev == 1 ) {
     172                                enabled = true;
     173                                if( proc->pending_preemption ) {
     174                                        proc->pending_preemption = false;
     175                                        BlockInternal( thrd );
     176                                }
    173177                        }
    174178                }
     
    328332        if( !preemption_ready() ) { return; }
    329333
    330         __cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p).\n", this_processor, this_thread);
     334        __cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p).\n", TL_GET( this_processor ), TL_GET( this_thread ) );
    331335
    332336        TL_GET( preemption_state ).in_progress = true;  // Sync flag : prevent recursive calls to the signal handler
  • src/libcfa/concurrency/thread

    r22bdc34 rde6319f  
    2323
    2424//-----------------------------------------------------------------------------
    25 // Coroutine trait
    26 // Anything that implements this trait can be resumed.
    27 // Anything that is resumed is a coroutine.
     25// thread trait
    2826trait is_thread(dtype T) {
    2927      void ^?{}(T& mutex this);
     
    5250}
    5351
    54 //extern thread_local thread_desc * volatile this_thread;
     52extern struct cluster * mainCluster;
    5553
    5654forall( dtype T | is_thread(T) )
     
    5957//-----------------------------------------------------------------------------
    6058// Ctors and dtors
    61 void ?{}(thread_desc& this);
    62 void ^?{}(thread_desc& this);
     59void ?{}(thread_desc & this, const char * const name, struct cluster & cl, void * storage, size_t storageSize );
     60void ^?{}(thread_desc & this);
     61
     62static inline void ?{}(thread_desc & this)                                                                  { this{ "Anonymous Thread", *mainCluster, NULL, 0 }; }
     63static inline void ?{}(thread_desc & this, size_t stackSize )                                               { this{ "Anonymous Thread", *mainCluster, NULL, stackSize }; }
     64static inline void ?{}(thread_desc & this, void * storage, size_t storageSize )                             { this{ "Anonymous Thread", *mainCluster, storage, storageSize }; }
     65static inline void ?{}(thread_desc & this, struct cluster & cl )                                            { this{ "Anonymous Thread", cl, NULL, 0 }; }
     66static inline void ?{}(thread_desc & this, struct cluster & cl, size_t stackSize )                          { this{ "Anonymous Thread", cl, 0, stackSize }; }
     67static inline void ?{}(thread_desc & this, struct cluster & cl, void * storage, size_t storageSize )        { this{ "Anonymous Thread", cl, storage, storageSize }; }
     68static inline void ?{}(thread_desc & this, const char * const name)                                         { this{ name, *mainCluster, NULL, 0 }; }
     69static inline void ?{}(thread_desc & this, const char * const name, struct cluster & cl )                   { this{ name, cl, NULL, 0 }; }
     70static inline void ?{}(thread_desc & this, const char * const name, struct cluster & cl, size_t stackSize ) { this{ name, cl, NULL, stackSize }; }
    6371
    6472//-----------------------------------------------------------------------------
  • src/libcfa/concurrency/thread.c

    r22bdc34 rde6319f  
    3030//-----------------------------------------------------------------------------
    3131// Thread ctors and dtors
    32 
    33 void ?{}(thread_desc& this) with( this ) {
    34         self_cor{};
    35         self_cor.name = "Anonymous Coroutine";
     32void ?{}(thread_desc & this, const char * const name, cluster & cl, void * storage, size_t storageSize ) with( this ) {
     33        self_cor{ name, storage, storageSize };
     34        verify(&self_cor);
    3635        curr_cor = &self_cor;
    3736        self_mon.owner = &this;
    3837        self_mon.recursion = 1;
    3938        self_mon_p = &self_mon;
     39        curr_cluster = &cl;
    4040        next = NULL;
    4141        __cfaabi_dbg_debug_do(
Note: See TracChangeset for help on using the changeset viewer.