Changeset c4f411e for libcfa/src


Ignore:
Timestamp:
May 8, 2023, 6:21:10 PM (14 months ago)
Author:
caparsons <caparson@…>
Branches:
ADT, ast-experimental, master
Children:
02fa55e
Parents:
84018e0
Message:

fixed a bug which may potentially fix build

Location:
libcfa/src/concurrency
Files:
2 edited

Legend:

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

    r84018e0 rc4f411e  
    350350    #endif
    351351
    352     // check if we can complete operation. If so race to establish winner in special OR case
    353     if ( !node.park_counter && ( count != 0 || !prods`isEmpty || unlikely(closed) ) ) {
    354         if ( !__make_select_node_available( node ) ) { // we didn't win the race so give up on registering
    355            unlock( mutex_lock );
    356            return false;
     352    if ( !node.park_counter ) {
     353        // are we special case OR and front of cons is also special case OR
     354        if ( !unlikely(closed) && !prods`isEmpty && prods`first.clause_status && !prods`first.park_counter ) {
     355            if ( !__make_select_node_pending( node ) ) {
     356                unlock( mutex_lock );
     357                return false;
     358            }
     359           
     360            if ( __handle_waituntil_OR( prods ) ) {
     361                __prods_handoff( chan, ret );
     362                unlock( mutex_lock );
     363                return true;
     364            }
     365            __make_select_node_unsat( node );
     366        }
     367        // check if we can complete operation. If so race to establish winner in special OR case
     368        if ( count != 0 || !prods`isEmpty || unlikely(closed) ) {
     369            if ( !__make_select_node_available( node ) ) { // we didn't win the race so give up on registering
     370                unlock( mutex_lock );
     371                return false;
     372            }
    357373        }
    358374    }
     
    422438    #endif
    423439
    424     // check if we can complete operation. If so race to establish winner in special OR case
    425     if ( !node.park_counter && ( count != size || !cons`isEmpty || unlikely(closed) ) ) {
    426         if ( !__make_select_node_available( node ) ) { // we didn't win the race so give up on registering
    427            unlock( mutex_lock );
    428            return false;
     440    // special OR case handling
     441    if ( !node.park_counter ) {
     442        // are we special case OR and front of cons is also special case OR
     443        if ( !unlikely(closed) && !cons`isEmpty && cons`first.clause_status && !cons`first.park_counter ) {
     444            if ( !__make_select_node_pending( node ) ) {
     445                unlock( mutex_lock );
     446                return false;
     447            }
     448           
     449            if ( __handle_waituntil_OR( cons ) ) {
     450                __cons_handoff( chan, elem );
     451                unlock( mutex_lock );
     452                return true;
     453            }
     454            __make_select_node_unsat( node );
     455        }
     456        // check if we can complete operation. If so race to establish winner in special OR case
     457        if ( count != size || !cons`isEmpty || unlikely(closed) ) {
     458            if ( !__make_select_node_available( node ) ) { // we didn't win the race so give up on registering
     459                unlock( mutex_lock );
     460                return false;
     461            }
    429462        }
    430463    }
  • libcfa/src/concurrency/select.hfa

    r84018e0 rc4f411e  
    22
    33#include "containers/list.hfa"
     4// #include "alarm.hfa"
    45#include "stdint.h"
    56#include "kernel.hfa"
     7#include "time.hfa"
    68
    79struct select_node;
     
    911// node status
    1012static const unsigned long int __SELECT_UNSAT = 0;
    11 static const unsigned long int __SELECT_SAT = 1;
    12 static const unsigned long int __SELECT_RUN = 2;
     13static const unsigned long int __SELECT_PENDING = 1; // used only by special OR case
     14static const unsigned long int __SELECT_SAT = 2;
     15static const unsigned long int __SELECT_RUN = 3;
    1316
     17
     18// these are used inside the compiler to aid in code generation
    1419static inline bool __CFA_has_clause_run( unsigned long int status ) { return status == __SELECT_RUN; }
    1520static inline void __CFA_maybe_park( int * park_counter ) {
     
    5055    this.extra = extra;
    5156}
    52 
    5357static inline void ^?{}( select_node & this ) {}
    5458
     59// this is used inside the compiler to aid in code generation
    5560static inline unsigned long int * __get_clause_status( select_node & s ) { return s.clause_status; }
     61
     62// this is used inside the compiler to attempt to establish an else clause as a winner in the OR special case race
     63static inline bool __select_node_else_race( select_node & this ) with( this ) {
     64    unsigned long int cmp_status = __SELECT_UNSAT;
     65    return *clause_status == 0
     66            && __atomic_compare_exchange_n( clause_status, &cmp_status, __SELECT_SAT, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST );
     67}
    5668
    5769//-----------------------------------------------------------------------------
     
    7385};
    7486
    75 // this is used inside the compiler to attempt to establish an else clause as a winner in the OR special case race
    76 static inline bool __select_node_else_race( select_node & this ) with( this ) {
     87//=============================================================================================
     88// Waituntil Helpers
     89//=============================================================================================
     90
     91// used for the 2-stage avail needed by the special OR case
     92static inline bool __mark_select_node( select_node & this, unsigned long int val ) with( this ) {
     93    /* paranoid */ verify( park_counter == 0p );
     94    /* paranoid */ verify( clause_status != 0p );
     95
    7796    unsigned long int cmp_status = __SELECT_UNSAT;
    78     return *clause_status == 0
    79             && __atomic_compare_exchange_n( clause_status, &cmp_status, 1, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST );
     97    while( !__atomic_compare_exchange_n( clause_status, &cmp_status, val, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) {
     98        if ( cmp_status != __SELECT_PENDING ) return false;
     99        cmp_status = __SELECT_UNSAT;
     100    }
     101    return true;
     102}
     103
     104static inline void __make_select_node_unsat( select_node & this ) with( this ) {
     105    __atomic_store_n( clause_status, __SELECT_UNSAT, __ATOMIC_SEQ_CST );
     106}
     107
     108static inline bool __make_select_node_pending( select_node & this ) with( this ) {
     109    return __mark_select_node( this, __SELECT_PENDING );
    80110}
    81111
     
    83113// return true if we want to unpark the thd
    84114static inline bool __make_select_node_available( select_node & this ) with( this ) {
     115    /* paranoid */ verify( clause_status != 0p );
     116    if( !park_counter )
     117        return __mark_select_node( this, (unsigned long int)&this );
     118    // return *clause_status == 0
     119    //     && __atomic_compare_exchange_n( clause_status, &cmp_status, (unsigned long int)&this, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ); // OR specific case where race was won
     120
    85121    unsigned long int cmp_status = __SELECT_UNSAT;
    86122
    87     if( !park_counter )
    88         return *clause_status == 0
    89             && __atomic_compare_exchange_n( clause_status, &cmp_status, (unsigned long int)&this, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ); // OR specific case where race was won
    90 
    91     return *clause_status == 0
     123    return *clause_status == 0 // C_TODO might not need a cmp_xchg in non special OR case
    92124        && __atomic_compare_exchange_n( clause_status, &cmp_status, __SELECT_SAT, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) // can maybe just use atomic write
    93125        && !__atomic_add_fetch( park_counter, 1, __ATOMIC_SEQ_CST);
     
    128160}
    129161
     162
Note: See TracChangeset for help on using the changeset viewer.