Changes in / [a073d46:e994912]


Ignore:
Location:
src
Files:
1 deleted
5 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/coroutines

    ra073d46 re994912  
    3636void ?{}(coStack_t * this);
    3737void ?{}(coroutine * this);
    38 void ?{}(coroutine * this, const char * name);
    3938void ^?{}(coStack_t * this);
    4039void ^?{}(coroutine * this);
  • src/libcfa/concurrency/coroutines.c

    ra073d46 re994912  
    6262void ?{}(coroutine* this) {
    6363        this->name = "Anonymous Coroutine";
    64         this->errno_ = 0;
    65         this->state = Start;
    66       this->notHalted = true;
    67         this->starter = NULL;
    68         this->last = NULL;
    69 }
    70 
    71 void ?{}(coroutine* this, const char * name) {
    72         this->name = name;
    7364        this->errno_ = 0;
    7465        this->state = Start;
     
    169160        this->context = this->base;
    170161        this->top = (char *)this->context + cxtSize;
    171 
    172         LIB_DEBUG_PRINTF("Coroutine : created stack %p\n", this->base);
    173162}
    174163
  • src/libcfa/concurrency/kernel

    ra073d46 re994912  
    3030struct cluster {
    3131        simple_thread_list ready_queue;
    32         // pthread_spinlock_t lock;
     32        pthread_spinlock_t lock;
    3333};
    3434
     
    3838//-----------------------------------------------------------------------------
    3939// Processor
    40 enum ProcessorAction {
    41         Reschedule,
    42         NoAction
    43 };
    44 
    4540struct processor {
    46         struct processorCtx_t * runner;
     41        struct processorCtx_t * ctx;
    4742        cluster * cltr;
    4843        coroutine * current_coroutine;
     
    5146        simple_lock lock;
    5247        volatile bool terminated;
    53         ProcessorAction thread_action;
    5448};
    5549
     
    6862void unlock( simple_lock * );
    6963
     64struct pthread_spinlock_guard {
     65        pthread_spinlock_t * lock;
     66};
     67
     68static inline void ?{}( pthread_spinlock_guard * this, pthread_spinlock_t * lock ) {
     69        this->lock = lock;
     70        pthread_spin_lock( this->lock );
     71}
     72
     73static inline void ^?{}( pthread_spinlock_guard * this ) {
     74        pthread_spin_unlock( this->lock );
     75}
     76
     77// //Simple spinlock implementation from
     78// //http://stackoverflow.com/questions/1383363/is-my-spin-lock-implementation-correct-and-optimal
     79// //Not optimal but correct
     80// #define VOL
     81
     82// struct simple_spinlock {
     83//      VOL int lock;
     84// };
     85
     86// extern VOL int __sync_lock_test_and_set( VOL int *, VOL int);
     87// extern void __sync_synchronize();
     88
     89// static inline void lock( simple_spinlock * this ) {
     90//     while (__sync_lock_test_and_set(&this->lock, 1)) {
     91//         // Do nothing. This GCC builtin instruction
     92//         // ensures memory barrier.
     93//     }
     94// }
     95
     96// static inline void unlock( simple_spinlock * this ) {
     97//     __sync_synchronize(); // Memory barrier.
     98//     this->lock = 0;
     99// }
     100
    70101#endif //KERNEL_H
    71102
  • src/libcfa/concurrency/kernel.c

    ra073d46 re994912  
    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();
  • src/libcfa/concurrency/threads.c

    ra073d46 re994912  
    2424
    2525extern "C" {
    26         #include <fenv.h>
    2726        #include <stddef.h>
    2827}
     
    9291        CtxSwitch( thrd_c->last->stack.context, thrd_c->stack.context );
    9392
    94         fenv_t envp;
    95         fegetenv( &envp );
    96         LIB_DEBUG_PRINTF("Thread : mxcsr %x\n", envp.__mxcsr);
    9793        LIB_DEBUG_PRINTF("Thread started : %p (t %p, c %p)\n", this, thrd_c, thrd_h);
    9894
     
    109105
    110106void yield( void ) {
    111         get_this_processor()->thread_action = Reschedule;
     107        thread_schedule( this_thread() );
    112108        suspend();
    113109}
Note: See TracChangeset for help on using the changeset viewer.