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

fixed a bug which may potentially fix build

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.