Ignore:
Timestamp:
Oct 29, 2019, 4:01:24 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
773db65, 9421f3d8
Parents:
7951100 (diff), 8364209 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 moved

Legend:

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

    r7951100 rb067d9b  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 30 18:23:45 2018
    13 // Update Count     : 8
     12// Last Modified On : Fri Jun 21 17:49:39 2019
     13// Update Count     : 9
    1414//
    1515
     
    4646//-----------------------------------------------------------------------------
    4747// Public coroutine API
    48 static inline void suspend();
     48static inline void suspend(void);
    4949
    5050forall(dtype T | is_coroutine(T))
    51 static inline void resume(T & cor);
     51static inline T & resume(T & cor);
    5252
    5353forall(dtype T | is_coroutine(T))
    5454void prime(T & cor);
     55
     56static inline struct coroutine_desc * active_coroutine() { return TL_GET( this_thread )->curr_cor; }
    5557
    5658//-----------------------------------------------------------------------------
     
    6466      forall(dtype T | is_coroutine(T))
    6567      void CtxStart(T * this, void ( *invoke)(T *));
     68
     69        extern void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc *) __attribute__ ((__noreturn__));
     70
     71        extern void CtxSwitch( struct __stack_context_t * from, struct __stack_context_t * to ) asm ("CtxSwitch");
    6672}
    6773
    6874// Private wrappers for context switch and stack creation
    69 extern void CoroutineCtxSwitch(coroutine_desc * src, coroutine_desc * dst);
    70 extern void create_stack( coStack_t * this, unsigned int storageSize );
     75// Wrapper for co
     76static 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
     96extern void __stack_prepare   ( __stack_info_t * this, size_t size /* ignored if storage already allocated */);
    7197
    7298// Suspend implementation inlined for performance
    73 static inline void suspend() {
     99static inline void suspend(void) {
    74100        // optimization : read TLS once and reuse it
    75101        // Safety note: this is preemption safe since if
     
    77103        // will also migrate which means this value will
    78104        // stay in syn with the TLS
    79         coroutine_desc * src = TL_GET( this_coroutine );
     105        coroutine_desc * src = TL_GET( this_thread )->curr_cor;
    80106
    81107        assertf( src->last != 0,
     
    93119// Resume implementation inlined for performance
    94120forall(dtype T | is_coroutine(T))
    95 static inline void resume(T & cor) {
     121static inline T & resume(T & cor) {
    96122        // optimization : read TLS once and reuse it
    97123        // Safety note: this is preemption safe since if
     
    99125        // will also migrate which means this value will
    100126        // stay in syn with the TLS
    101         coroutine_desc * src = TL_GET( this_coroutine );
     127        coroutine_desc * src = TL_GET( this_thread )->curr_cor;
    102128        coroutine_desc * dst = get_coroutine(cor);
    103129
    104         if( unlikely(!dst->stack.base) ) {
    105                 create_stack(&dst->stack, dst->stack.size);
     130        if( unlikely(dst->context.SP == NULL) ) {
     131                __stack_prepare(&dst->stack, 65000);
    106132                CtxStart(&cor, CtxInvokeCoroutine);
    107133        }
     
    121147        // always done for performance testing
    122148        CoroutineCtxSwitch( src, dst );
     149
     150        return cor;
    123151}
    124152
     
    129157        // will also migrate which means this value will
    130158        // stay in syn with the TLS
    131         coroutine_desc * src = TL_GET( this_coroutine );
     159        coroutine_desc * src = TL_GET( this_thread )->curr_cor;
    132160
    133161        // not resuming self ?
Note: See TracChangeset for help on using the changeset viewer.