- File:
-
- 1 edited
-
libcfa/src/concurrency/coroutine.hfa (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/coroutine.hfa
rac2b598 rd4e68a6 10 10 // Created On : Mon Nov 28 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Feb 4 12:29:26 202013 // Update Count : 1112 // Last Modified On : Fri Jun 21 17:49:39 2019 13 // Update Count : 9 14 14 // 15 15 … … 25 25 trait is_coroutine(dtype T) { 26 26 void main(T & this); 27 $coroutine* get_coroutine(T & this);27 coroutine_desc * get_coroutine(T & this); 28 28 }; 29 29 30 #define DECL_COROUTINE(X) static inline $coroutine* get_coroutine(X& this) { return &this.__cor; } void main(X& this)30 #define DECL_COROUTINE(X) static inline coroutine_desc* get_coroutine(X& this) { return &this.__cor; } void main(X& this) 31 31 32 32 //----------------------------------------------------------------------------- … … 35 35 // void ^?{}( coStack_t & this ); 36 36 37 void ?{}( $coroutine & this, const char name[], void * storage, size_t storageSize );38 void ^?{}( $coroutine& this );37 void ?{}( coroutine_desc & this, const char * name, void * storage, size_t storageSize ); 38 void ^?{}( coroutine_desc & this ); 39 39 40 static inline void ?{}( $coroutine & this) { this{ "Anonymous Coroutine", 0p, 0 }; }41 static inline void ?{}( $coroutine & this, size_t stackSize) { this{ "Anonymous Coroutine", 0p, stackSize }; }42 static inline void ?{}( $coroutine& this, void * storage, size_t storageSize ) { this{ "Anonymous Coroutine", storage, storageSize }; }43 static inline void ?{}( $coroutine & this, const char name[]) { this{ name, 0p, 0 }; }44 static inline void ?{}( $coroutine & this, const char name[], size_t stackSize ) { this{ name, 0p, stackSize }; }40 static inline void ?{}( coroutine_desc & this) { this{ "Anonymous Coroutine", NULL, 0 }; } 41 static inline void ?{}( coroutine_desc & this, size_t stackSize) { this{ "Anonymous Coroutine", NULL, stackSize }; } 42 static inline void ?{}( coroutine_desc & this, void * storage, size_t storageSize ) { this{ "Anonymous Coroutine", storage, storageSize }; } 43 static inline void ?{}( coroutine_desc & this, const char * name) { this{ name, NULL, 0 }; } 44 static inline void ?{}( coroutine_desc & this, const char * name, size_t stackSize ) { this{ name, NULL, stackSize }; } 45 45 46 46 //----------------------------------------------------------------------------- … … 54 54 void prime(T & cor); 55 55 56 static inline struct $coroutine* active_coroutine() { return TL_GET( this_thread )->curr_cor; }56 static inline struct coroutine_desc * active_coroutine() { return TL_GET( this_thread )->curr_cor; } 57 57 58 58 //----------------------------------------------------------------------------- … … 61 61 // Start coroutine routines 62 62 extern "C" { 63 void __cfactx_invoke_coroutine(void (*main)(void *), void * this); 63 forall(dtype T | is_coroutine(T)) 64 void CtxInvokeCoroutine(T * this); 64 65 65 forall(dtype T)66 void __cfactx_start(void (*main)(T &), struct $coroutine * cor, T & this, void (*invoke)(void (*main)(void *), void*));66 forall(dtype T | is_coroutine(T)) 67 void CtxStart(T * this, void ( *invoke)(T *)); 67 68 68 extern void _ _cfactx_coroutine_unwind(struct _Unwind_Exception * storage, struct $coroutine*) __attribute__ ((__noreturn__));69 extern void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc *) __attribute__ ((__noreturn__)); 69 70 70 extern void __cfactx_switch( struct __stack_context_t * from, struct __stack_context_t * to ) asm ("__cfactx_switch");71 extern void CtxSwitch( struct __stack_context_t * from, struct __stack_context_t * to ) asm ("CtxSwitch"); 71 72 } 72 73 73 74 // Private wrappers for context switch and stack creation 74 75 // Wrapper for co 75 static inline void $ctx_switch( $coroutine * src, $coroutine * dst ) __attribute__((nonnull (1, 2))) {76 static inline void CoroutineCtxSwitch(coroutine_desc* src, coroutine_desc* dst) { 76 77 // set state of current coroutine to inactive 77 78 src->state = src->state == Halted ? Halted : Inactive; … … 82 83 // context switch to specified coroutine 83 84 verify( dst->context.SP ); 84 __cfactx_switch( &src->context, &dst->context );85 // when __cfactx_switch returns we are back in the src coroutine85 CtxSwitch( &src->context, &dst->context ); 86 // when CtxSwitch returns we are back in the src coroutine 86 87 87 88 // set state of new coroutine to active 88 89 src->state = Active; 89 90 90 if( unlikely(src->cancellation != 0p) ) {91 _ _cfactx_coroutine_unwind(src->cancellation, src);91 if( unlikely(src->cancellation != NULL) ) { 92 _CtxCoroutine_Unwind(src->cancellation, src); 92 93 } 93 94 } … … 102 103 // will also migrate which means this value will 103 104 // stay in syn with the TLS 104 $coroutine* src = TL_GET( this_thread )->curr_cor;105 coroutine_desc * src = TL_GET( this_thread )->curr_cor; 105 106 106 107 assertf( src->last != 0, … … 113 114 src->name, src, src->last->name, src->last ); 114 115 115 $ctx_switch( src, src->last );116 CoroutineCtxSwitch( src, src->last ); 116 117 } 117 118 … … 124 125 // will also migrate which means this value will 125 126 // stay in syn with the TLS 126 $coroutine* src = TL_GET( this_thread )->curr_cor;127 $coroutine* dst = get_coroutine(cor);127 coroutine_desc * src = TL_GET( this_thread )->curr_cor; 128 coroutine_desc * dst = get_coroutine(cor); 128 129 129 if( unlikely(dst->context.SP == 0p) ) { 130 TL_GET( this_thread )->curr_cor = dst; 130 if( unlikely(dst->context.SP == NULL) ) { 131 131 __stack_prepare(&dst->stack, 65000); 132 __cfactx_start(main, dst, cor, __cfactx_invoke_coroutine); 133 TL_GET( this_thread )->curr_cor = src; 132 CtxStart(&cor, CtxInvokeCoroutine); 134 133 } 135 134 … … 147 146 148 147 // always done for performance testing 149 $ctx_switch( src, dst );148 CoroutineCtxSwitch( src, dst ); 150 149 151 150 return cor; 152 151 } 153 152 154 static inline void resume( $coroutine * dst ) __attribute__((nonnull (1))) {153 static inline void resume(coroutine_desc * dst) { 155 154 // optimization : read TLS once and reuse it 156 155 // Safety note: this is preemption safe since if … … 158 157 // will also migrate which means this value will 159 158 // stay in syn with the TLS 160 $coroutine* src = TL_GET( this_thread )->curr_cor;159 coroutine_desc * src = TL_GET( this_thread )->curr_cor; 161 160 162 161 // not resuming self ? … … 172 171 173 172 // always done for performance testing 174 $ctx_switch( src, dst );173 CoroutineCtxSwitch( src, dst ); 175 174 } 176 175
Note:
See TracChangeset
for help on using the changeset viewer.