Ignore:
File:
1 edited

Legend:

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

    r8fcbb4c r77e6fcb  
    2525#include <stddef.h>
    2626extern "C" {
    27 #include <fenv.h>
    2827#include <sys/resource.h>
    2928}
     
    3635#define __CFA_INVOKE_PRIVATE__
    3736#include "invoke.h"
    38 
    39 static volatile int lock;
    40 
    41 void spin_lock( volatile int *lock ) {
    42         for ( unsigned int i = 1;; i += 1 ) {
    43           if ( *lock == 0 && __sync_lock_test_and_set_4( lock, 1 ) == 0 ) break;
    44         }
    45 }
    46 
    47 void spin_unlock( volatile int *lock ) {
    48         __sync_lock_release_4( lock );
    49 }
    5037
    5138//-----------------------------------------------------------------------------
     
    140127        (&this->c){};
    141128        this->proc = proc;
    142         proc->runner = this;
     129        proc->ctx = this;
    143130}
    144131
     
    146133        (&this->c){ info };
    147134        this->proc = proc;
    148         proc->runner = this;
     135        proc->ctx = this;
    149136}
    150137
     
    165152}
    166153
    167 void ?{}(processor * this, cluster * cltr, processorCtx_t * runner) {
     154void ?{}(processor * this, cluster * cltr, processorCtx_t * ctx) {
    168155        this->cltr = cltr;
    169156        this->current_coroutine = NULL;
     
    172159        this->terminated = false;
    173160
    174         this->runner = runner;
    175         LIB_DEBUG_PRINTF("Kernel : constructing processor context %p\n", runner);
    176         runner{ this };
     161        this->ctx = ctx;
     162        LIB_DEBUG_PRINTF("Kernel : constructing processor context %p\n", ctx);
     163        ctx{ this };
    177164}
    178165
     
    187174void ?{}(cluster * this) {
    188175        ( &this->ready_queue ){};
    189         lock = 0;
     176        pthread_spin_init( &this->lock, PTHREAD_PROCESS_PRIVATE );
    190177}
    191178
    192179void ^?{}(cluster * this) {
    193        
     180        pthread_spin_destroy( &this->lock );
    194181}
    195182
    196183//-----------------------------------------------------------------------------
    197184// Processor running routines
    198 void main(processorCtx_t *);
     185void main(processorCtx_t * ctx);
    199186thread * nextThread(cluster * this);
    200187void scheduleInternal(processor * this, thread * dst);
    201188void spin(processor * this, unsigned int * spin_count);
    202 void thread_schedule( thread * thrd );
    203 
    204 //Main of the processor contexts
    205 void main(processorCtx_t * runner) {
    206         processor * this = runner->proc;
     189
     190void main(processorCtx_t * ctx) {
     191        processor * this = ctx->proc;
    207192        LIB_DEBUG_PRINTF("Kernel : core %p starting\n", this);
    208 
    209         fenv_t envp;
    210         fegetenv( &envp );
    211         LIB_DEBUG_PRINTF("Kernel : mxcsr %x\n", envp.__mxcsr);
    212193
    213194        thread * readyThread = NULL;
     
    235216// from the processor coroutine to the target thread
    236217void scheduleInternal(processor * this, thread * dst) {
    237         this->thread_action = NoAction;
    238 
    239218        // coroutine * proc_ctx = get_coroutine(this->ctx);
    240219        // coroutine * thrd_ctx = get_coroutine(dst);
     
    247226        // // when ThreadCtxSwitch returns we are back in the processor coroutine
    248227
    249         coroutine * proc_ctx = get_coroutine(this->runner);
     228        coroutine * proc_ctx = get_coroutine(this->ctx);
    250229        coroutine * thrd_ctx = get_coroutine(dst);
    251230      thrd_ctx->last = proc_ctx;
     
    253232      // context switch to specified coroutine
    254233      // Which is now the current_coroutine
    255       // LIB_DEBUG_PRINTF("Kernel : switching to ctx %p (from %p, current %p)\n", thrd_ctx, proc_ctx, this->current_coroutine);
     234      LIB_DEBUG_PRINTF("Kernel : switching to ctx %p (from %p, current %p)\n", thrd_ctx, proc_ctx, this->current_coroutine);
    256235      this->current_thread = dst;
    257236      this->current_coroutine = thrd_ctx;
    258237      CtxSwitch( proc_ctx->stack.context, thrd_ctx->stack.context );
    259238      this->current_coroutine = proc_ctx;
    260       // LIB_DEBUG_PRINTF("Kernel : returned from ctx %p (to %p, current %p)\n", thrd_ctx, proc_ctx, this->current_coroutine);
     239      LIB_DEBUG_PRINTF("Kernel : returned from ctx %p (to %p, current %p)\n", thrd_ctx, proc_ctx, this->current_coroutine);
    261240 
    262241      // when CtxSwitch returns we are back in the processor coroutine
    263         if(this->thread_action == Reschedule) {
    264                 thread_schedule( dst );
    265         }
    266242}
    267243
     
    286262        processorCtx_t proc_cor_storage = { proc, &info };
    287263
    288         LIB_DEBUG_PRINTF("Coroutine : created stack %p\n", proc_cor_storage.c.stack.base);
    289 
    290264        //Set global state
    291         proc->current_coroutine = &proc->runner->c;
     265        proc->current_coroutine = &proc->ctx->c;
    292266        proc->current_thread = NULL;
    293267
    294268        //We now have a proper context from which to schedule threads
    295         LIB_DEBUG_PRINTF("Kernel : core %p created (%p, %p)\n", proc, proc->runner, &ctx);
     269        LIB_DEBUG_PRINTF("Kernel : core %p created (%p)\n", proc, proc->ctx);
    296270
    297271        // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't
     
    305279
    306280        // Main routine of the core returned, the core is now fully terminated
    307         LIB_DEBUG_PRINTF("Kernel : core %p main ended (%p)\n", proc, proc->runner);     
     281        LIB_DEBUG_PRINTF("Kernel : core %p main ended (%p)\n", proc, proc->ctx);       
    308282
    309283        return NULL;
     
    313287        LIB_DEBUG_PRINTF("Kernel : Starting core %p\n", this);
    314288       
    315         // pthread_attr_t attributes;
    316         // pthread_attr_init( &attributes );
    317 
    318         pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this );
    319 
    320         // pthread_attr_destroy( &attributes );
     289        pthread_attr_t attributes;
     290        pthread_attr_init( &attributes );
     291
     292        pthread_create( &this->kernel_thread, &attributes, CtxInvokeProcessor, (void*)this );
     293
     294        pthread_attr_destroy( &attributes );
    321295
    322296        LIB_DEBUG_PRINTF("Kernel : core %p started\n", this);   
     
    328302        assertf( thrd->next == NULL, "Expected null got %p", thrd->next );
    329303       
    330         spin_lock( &lock );
     304        pthread_spinlock_guard guard = { &systemProcessor->cltr->lock };
    331305        append( &systemProcessor->cltr->ready_queue, thrd );
    332         spin_unlock( &lock );
    333306}
    334307
    335308thread * nextThread(cluster * this) {
    336         spin_lock( &lock );
    337         thread * head = pop_head( &this->ready_queue );
    338         spin_unlock( &lock );
    339         return head;
     309        pthread_spinlock_guard guard = { &this->lock };
     310        return pop_head( &this->ready_queue );
    340311}
    341312
     
    343314// Kernel boot procedures
    344315void kernel_startup(void) {
    345         LIB_DEBUG_PRINTF("Kernel : Starting\n");       
    346 
    347         // Start by initializing the main thread
     316
    348317        // SKULLDUGGERY: the mainThread steals the process main thread
    349318        // which will then be scheduled by the systemProcessor normally
     319        LIB_DEBUG_PRINTF("Kernel : Starting\n");       
     320
     321        current_stack_info_t info;
     322
     323        // LIB_DEBUG_PRINTF("Kernel : core    base : %p \n", info.base );
     324        // LIB_DEBUG_PRINTF("Kernel : core storage : %p \n", info.storage );
     325        // LIB_DEBUG_PRINTF("Kernel : core    size : %x \n", info.size );
     326        // LIB_DEBUG_PRINTF("Kernel : core   limit : %p \n", info.limit );
     327        // LIB_DEBUG_PRINTF("Kernel : core context : %p \n", info.context );
     328        // LIB_DEBUG_PRINTF("Kernel : core     top : %p \n", info.top );
     329
     330        // Start by initializing the main thread
    350331        mainThread = (thread *)&mainThread_storage;
    351         current_stack_info_t info;
    352332        mainThread{ &info };
    353333
     
    373353        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
    374354        // mainThread is on the ready queue when this call is made.
    375         resume(systemProcessor->runner);
     355        resume(systemProcessor->ctx);
    376356
    377357
    378358
    379359        // THE SYSTEM IS NOW COMPLETELY RUNNING
     360
     361
     362
    380363        LIB_DEBUG_PRINTF("Kernel : Started\n--------------------------------------------------\n\n");
    381364}
     
    394377        // Destroy the system processor and its context in reverse order of construction
    395378        // These were manually constructed so we need manually destroy them
    396         ^(systemProcessor->runner){};
     379        ^(systemProcessor->ctx){};
    397380        ^(systemProcessor){};
    398381
     
    416399void lock( simple_lock * this ) {
    417400        {
    418                 spin_lock( &lock );
     401                pthread_spinlock_guard guard = { &systemCluster->lock };        //HUGE TEMP HACK which only works if we have a single cluster and is stupid
    419402                append( &this->blocked, this_thread() );
    420                 spin_unlock( &lock );
    421403        }
    422404        suspend();
Note: See TracChangeset for help on using the changeset viewer.