Ignore:
Timestamp:
Jan 17, 2017, 1:33:11 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, 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:
2fc88be
Parents:
aed3f54
Message:

Moved coroutines code in libcfa to coroutines header

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/threads

    raed3f54 r6a3d2e7  
    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"       //
    21 #include "invoke.h"
    2220
    23 //-----------------------------------------------------------------------------
    24 // Coroutine trait
    25 // Anything that implements this trait can be resumed.
    26 // 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);
    30 };
    31 
    32 //-----------------------------------------------------------------------------
    33 // Ctors and dtors
    34 void ?{}(coStack_t* this);
    35 void ?{}(coroutine* this);
    36 void ^?{}(coStack_t* this);
    37 void ^?{}(coroutine* this);
    38 
    39 //-----------------------------------------------------------------------------
    40 // Public coroutine API
    41 static inline void suspend();
    42 
    43 forall(dtype T | is_coroutine(T))
    44 static inline void resume(T* cor);
    45 
    46 forall(dtype T | is_coroutine(T))
    47 void prime(T* cor);
    48 
    49 //-----------------------------------------------------------------------------
    50 // 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 }
    11221
    11322#endif //THREADS_H
Note: See TracChangeset for help on using the changeset viewer.