- File:
-
- 1 edited
-
libcfa/src/concurrency/coroutine.hfa (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/coroutine.hfa
r10248ae0 r73abe95 46 46 //----------------------------------------------------------------------------- 47 47 // Public coroutine API 48 static inline void suspend( void);48 static inline void suspend(); 49 49 50 50 forall(dtype T | is_coroutine(T)) 51 static inline T &resume(T & cor);51 static inline void resume(T & cor); 52 52 53 53 forall(dtype T | is_coroutine(T)) … … 64 64 forall(dtype T | is_coroutine(T)) 65 65 void CtxStart(T * this, void ( *invoke)(T *)); 66 67 extern void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc *) __attribute__ ((__noreturn__));68 69 extern void CtxSwitch( struct __stack_context_t * from, struct __stack_context_t * to ) asm ("CtxSwitch");70 66 } 71 67 72 68 // Private wrappers for context switch and stack creation 73 // Wrapper for co 74 static inline void CoroutineCtxSwitch(coroutine_desc* src, coroutine_desc* dst) { 75 // set state of current coroutine to inactive 76 src->state = src->state == Halted ? Halted : Inactive; 77 78 // set new coroutine that task is executing 79 TL_GET( this_thread )->curr_cor = dst; 80 81 // context switch to specified coroutine 82 verify( dst->context.SP ); 83 CtxSwitch( &src->context, &dst->context ); 84 // when CtxSwitch returns we are back in the src coroutine 85 86 // set state of new coroutine to active 87 src->state = Active; 88 89 if( unlikely(src->cancellation != NULL) ) { 90 _CtxCoroutine_Unwind(src->cancellation, src); 91 } 92 } 93 94 extern void __stack_prepare ( __stack_info_t * this, size_t size /* ignored if storage already allocated */); 69 extern void CoroutineCtxSwitch(coroutine_desc * src, coroutine_desc * dst); 70 extern void create_stack( coStack_t * this, unsigned int storageSize ); 95 71 96 72 // Suspend implementation inlined for performance 97 static inline void suspend( void) {73 static inline void suspend() { 98 74 // optimization : read TLS once and reuse it 99 75 // Safety note: this is preemption safe since if … … 101 77 // will also migrate which means this value will 102 78 // stay in syn with the TLS 103 coroutine_desc * src = TL_GET( this_ thread )->curr_cor;79 coroutine_desc * src = TL_GET( this_coroutine ); 104 80 105 81 assertf( src->last != 0, … … 117 93 // Resume implementation inlined for performance 118 94 forall(dtype T | is_coroutine(T)) 119 static inline T &resume(T & cor) {95 static inline void resume(T & cor) { 120 96 // optimization : read TLS once and reuse it 121 97 // Safety note: this is preemption safe since if … … 123 99 // will also migrate which means this value will 124 100 // stay in syn with the TLS 125 coroutine_desc * src = TL_GET( this_ thread )->curr_cor;101 coroutine_desc * src = TL_GET( this_coroutine ); 126 102 coroutine_desc * dst = get_coroutine(cor); 127 103 128 if( unlikely( dst->context.SP == NULL) ) {129 __stack_prepare(&dst->stack, 65000);104 if( unlikely(!dst->stack.base) ) { 105 create_stack(&dst->stack, dst->stack.size); 130 106 CtxStart(&cor, CtxInvokeCoroutine); 131 107 } … … 145 121 // always done for performance testing 146 122 CoroutineCtxSwitch( src, dst ); 147 148 return cor;149 123 } 150 124 … … 155 129 // will also migrate which means this value will 156 130 // stay in syn with the TLS 157 coroutine_desc * src = TL_GET( this_ thread )->curr_cor;131 coroutine_desc * src = TL_GET( this_coroutine ); 158 132 159 133 // not resuming self ?
Note:
See TracChangeset
for help on using the changeset viewer.