Changeset ffec1bf for libcfa/src


Ignore:
Timestamp:
Jul 25, 2022, 2:23:28 PM (3 years ago)
Author:
Fangren Yu <f37yu@…>
Branches:
ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
Children:
4c48be0, 5cf1228, def751f
Parents:
9e23b446 (diff), 1f950c3b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
libcfa/src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/Makefile.am

    r9e23b446 rffec1bf  
    216216nobase_cfa_include_HEADERS = ${stdhdr} ${inst_headers_src} ${inst_headers_nosrc} ${inst_thread_headers_src} ${inst_thread_headers_nosrc}
    217217EXTRA_DIST = stdhdr
     218DISTCLEANFILES = $(libdeps) $(thread_libdeps)
    218219
    219220#----------------------------------------------------------------------------------------------------------------
     
    221222        -rm -rf ${CFA_INCDIR} ${CFA_LIBDIR}
    222223
    223 distclean-local:
    224         find ${builddir} -path '*.Plo' -delete
     224#distclean-local:
     225#       find ${builddir} -path '*.Plo' -delete
    225226
    226227
  • libcfa/src/concurrency/kernel/fwd.hfa

    r9e23b446 rffec1bf  
    254254                        // intented to be use by wait, wait_any, waitfor, etc. rather than used directly
    255255                        bool setup( future_t & this, oneshot & wait_ctx ) {
    256                                 /* paranoid */ verify( wait_ctx.ptr == 0p );
     256                                /* paranoid */ verify( wait_ctx.ptr == 0p || wait_ctx.ptr == 1p );
    257257                                // The future needs to set the wait context
    258258                                for() {
     
    274274                        // intented to be use by wait, wait_any, waitfor, etc. rather than used directly
    275275                        bool retract( future_t & this, oneshot & wait_ctx ) {
    276                                 for() {
    277                                         struct oneshot * expected = this.ptr;
    278 
    279                                         // expected == 0p: future was never actually setup, just return
    280                                         if( expected == 0p ) return false;
    281 
    282                                         // expected == 1p: the future is ready and the context was fully consumed
    283                                         // the server won't use the pointer again
    284                                         // It is safe to delete (which could happen after the return)
    285                                         if( expected == 1p ) return true;
    286 
    287                                         // expected == 2p: the future is ready but the context hasn't fully been consumed
    288                                         // spin until it is safe to move on
    289                                         if( expected == 2p ) {
    290                                                 while( this.ptr != 1p ) Pause();
    291                                                 /* paranoid */ verify( this.ptr == 1p );
    292                                                 return true;
    293                                         }
    294 
    295                                         // expected != wait_ctx: the future was setup with a different context ?!?!
    296                                         // something went wrong here, abort
    297                                         if( expected != &wait_ctx ) abort("Future in unexpected state");
    298 
     276                                struct oneshot * expected = this.ptr;
     277
     278                                // attempt to remove the context so it doesn't get consumed.
     279                                if(__atomic_compare_exchange_n( &this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
    299280                                        // we still have the original context, then no one else saw it
    300                                         // attempt to remove the context so it doesn't get consumed.
    301                                         if(__atomic_compare_exchange_n( &this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
    302                                                 return false;
    303                                         }
    304                                 }
     281                                        return false;
     282                                }
     283
     284                                // expected == 0p: future was never actually setup, just return
     285                                if( expected == 0p ) return false;
     286
     287                                // expected == 1p: the future is ready and the context was fully consumed
     288                                // the server won't use the pointer again
     289                                // It is safe to delete (which could happen after the return)
     290                                if( expected == 1p ) return true;
     291
     292                                // expected == 2p: the future is ready but the context hasn't fully been consumed
     293                                // spin until it is safe to move on
     294                                if( expected == 2p ) {
     295                                        while( this.ptr != 1p ) Pause();
     296                                        /* paranoid */ verify( this.ptr == 1p );
     297                                        return true;
     298                                }
     299
     300                                // anything else: the future was setup with a different context ?!?!
     301                                // something went wrong here, abort
     302                                abort("Future in unexpected state");
    305303                        }
    306304
  • libcfa/src/concurrency/locks.cfa

    r9e23b446 rffec1bf  
    237237                // This pthread_cond_var member is called from the kernel, and therefore, cannot block, but it can spin.
    238238                lock( cond->lock __cfaabi_dbg_ctx2 );
    239 
    240239                // this check is necessary to avoid a race condition since this timeout handler
    241240                //      may still be called after a thread has been removed from the queue but
     
    347346                size_t recursion_count = queue_and_get_recursion(this, &info);
    348347                alarm_node_wrap(L) node_wrap = { t, 0`s, callback, &this, &info };
     348                unlock( lock );
     349
     350                // registers alarm outside cond lock to avoid deadlock
    349351                register_self( &node_wrap.alarm_node );
    350                 unlock( lock );
    351352
    352353                // blocks here
     
    437438                if ( ret ) {
    438439                        info_thread(L) & popped = try_pop_front( blocked_threads );
     440                        popped.signalled = true;
    439441                        on_notify(*popped.lock, popped.t);
    440442                }
     
    448450                while( ! blocked_threads`isEmpty ) {
    449451                        info_thread(L) & popped = try_pop_front( blocked_threads );
     452                        popped.signalled = true;
    450453                        on_notify(*popped.lock, popped.t);
    451454                }
     
    469472                size_t recursion_count = queue_and_get_recursion(this, &info);
    470473                pthread_alarm_node_wrap(L) node_wrap = { t, 0`s, callback, &this, &info };
     474                unlock( lock );
     475
     476                // registers alarm outside cond lock to avoid deadlock
    471477                register_self( &node_wrap.alarm_node );
    472                 unlock( lock );
    473478
    474479                // blocks here
     
    500505                return i.signalled;
    501506
     507        Duration getDuration(timespec t) {
     508                timespec currTime;
     509                clock_gettime(CLOCK_REALTIME, &currTime);
     510                Duration waitUntil = { t };
     511                Duration currDur = { currTime };
     512                if ( currDur >= waitUntil ) return currDur - waitUntil;
     513                Duration zero = { 0 };
     514                return zero;
     515        }
     516
    502517        bool wait( pthread_cond_var(L) & this, L & l, timespec t ) {
    503                 Duration d = { t };
    504                 WAIT_TIME( 0, &l , d )
     518                PTHREAD_WAIT_TIME( 0, &l , getDuration( t ) )
    505519        }
    506520       
    507521        bool wait( pthread_cond_var(L) & this, L & l, uintptr_t info, timespec t  ) {
    508                 Duration d = { t };
    509                 WAIT_TIME( info, &l , d )
     522                PTHREAD_WAIT_TIME( info, &l , getDuration( t ) )
    510523        }
    511524}
  • libcfa/src/concurrency/locks.hfa

    r9e23b446 rffec1bf  
    478478        #endif
    479479        lock( lock, node );
    480         while(held) Pause();
    481         held = true;
    482         // printf("locked\n");
     480        while(__atomic_load_n(&held, __ATOMIC_SEQ_CST)) Pause();
     481        __atomic_store_n(&held, true, __ATOMIC_SEQ_CST);
    483482        unlock( lock, node );
    484483        #ifdef __CFA_DEBUG__
     
    488487
    489488static inline void unlock(spin_queue_lock & this) with(this) {
    490         // printf("unlocked\n");
    491489        #ifdef __CFA_DEBUG__
    492490        owner = 0p;
    493491        #endif
    494         held = false;
     492        __atomic_store_n(&held, false, __ATOMIC_RELEASE);
    495493}
    496494
     
    535533        #endif
    536534        lock( lock, node );
    537         while(held) Pause();
    538         held = true;
     535        while(__atomic_load_n(&held, __ATOMIC_SEQ_CST)) Pause();
     536        __atomic_store_n(&held, true, __ATOMIC_SEQ_CST);
    539537        unlock( lock, node );
    540538        #ifdef __CFA_DEBUG__
     
    547545        owner = 0p;
    548546        #endif
    549         held = false;
     547        __atomic_store_n(&held, false, __ATOMIC_SEQ_CST);
    550548}
    551549
     
    588586        #endif
    589587        lock( lock );
    590         while(held) Pause();
    591         held = true;
     588        while(__atomic_load_n(&held, __ATOMIC_SEQ_CST)) Pause();
     589        __atomic_store_n(&held, true, __ATOMIC_RELEASE);
    592590        unlock( lock );
    593591        #ifdef __CFA_DEBUG__
     
    600598        owner = 0p;
    601599        #endif
    602         held = false;
     600        __atomic_store_n(&held, false, __ATOMIC_RELEASE);
    603601}
    604602
  • libcfa/src/concurrency/ready_subqueue.hfa

    r9e23b446 rffec1bf  
    4949        // Get the relevant nodes locally
    5050        this.prev->link.next = node;
    51         this.prev->link.ts   = rdtscl();
     51        __atomic_store_n(&this.prev->link.ts, rdtscl(), __ATOMIC_RELAXED);
    5252        this.prev = node;
    5353        #if !defined(__CFA_NO_STATISTICS__)
  • libcfa/src/heap.cfa

    r9e23b446 rffec1bf  
    509509        checkHeader( header < (Heap.Storage.Header *)heapBegin || (Heap.Storage.Header *)heapEnd < header, name, addr ); // bad address ? (offset could be + or -)
    510510
    511         Heap * homeManager;
    512511        if ( unlikely( freeHead == 0p || // freed and only free-list node => null link
    513512                                   // freed and link points at another free block not to a bucket in the bucket array.
Note: See TracChangeset for help on using the changeset viewer.