Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/coroutine.hfa

    r5b11c25 r212c2187  
    6464      forall(dtype T | is_coroutine(T))
    6565      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         extern void CtxStore ( struct __stack_context_t * from, __attribute__((noreturn)) void (*__callback)(void) ) asm ("CtxStore");
    71         extern void CtxRet   ( struct __stack_context_t * to ) asm ("CtxRet") __attribute__ ((__noreturn__));
    7266}
    7367
    7468// Private wrappers for context switch and stack creation
    75 // Wrapper for co
    76 static inline void CoroutineCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {
    77         // set state of current coroutine to inactive
    78         src->state = src->state == Halted ? Halted : Inactive;
    79 
    80         // set new coroutine that task is executing
    81         TL_GET( this_thread )->curr_cor = dst;
    82 
    83         // context switch to specified coroutine
    84         verify( dst->context.SP );
    85         CtxSwitch( &src->context, &dst->context );
    86         // when CtxSwitch returns we are back in the src coroutine
    87 
    88         // set state of new coroutine to active
    89         src->state = Active;
    90 
    91         if( unlikely(src->cancellation != NULL) ) {
    92                 _CtxCoroutine_Unwind(src->cancellation, src);
    93         }
    94 }
    95 
    96 extern void __stack_prepare   ( __stack_info_t * this, size_t size /* ignored if storage already allocated */);
     69extern void CoroutineCtxSwitch(coroutine_desc * src, coroutine_desc * dst);
     70extern void create_stack( coStack_t * this, unsigned int storageSize );
    9771
    9872// Suspend implementation inlined for performance
     
    128102        coroutine_desc * dst = get_coroutine(cor);
    129103
    130         if( unlikely(dst->context.SP == NULL) ) {
    131                 __stack_prepare(&dst->stack, 65000);
     104        if( unlikely(!dst->stack.base) ) {
     105                create_stack(&dst->stack, dst->stack.size);
    132106                CtxStart(&cor, CtxInvokeCoroutine);
    133107        }
     
    172146}
    173147
    174 static inline void suspend_then(fptr_t call) {
    175         // optimization : read TLS once and reuse it
    176         // Safety note: this is preemption safe since if
    177         // preemption occurs after this line, the pointer
    178         // will also migrate which means this value will
    179         // stay in syn with the TLS
    180         coroutine_desc * src = TL_GET( this_thread )->curr_cor;
    181 
    182         assertf( src->last != 0,
    183                 "Attempt to suspend coroutine \"%.256s\" (%p) that has never been resumed.\n"
    184                 "Possible cause is a suspend executed in a member called by a coroutine user rather than by the coroutine main.",
    185                 src->name, src );
    186         assertf( src->last->state != Halted,
    187                 "Attempt by coroutine \"%.256s\" (%p) to suspend back to terminated coroutine \"%.256s\" (%p).\n"
    188                 "Possible cause is terminated coroutine's main routine has already returned.",
    189                 src->name, src, src->last->name, src->last );
    190 
    191         src->state = PreInactive;
    192 
    193       // context switch to specified coroutine
    194       assert( src->context.SP );
    195 
    196         __attribute__((noreturn)) void __suspend_callback(void) {
    197                 call();
    198 
    199                 // set state of current coroutine to inactive
    200                 src->state = src->state == Halted ? Halted : Inactive;
    201 
    202                 TL_GET( this_thread )->curr_cor = src->last;
    203 
    204                 // context switch to specified coroutine
    205                 assert( src->last->context.SP );
    206                 CtxRet( &src->last->context );
    207 
    208                 abort();
    209         }
    210       CtxStore( &src->context, __suspend_callback );
    211         // when CtxStore returns we are back in the src coroutine
    212 
    213         // set state of new coroutine to active
    214         src->state = Active;
    215 
    216         if( unlikely(src->cancellation != NULL) ) {
    217                 _CtxCoroutine_Unwind(src->cancellation, src);
    218         }
    219 
    220         return;
    221 }
     148
     149
     150// static inline bool suspend_checkpoint(void) {
     151//      // optimization : read TLS once and reuse it
     152//      // Safety note: this is preemption safe since if
     153//      // preemption occurs after this line, the pointer
     154//      // will also migrate which means this value will
     155//      // stay in syn with the TLS
     156//      // set state of current coroutine to inactive
     157//       this->state = Checkpoint;
     158
     159//       // context switch to specified coroutine
     160//       assert( src->stack.context );
     161
     162//       CtxStore(src->stack.context);
     163
     164//      bool ret = this->state == Checkpoint;
     165
     166//       // set state of new coroutine to active
     167//       src->state = Active;
     168
     169//       enable_interrupts( __cfaabi_dbg_ctx );
     170//       // Safety note : This could cause some false positives due to preemption
     171//       verify( TL_GET( preemption_state.enabled ) || TL_GET( this_processor )->do_terminate );
     172
     173//       if( unlikely(src->cancellation != NULL) ) {
     174//             _CtxCoroutine_Unwind(src->cancellation);
     175//       }
     176
     177//      return ret;
     178// }
    222179
    223180// static inline void suspend_return(void) {
Note: See TracChangeset for help on using the changeset viewer.