Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/threads

    rbb82c03 rc84e80a  
    99//
    1010// Author           : Thierry Delisle
    11 // Created On       : Mon Nov 28 12:27:26 2016
     11// Created On       : Tue Jan 17 12:27:26 2016
    1212// Last Modified By : Thierry Delisle
    13 // Last Modified On : Mon Nov 28 12:27:26 2016
     13// Last Modified On : --
    1414// Update Count     : 0
    1515//
     
    1818#define THREADS_H
    1919
    20 #include "assert"       //
     20#include "assert"
    2121#include "invoke.h"
     22
     23#include "coroutines"
    2224
    2325//-----------------------------------------------------------------------------
     
    2527// Anything that implements this trait can be resumed.
    2628// Anything that is resumed is a coroutine.
    27 trait is_coroutine(dtype T) {
    28       void co_main(T* this);
    29       coroutine* get_coroutine(T* this);
     29trait is_thread(dtype T /*| sized(T)*/) {
     30      void main(T* this);
     31      thread_h* get_thread(T* this);
     32        /*void ?{}(T*);
     33        void ^?{}(T*);*/
    3034};
     35
     36forall(otype T | is_thread(T) )
     37static inline coroutine* get_coroutine(T* this) {
     38        return &get_thread(this)->c;
     39}
     40
     41static inline coroutine* get_coroutine(thread_h* this) {
     42        return &this->c;
     43}
    3144
    3245//-----------------------------------------------------------------------------
    3346// Ctors and dtors
    34 void ?{}(coStack_t* this);
    35 void ?{}(coroutine* this);
    36 void ^?{}(coStack_t* this);
    37 void ^?{}(coroutine* this);
     47void ?{}(thread_h* this);
     48void ^?{}(thread_h* this);
    3849
    3950//-----------------------------------------------------------------------------
    40 // Public coroutine API
    41 static inline void suspend();
     51// thread runner
     52// Structure that actually start and stop threads
     53forall(otype T | is_thread(T) )
     54struct thread {
     55        T handle;
     56};
    4257
    43 forall(dtype T | is_coroutine(T))
    44 static inline void resume(T* cor);
     58forall(otype T | is_thread(T) )
     59void ?{}( thread(T)* this );
    4560
    46 forall(dtype T | is_coroutine(T))
    47 void prime(T* cor);
     61forall(otype T, ttype P | is_thread(T) | { void ?{}(T*, P); } )
     62void ?{}( thread(T)* this, P params );
     63
     64forall(otype T | is_thread(T) )
     65void ^?{}( thread(T)* this );
    4866
    4967//-----------------------------------------------------------------------------
    5068// PRIVATE exposed because of inline
    51 
    52 // Start coroutine routines
    53 extern "C" {
    54       forall(dtype T | is_coroutine(T))
    55       void CtxInvokeCoroutine(T* this);
    56 
    57       forall(dtype T | is_coroutine(T))
    58       void CtxStart(T* this, void (*invoke)(T*));
    59 }
    60 
    61 // Get current coroutine
    62 extern coroutine* current_coroutine; //PRIVATE, never use directly
    63 static inline coroutine* this_coroutine(void) {
    64         return current_coroutine;
    65 }
    66 
    67 // Private wrappers for context switch and stack creation
    68 extern void corCxtSw(coroutine* src, coroutine* dst);
    69 extern void create_stack( coStack_t* this, unsigned int storageSize );
    70 
    71 // Suspend implementation inlined for performance
    72 static inline void suspend() {
    73       coroutine* src = this_coroutine();                // optimization
    74 
    75         assertf( src->last != 0,
    76                 "Attempt to suspend coroutine %.256s (%p) that has never been resumed.\n"
    77                 "Possible cause is a suspend executed in a member called by a coroutine user rather than by the coroutine main.",
    78                 src->name, src );
    79         assertf( src->last->notHalted,
    80                 "Attempt by coroutine %.256s (%p) to suspend back to terminated coroutine %.256s (%p).\n"
    81                 "Possible cause is terminated coroutine's main routine has already returned.",
    82                 src->name, src, src->last->name, src->last );
    83 
    84         corCxtSw( src, src->last );
    85 }
    86 
    87 // Resume implementation inlined for performance
    88 forall(dtype T | is_coroutine(T))
    89 static inline void resume(T* cor) {
    90         coroutine* src = this_coroutine();              // optimization
    91         coroutine* dst = get_coroutine(cor);
    92 
    93       if( unlikely(!dst->stack.base) ) {
    94                 create_stack(&dst->stack, dst->stack.size);
    95                 CtxStart(cor, CtxInvokeCoroutine);
    96         }
    97 
    98       // not resuming self ?
    99         if ( src != dst ) {
    100                 assertf( dst->notHalted ,
    101                         "Attempt by coroutine %.256s (%p) to resume terminated coroutine %.256s (%p).\n"
    102                         "Possible cause is terminated coroutine's main routine has already returned.",
    103                         src->name, src, dst->name, dst );
    104 
    105             // set last resumer
    106                 dst->last = src;
    107         } // if
    108 
    109       // always done for performance testing
    110         corCxtSw( src, dst );
    111 }
    11269
    11370#endif //THREADS_H
Note: See TracChangeset for help on using the changeset viewer.