- File:
-
- 1 edited
-
src/libcfa/concurrency/coroutines (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/coroutines
rc84e80a raed3f54 1 // - *- Mode: CFA - *-2 //3 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo4 //5 // The contents of this file are covered under the licence agreement in the6 // file "LICENCE" distributed with Cforall.7 //8 // coroutines --9 //10 // Author : Thierry Delisle11 // Created On : Mon Nov 28 12:27:26 201612 // Last Modified By : Thierry Delisle13 // Last Modified On : Mon Nov 28 12:27:26 201614 // Update Count : 015 //16 17 #ifndef COROUTINES_H18 #define COROUTINES_H19 20 #include "assert"21 #include "invoke.h"22 23 //-----------------------------------------------------------------------------24 // Coroutine trait25 // Anything that implements this trait can be resumed.26 // Anything that is resumed is a coroutine.27 trait is_coroutine(dtype T) {28 void main(T * this);29 coroutine * get_coroutine(T * this);30 };31 32 #define DECL_COROUTINE(X) static inline coroutine* get_coroutine(X* this) { return &this->c; } void main(X* this);33 34 //-----------------------------------------------------------------------------35 // Ctors and dtors36 void ?{}(coStack_t * this);37 void ?{}(coroutine * this);38 void ^?{}(coStack_t * this);39 void ^?{}(coroutine * this);40 41 //-----------------------------------------------------------------------------42 // Public coroutine API43 static inline void suspend();44 45 forall(dtype T | is_coroutine(T))46 static inline void resume(T * cor);47 48 forall(dtype T | is_coroutine(T))49 void prime(T * cor);50 51 //-----------------------------------------------------------------------------52 // PRIVATE exposed because of inline53 54 // Start coroutine routines55 extern "C" {56 forall(dtype T | is_coroutine(T))57 void CtxInvokeCoroutine(T * this);58 59 forall(dtype T | is_coroutine(T))60 void CtxStart(T * this, void ( *invoke)(T *));61 }62 63 // Get current coroutine64 extern coroutine * current_coroutine; //PRIVATE, never use directly65 static inline coroutine * this_coroutine(void) {66 return current_coroutine;67 }68 69 // Private wrappers for context switch and stack creation70 extern void corCxtSw(coroutine * src, coroutine * dst);71 extern void create_stack( coStack_t * this, unsigned int storageSize );72 73 // Suspend implementation inlined for performance74 static inline void suspend() {75 coroutine * src = this_coroutine(); // optimization76 77 assertf( src->last != 0,78 "Attempt to suspend coroutine %.256s (%p) that has never been resumed.\n"79 "Possible cause is a suspend executed in a member called by a coroutine user rather than by the coroutine main.",80 src->name, src );81 assertf( src->last->notHalted,82 "Attempt by coroutine %.256s (%p) to suspend back to terminated coroutine %.256s (%p).\n"83 "Possible cause is terminated coroutine's main routine has already returned.",84 src->name, src, src->last->name, src->last );85 86 corCxtSw( src, src->last );87 }88 89 // Resume implementation inlined for performance90 forall(dtype T | is_coroutine(T))91 static inline void resume(T * cor) {92 coroutine * src = this_coroutine(); // optimization93 coroutine * dst = get_coroutine(cor);94 95 if( unlikely(!dst->stack.base) ) {96 create_stack(&dst->stack, dst->stack.size);97 CtxStart(cor, CtxInvokeCoroutine);98 }99 100 // not resuming self ?101 if ( src != dst ) {102 assertf( dst->notHalted ,103 "Attempt by coroutine %.256s (%p) to resume terminated coroutine %.256s (%p).\n"104 "Possible cause is terminated coroutine's main routine has already returned.",105 src->name, src, dst->name, dst );106 107 // set last resumer108 dst->last = src;109 } // if110 111 // always done for performance testing112 corCxtSw( src, dst );113 }114 115 #endif //COROUTINES_H116 117 // Local Variables: //118 // mode: c //119 // tab-width: 4 //120 // End: //
Note:
See TracChangeset
for help on using the changeset viewer.