Ignore:
File:
1 edited

Legend:

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

    r70a4ed5 r6f774be  
    9191    // For unregistering a select stmt on a selectable concurrency primitive
    9292    // If true is returned then the corresponding code block is run (only in non-special OR case and only if node status is not RUN)
    93     bool unregister_select( T &, select_node & );
     93    bool unregister_select( T &, select_node &  );
    9494
    9595    // This routine is run on the selecting thread prior to executing the statement corresponding to the select_node
    9696    //    passed as an arg to this routine
    9797    // If on_selected returns false, the statement is not run, if it returns true it is run.
    98     void on_selected( T &, select_node & );
     98    bool on_selected( T &, select_node & );
    9999};
    100100
     
    102102// Waituntil Helpers
    103103//=============================================================================================
     104
     105static inline void __make_select_node_unsat( select_node & this ) with( this ) {
     106    __atomic_store_n( clause_status, __SELECT_UNSAT, __ATOMIC_SEQ_CST );
     107}
     108static inline void __make_select_node_sat( select_node & this ) with( this ) {
     109    __atomic_store_n( clause_status, __SELECT_SAT, __ATOMIC_SEQ_CST );
     110}
    104111
    105112// used for the 2-stage avail needed by the special OR case
     
    116123}
    117124
    118 static inline void __make_select_node_unsat( select_node & this ) with( this ) {
    119     __atomic_store_n( clause_status, __SELECT_UNSAT, __ATOMIC_SEQ_CST );
    120 }
    121 static inline void __make_select_node_sat( select_node & this ) with( this ) {
    122     __atomic_store_n( clause_status, __SELECT_SAT, __ATOMIC_SEQ_CST );
     125// used for the 2-stage avail by the thread who owns a pending node
     126static inline bool __pending_set_other( select_node & other, select_node & mine, unsigned long int val ) with( other ) {
     127    /* paranoid */ verify( park_counter == 0p );
     128    /* paranoid */ verify( clause_status != 0p );
     129
     130    unsigned long int cmp_status = __SELECT_UNSAT;
     131    while( !__atomic_compare_exchange_n( clause_status, &cmp_status, val, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) {
     132        if ( cmp_status != __SELECT_PENDING )
     133            return false;
     134
     135        // toggle current status flag to avoid starvation/deadlock
     136        __make_select_node_unsat( mine );
     137        cmp_status = __SELECT_UNSAT;
     138        if ( !__atomic_compare_exchange_n( mine.clause_status, &cmp_status, __SELECT_PENDING, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) )
     139            return false;
     140        cmp_status = __SELECT_UNSAT;
     141    }
     142    return true;
    123143}
    124144
     
    188208bool register_select( select_timeout_node & this, select_node & node );
    189209bool unregister_select( select_timeout_node & this, select_node & node );
    190 void on_selected( select_timeout_node & this, select_node & node );
     210bool on_selected( select_timeout_node & this, select_node & node );
    191211
    192212// Gateway routines to waituntil on duration
Note: See TracChangeset for help on using the changeset viewer.