Changeset 0c92c9f for src/libcfa


Ignore:
Timestamp:
Jan 27, 2017, 4:28:05 PM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
8804701
Parents:
0157ca7
Message:

Cleaned-up threading code and added temporary test for threads (single core)

Location:
src/libcfa/concurrency
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/coroutines

    r0157ca7 r0c92c9f  
    6565
    6666// Private wrappers for context switch and stack creation
    67 extern void corCxtSw(coroutine * src, coroutine * dst);
     67extern void CoroutineCtxSwitch(coroutine * src, coroutine * dst);
    6868extern void create_stack( coStack_t * this, unsigned int storageSize );
    6969
     
    8181                src->name, src, src->last->name, src->last );
    8282
    83         corCxtSw( src, src->last );
     83        CoroutineCtxSwitch( src, src->last );
    8484}
    8585
     
    107107
    108108      // always done for performance testing
    109         corCxtSw( src, dst );
     109        CoroutineCtxSwitch( src, dst );
    110110}
    111111
  • src/libcfa/concurrency/coroutines.c

    r0157ca7 r0c92c9f  
    9898}
    9999
    100 // We need to call suspend from invoke.c, so we expose this wrapper that
    101 // is not inline (We can't inline Cforall in C)
    102 void suspend_no_inline(void) {
    103         suspend();
    104 }
    105 
    106 void corCxtSw(coroutine* src, coroutine* dst) {
     100// Wrapper for co
     101void CoroutineCtxSwitch(coroutine* src, coroutine* dst) {
    107102        // THREAD_GETMEM( This )->disableInterrupts();
    108103
     
    167162}
    168163
     164// We need to call suspend from invoke.c, so we expose this wrapper that
     165// is not inline (We can't inline Cforall in C)
     166extern "C" {
     167        void __suspend_internal(void) {
     168                suspend();
     169        }
     170}
     171
    169172// Local Variables: //
    170173// mode: c //
  • src/libcfa/concurrency/invoke.c

    r0157ca7 r0c92c9f  
    2828// Called from the kernel when starting a coroutine or task so must switch back to user mode.
    2929
    30 extern void __suspend_no_inline__F___1(void);
    31 extern void __signal_termination__F_P7sthread__1(struct thread*);
     30extern void __suspend_internal(void);
     31extern void __thread_signal_termination(struct thread*);
    3232
    3333void CtxInvokeCoroutine(
     
    4141
    4242      if(cor->state == Primed) {
    43             __suspend_no_inline__F___1();
     43            __suspend_internal();
    4444      }
    4545
     
    5252
    5353      //Final suspend, should never return
    54       __suspend_no_inline__F___1();
    55       assertf(false, "Resumed dead coroutine");
     54      __suspend_internal();
     55      abortf("Resumed dead coroutine");
    5656}
    5757
     
    6161      void *this
    6262) {
    63       // LIB_DEBUG_PRINTF("Invoke Thread : Received %p (main %p, get_t %p)\n", this, main, get_thread);
    64 
    65       __suspend_no_inline__F___1();
     63      __suspend_internal();
    6664
    6765      struct thread* thrd = get_thread( this );
     
    7270      main( this );
    7371
    74       __signal_termination__F_P7sthread__1(thrd);
     72      __thread_signal_termination(thrd);
    7573
    7674      //Final suspend, should never return
    77       __suspend_no_inline__F___1();
    78       assertf(false, "Resumed dead thread");
     75      __suspend_internal();
     76      abortf("Resumed dead thread");
    7977}
    8078
  • src/libcfa/concurrency/kernel.c

    r0157ca7 r0c92c9f  
    1515//
    1616
     17//Start and stop routine for the kernel, declared first to make sure they run first
     18void kernel_startup(void)  __attribute__((constructor(101)));
     19void kernel_shutdown(void) __attribute__((destructor(101)));
     20
    1721//Header
    1822#include "kernel"
     
    5256processor * systemProcessor;
    5357thread * mainThread;
    54 
    55 void kernel_startup(void)  __attribute__((constructor(101)));
    56 void kernel_shutdown(void) __attribute__((destructor(101)));
    5758
    5859//-----------------------------------------------------------------------------
     
    184185void main(processorCtx_t * ctx);
    185186thread * nextThread(cluster * this);
    186 void runThread(processor * this, thread * dst);
     187void scheduleInternal(processor * this, thread * dst);
    187188void spin(processor * this, unsigned int * spin_count);
    188189
     
    197198
    198199                if(readyThread) {
    199                         runThread(this, readyThread);
     200                        scheduleInternal(this, readyThread);
    200201                        spin_count = 0;
    201202                } else {
     
    209210}
    210211
    211 void runThread(processor * this, thread * dst) {
     212//Declarations for scheduleInternal
     213extern void ThreadCtxSwitch(coroutine * src, coroutine * dst);
     214
     215// scheduleInternal runs a thread by context switching
     216// from the processor coroutine to the target thread
     217void scheduleInternal(processor * this, thread * dst) {
     218        // coroutine * proc_ctx = get_coroutine(this->ctx);
     219        // coroutine * thrd_ctx = get_coroutine(dst);
     220
     221        // //Update global state
     222        // this->current_thread = dst;
     223
     224        // // Context Switch to the thread
     225        // ThreadCtxSwitch(proc_ctx, thrd_ctx);
     226        // // when ThreadCtxSwitch returns we are back in the processor coroutine
     227
    212228        coroutine * proc_ctx = get_coroutine(this->ctx);
    213229        coroutine * thrd_ctx = get_coroutine(dst);
    214         thrd_ctx->last = proc_ctx;
    215 
    216         // context switch to specified coroutine
    217         // Which is now the current_coroutine
    218         // LIB_DEBUG_PRINTF("Kernel : switching to ctx %p (from %p, current %p)\n", thrd_ctx, proc_ctx, current_coroutine);
    219         this->current_thread = dst;
    220         this->current_coroutine = thrd_ctx;
    221         CtxSwitch( proc_ctx->stack.context, thrd_ctx->stack.context );
    222         this->current_coroutine = proc_ctx;
    223         // LIB_DEBUG_PRINTF("Kernel : returned from ctx %p (to %p, current %p)\n", thrd_ctx, proc_ctx, current_coroutine);
    224 
    225         // when CtxSwitch returns we are back in the processor coroutine
    226 }
    227 
     230      thrd_ctx->last = proc_ctx;
     231 
     232      // context switch to specified coroutine
     233      // Which is now the current_coroutine
     234      LIB_DEBUG_PRINTF("Kernel : switching to ctx %p (from %p, current %p)\n", thrd_ctx, proc_ctx, this->current_coroutine);
     235      this->current_thread = dst;
     236      this->current_coroutine = thrd_ctx;
     237      CtxSwitch( proc_ctx->stack.context, thrd_ctx->stack.context );
     238      this->current_coroutine = proc_ctx;
     239      LIB_DEBUG_PRINTF("Kernel : returned from ctx %p (to %p, current %p)\n", thrd_ctx, proc_ctx, this->current_coroutine);
     240 
     241      // when CtxSwitch returns we are back in the processor coroutine
     242}
     243
     244// Handles spinning logic
     245// TODO : find some strategy to put cores to sleep after some time
    228246void spin(processor * this, unsigned int * spin_count) {
    229247        (*spin_count)++;
    230248}
    231249
     250// Context invoker for processors
     251// This is the entry point for processors (kernel threads)
     252// It effectively constructs a coroutine by stealing the pthread stack
    232253void * CtxInvokeProcessor(void * arg) {
    233254        processor * proc = (processor *) arg;
     
    241262        processorCtx_t proc_cor_storage = { proc, &info };
    242263
     264        //Set global state
    243265        proc->current_coroutine = &proc->ctx->c;
    244266        proc->current_thread = NULL;
    245267
     268        //We now have a proper context from which to schedule threads
    246269        LIB_DEBUG_PRINTF("Kernel : core %p created (%p)\n", proc, proc->ctx);
    247 
    248         // LIB_DEBUG_PRINTF("Kernel : core    base : %p \n", info.base );
    249         // LIB_DEBUG_PRINTF("Kernel : core storage : %p \n", info.storage );
    250         // LIB_DEBUG_PRINTF("Kernel : core    size : %x \n", info.size );
    251         // LIB_DEBUG_PRINTF("Kernel : core   limit : %p \n", info.limit );
    252         // LIB_DEBUG_PRINTF("Kernel : core context : %p \n", info.context );
    253         // LIB_DEBUG_PRINTF("Kernel : core     top : %p \n", info.top );
    254 
    255         //We now have a proper context from which to schedule threads
    256270
    257271        // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't
     
    264278      proc_cor_storage.c.notHalted = false;
    265279
     280        // Main routine of the core returned, the core is now fully terminated
    266281        LIB_DEBUG_PRINTF("Kernel : core %p main ended (%p)\n", proc, proc->ctx);       
    267282
  • src/libcfa/concurrency/threads

    r0157ca7 r0c92c9f  
    2727// Anything that implements this trait can be resumed.
    2828// Anything that is resumed is a coroutine.
    29 trait is_thread(dtype T | sized(T)) {
     29trait is_thread(dtype T) {
    3030      void main(T* this);
    3131      thread* get_thread(T* this);
    3232};
    3333
    34 #define DECL_THREAD(X) static inline thread* get_thread(X* this) { return &this->t; } void main(X* this);
     34#define DECL_THREAD(X) thread* get_thread(X* this) { return &this->t; } void main(X* this);
    3535
    36 forall( dtype T | sized(T) | is_thread(T) )
     36forall( dtype T | is_thread(T) )
    3737static inline coroutine* get_coroutine(T* this) {
    3838        return &get_thread(this)->c;
  • src/libcfa/concurrency/threads.c

    r0157ca7 r0c92c9f  
    3131//-----------------------------------------------------------------------------
    3232// Forward declarations
    33 forall( dtype T | sized(T) | is_thread(T) )
     33forall( dtype T | is_thread(T) )
    3434void start( T* this );
    3535
    36 forall( dtype T | sized(T) | is_thread(T) )
     36forall( dtype T | is_thread(T) )
    3737void stop( T* this );
    3838
     
    7878extern void thread_schedule( thread * );
    7979
    80 forall( dtype T | sized(T) | is_thread(T) )
     80forall( dtype T | is_thread(T) )
    8181void start( T* this ) {
    8282        coroutine* thrd_c = get_coroutine(this);
     
    8585        get_this_processor()->current_coroutine = thrd_c;
    8686
    87         // LIB_DEBUG_PRINTF("Thread start : %p (t %p, c %p)\n", handle, thrd_c, thrd_h);
     87        LIB_DEBUG_PRINTF("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h);
    8888
    8989        create_stack(&thrd_c->stack, thrd_c->stack.size);
     
    9191        CtxSwitch( thrd_c->last->stack.context, thrd_c->stack.context );
    9292
     93        LIB_DEBUG_PRINTF("Thread started : %p (t %p, c %p)\n", this, thrd_c, thrd_h);
     94
    9395        thread_schedule(thrd_h);
    9496}
    9597
    96 forall( dtype T | sized(T) | is_thread(T) )
     98forall( dtype T | is_thread(T) )
    9799void stop( T* this ) {
    98100        thread*  thrd = get_thread(this);
     
    102104}
    103105
    104 void signal_termination( thread * this ) {
    105         this->c.state = Halt;
    106       this->c.notHalted = false;
    107         unlock( &this->lock );
    108 }
    109 
    110106void yield( void ) {
    111107        thread_schedule( this_thread() );
    112108        suspend();
     109}
     110
     111void ThreadCtxSwitch(coroutine* src, coroutine* dst) {
     112        dst->last = src;
     113
     114        // set state of current coroutine to inactive
     115        src->state = Inactive;
     116
     117        // set new coroutine that task is executing
     118        get_this_processor()->current_coroutine = dst; 
     119
     120        // context switch to specified coroutine
     121        CtxSwitch( src->stack.context, dst->stack.context );
     122        // when CtxSwitch returns we are back in the src coroutine
     123
     124        // set state of new coroutine to active
     125        src->state = Active;
     126}
     127
     128// C Helper to signal the termination of a thread
     129// Used in invoke.c
     130extern "C" {
     131        void __thread_signal_termination( thread * this ) {
     132                this->c.state = Halt;
     133                this->c.notHalted = false;
     134                unlock( &this->lock );
     135        }
    113136}
    114137
Note: See TracChangeset for help on using the changeset viewer.