Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/threads

    rc84e80a rbb82c03  
    99//
    1010// Author           : Thierry Delisle
    11 // Created On       : Tue Jan 17 12:27:26 2016
     11// Created On       : Mon Nov 28 12:27:26 2016
    1212// Last Modified By : Thierry Delisle
    13 // Last Modified On : --
     13// Last Modified On : Mon Nov 28 12:27:26 2016
    1414// Update Count     : 0
    1515//
     
    1818#define THREADS_H
    1919
    20 #include "assert"
     20#include "assert"       //
    2121#include "invoke.h"
    22 
    23 #include "coroutines"
    2422
    2523//-----------------------------------------------------------------------------
     
    2725// Anything that implements this trait can be resumed.
    2826// Anything that is resumed is a coroutine.
    29 trait is_thread(dtype T /*| sized(T)*/) {
    30       void main(T* this);
    31       thread_h* get_thread(T* this);
    32         /*void ?{}(T*);
    33         void ^?{}(T*);*/
     27trait is_coroutine(dtype T) {
     28      void co_main(T* this);
     29      coroutine* get_coroutine(T* this);
    3430};
    35 
    36 forall(otype T | is_thread(T) )
    37 static inline coroutine* get_coroutine(T* this) {
    38         return &get_thread(this)->c;
    39 }
    40 
    41 static inline coroutine* get_coroutine(thread_h* this) {
    42         return &this->c;
    43 }
    4431
    4532//-----------------------------------------------------------------------------
    4633// Ctors and dtors
    47 void ?{}(thread_h* this);
    48 void ^?{}(thread_h* this);
     34void ?{}(coStack_t* this);
     35void ?{}(coroutine* this);
     36void ^?{}(coStack_t* this);
     37void ^?{}(coroutine* this);
    4938
    5039//-----------------------------------------------------------------------------
    51 // thread runner
    52 // Structure that actually start and stop threads
    53 forall(otype T | is_thread(T) )
    54 struct thread {
    55         T handle;
    56 };
     40// Public coroutine API
     41static inline void suspend();
    5742
    58 forall(otype T | is_thread(T) )
    59 void ?{}( thread(T)* this );
     43forall(dtype T | is_coroutine(T))
     44static inline void resume(T* cor);
    6045
    61 forall(otype T, ttype P | is_thread(T) | { void ?{}(T*, P); } )
    62 void ?{}( thread(T)* this, P params );
    63 
    64 forall(otype T | is_thread(T) )
    65 void ^?{}( thread(T)* this );
     46forall(dtype T | is_coroutine(T))
     47void prime(T* cor);
    6648
    6749//-----------------------------------------------------------------------------
    6850// PRIVATE exposed because of inline
     51
     52// Start coroutine routines
     53extern "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
     62extern coroutine* current_coroutine; //PRIVATE, never use directly
     63static inline coroutine* this_coroutine(void) {
     64        return current_coroutine;
     65}
     66
     67// Private wrappers for context switch and stack creation
     68extern void corCxtSw(coroutine* src, coroutine* dst);
     69extern void create_stack( coStack_t* this, unsigned int storageSize );
     70
     71// Suspend implementation inlined for performance
     72static 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
     88forall(dtype T | is_coroutine(T))
     89static 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}
    69112
    70113#endif //THREADS_H
Note: See TracChangeset for help on using the changeset viewer.