Changeset c06551b


Ignore:
Timestamp:
Jun 9, 2022, 4:30:00 PM (23 months ago)
Author:
caparsons <caparson@…>
Branches:
ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
Children:
6d41f66
Parents:
aeb20a4
Message:

added wait_any to fwd.cfa for future_t

Files:
2 added
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/kernel/fwd.hfa

    raeb20a4 rc06551b  
    200200                                        struct thread$ * expected = this.ptr;
    201201                                        if(expected == 1p) return false;
    202                                         /* paranoid */ verify( expected == 0p );
    203202                                        if(__atomic_compare_exchange_n(&this.ptr, &expected, active_thread(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
    204203                                                park();
     
    213212                        thread$ * post(oneshot & this, bool do_unpark = true) {
    214213                                struct thread$ * got = __atomic_exchange_n( &this.ptr, 1p, __ATOMIC_SEQ_CST);
    215                                 if( got == 0p ) return 0p;
     214                                if( got == 0p || got == 1p ) return 0p;
    216215                                if(do_unpark) unpark( got );
    217216                                return got;
     
    263262
    264263                                        // The future is not fulfilled, try to setup the wait context
    265                                         /* paranoid */ verify( expected == 0p );
    266264                                        if(__atomic_compare_exchange_n(&this.ptr, &expected, &wait_ctx, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
    267265                                                return true;
     
    275273                        // should retract the wait ctx
    276274                        // intented to be use by wait, wait_any, waitfor, etc. rather than used directly
    277                         void retract( future_t & this, oneshot & wait_ctx ) {
     275                        bool retract( future_t & this, oneshot & wait_ctx ) {
    278276                                // Remove the wait context
    279277                                struct oneshot * got = __atomic_exchange_n( &this.ptr, 0p, __ATOMIC_SEQ_CST);
    280278
    281279                                // got == 0p: future was never actually setup, just return
    282                                 if( got == 0p ) return;
     280                                if( got == 0p ) return false;
    283281
    284282                                // got == wait_ctx: since fulfil does an atomic_swap,
    285283                                // if we got back the original then no one else saw context
    286284                                // It is safe to delete (which could happen after the return)
    287                                 if( got == &wait_ctx ) return;
     285                                if( got == &wait_ctx ) return false;
    288286
    289287                                // got == 1p: the future is ready and the context was fully consumed
    290288                                // the server won't use the pointer again
    291289                                // It is safe to delete (which could happen after the return)
    292                                 if( got == 1p ) return;
     290                                if( got == 1p ) return true;
    293291
    294292                                // got == 2p: the future is ready but the context hasn't fully been consumed
     
    296294                                if( got == 2p ) {
    297295                                        while( this.ptr != 1p ) Pause();
    298                                         return;
     296                                        return false;
    299297                                }
    300298
     
    379377                                return ret;
    380378                        }
     379
     380                        // Wait for any future to be fulfilled
     381                        future_t & wait_any( future_t * futures, size_t num_futures ) {
     382                                oneshot temp;
     383
     384                                // setup all futures
     385                                // if any are already satisfied return
     386                                for ( i; num_futures ) {
     387                                        if( !setup(futures[i], temp) ) return futures[i];
     388                                }
     389                               
     390                                // Wait context is setup, just wait on it
     391                                wait( temp );
     392                               
     393                                size_t ret;
     394                                // attempt to retract all futures
     395                                for ( i; num_futures ) {
     396                                        if ( retract( futures[i], temp ) ) ret = i;
     397                                }
     398                               
     399                                return futures[ret];
     400                        }
    381401                }
    382402
Note: See TracChangeset for help on using the changeset viewer.