Ignore:
Timestamp:
Dec 15, 2016, 12:40:01 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
66f8528
Parents:
12d44bb
Message:

Some optimization and clean-up of coroutines

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/threads

    r12d44bb r596f987b  
    1818#define __THREADS_H__
    1919
     20#include "assert"       //
    2021#include "invoke.h"
    2122
    22 void ?{}(coStack_t* this);
    23 
    24 void ?{}(coroutine* this);
    25 
     23//-----------------------------------------------------------------------------
     24// Coroutine trait
     25// Anything that implements this trait can be resumed.
     26// Anything that is resumed is a coroutine.
    2627trait is_coroutine(dtype T) {
    2728      void co_main(T* this);
     
    2930};
    3031
    31 void suspend(void);
     32//-----------------------------------------------------------------------------
     33// Ctors and dtors
     34void ?{}(coStack_t* this);
     35void ?{}(coroutine* this);
     36void ^?{}(coStack_t* this);
     37void ^?{}(coroutine* this);
     38
     39//-----------------------------------------------------------------------------
     40// Public coroutine API
     41static inline void suspend();
    3242
    3343forall(dtype T | is_coroutine(T))
    34 void resume(T* cor);
     44static inline void resume(T* cor);
    3545
    3646forall(dtype T | is_coroutine(T))
    3747void prime(T* cor);
     48
     49//-----------------------------------------------------------------------------
     50// PRIVATE exposed because of inline
     51
     52// Start coroutine routines
     53extern "C" {
     54      forall(dtype T | is_coroutine(T))
     55      void CtxInvokeCoroutine(T* this);
     56
     57      forall(dtype T | is_coroutine(T))
     58      void CtxStart(T* this, void (*invoke)(T*));
     59}
     60
     61// Get current coroutine
     62extern coroutine* current_coroutine; //PRIVATE, never use directly
     63static inline coroutine* this_coroutine(void) {
     64        return current_coroutine;
     65}
     66
     67// Private wrappers for context switch and stack creation
     68extern void corCxtSw(coroutine* src, coroutine* dst);
     69extern void create_stack( coStack_t* this, unsigned int storageSize );
     70
     71// Suspend implementation inlined for performance
     72static inline void suspend() {
     73      coroutine* src = this_coroutine();                // optimization
     74
     75        assertf( src->last != 0,
     76                "Attempt to suspend coroutine %.256s (%p) that has never been resumed.\n"
     77                "Possible cause is a suspend executed in a member called by a coroutine user rather than by the coroutine main.",
     78                src->name, src );
     79        assertf( src->last->notHalted,
     80                "Attempt by coroutine %.256s (%p) to suspend back to terminated coroutine %.256s (%p).\n"
     81                "Possible cause is terminated coroutine's main routine has already returned.",
     82                src->name, src, src->last->name, src->last );
     83
     84        corCxtSw( src, src->last );
     85}
     86
     87// Resume implementation inlined for performance
     88forall(dtype T | is_coroutine(T))
     89static inline void resume(T* cor) {
     90        coroutine* src = this_coroutine();              // optimization
     91        coroutine* dst = get_coroutine(cor);
     92
     93      if( unlikely(!dst->stack.base) ) {
     94                create_stack(&dst->stack, dst->stack.size);
     95                CtxStart(cor, CtxInvokeCoroutine);
     96        }
     97
     98      // not resuming self ?
     99        if ( src != dst ) {
     100                assertf( dst->notHalted ,
     101                        "Attempt by coroutine %.256s (%p) to resume terminated coroutine %.256s (%p).\n"
     102                        "Possible cause is terminated coroutine's main routine has already returned.",
     103                        src->name, src, dst->name, dst );
     104
     105            // set last resumer
     106                dst->last = src;
     107        } // if
     108
     109      // always done for performance testing
     110        corCxtSw( src, dst );
     111}
    38112
    39113#endif //__THREADS_H__
Note: See TracChangeset for help on using the changeset viewer.