Ignore:
File:
1 edited

Legend:

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

    r63364d8 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");
    7066}
    7167
    7268// 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 */);
     69extern void CoroutineCtxSwitch(coroutine_desc * src, coroutine_desc * dst);
     70extern void create_stack( coStack_t * this, unsigned int storageSize );
    9571
    9672// Suspend implementation inlined for performance
     
    126102        coroutine_desc * dst = get_coroutine(cor);
    127103
    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);
    130106                CtxStart(&cor, CtxInvokeCoroutine);
    131107        }
     
    170146}
    171147
     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// }
     179
     180// static inline void suspend_return(void) {
     181//      // optimization : read TLS once and reuse it
     182//      // Safety note: this is preemption safe since if
     183//      // preemption occurs after this line, the pointer
     184//      // will also migrate which means this value will
     185//      // stay in syn with the TLS
     186//      coroutine_desc * src = TL_GET( this_thread )->curr_cor;
     187
     188//      assertf( src->last != 0,
     189//              "Attempt to suspend coroutine \"%.256s\" (%p) that has never been resumed.\n"
     190//              "Possible cause is a suspend executed in a member called by a coroutine user rather than by the coroutine main.",
     191//              src->name, src );
     192//      assertf( src->last->state != Halted,
     193//              "Attempt by coroutine \"%.256s\" (%p) to suspend back to terminated coroutine \"%.256s\" (%p).\n"
     194//              "Possible cause is terminated coroutine's main routine has already returned.",
     195//              src->name, src, src->last->name, src->last );
     196
     197//      // Safety note : Preemption must be disabled here since kernelTLS.this_coroutine must always be up to date
     198//       verify( TL_GET( preemption_state.enabled ) || TL_GET( this_processor )->do_terminate );
     199//       disable_interrupts();
     200
     201//       // set state of current coroutine to inactive
     202//       src->state = src->state == Halted ? Halted : Inactive;
     203
     204//       // set new coroutine that task is executing
     205//       kernelTLS.this_coroutine = dst;
     206
     207//       // context switch to specified coroutine
     208//       assert( src->stack.context );
     209//      CtxRet( src->stack.context );
     210
     211//      abort();
     212// }
     213
    172214// Local Variables: //
    173215// mode: c //
Note: See TracChangeset for help on using the changeset viewer.