Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/ready_queue.cfa

    rd2fadeb r5f6a172  
    3535static const size_t cache_line_size = 64;
    3636
    37 #if !defined(__CFA_NO_STATISTICS__)
    38         #define __STATS(...) __VA_ARGS__
    39 #else
    40         #define __STATS(...)
    41 #endif
    42 
    4337// No overriden function, no environment variable, no define
    4438// fall back to a magic number
     
    5852#endif
    5953
    60 static inline struct $thread * try_pop(struct cluster * cltr, unsigned w __STATS(, __stats_readyQ_pop_t & stats));
    61 static inline struct $thread * try_pop(struct cluster * cltr, unsigned i, unsigned j __STATS(, __stats_readyQ_pop_t & stats));
     54static inline [unsigned, bool] idx_from_r(unsigned r, unsigned preferred);
     55static inline struct $thread * try_pop(struct cluster * cltr, unsigned w);
     56static inline struct $thread * try_pop(struct cluster * cltr, unsigned i, unsigned j);
    6257static inline struct $thread * search(struct cluster * cltr);
    63 static inline [unsigned, bool] idx_from_r(unsigned r, unsigned preferred);
    6458
    6559
     
    275269
    276270                        #if !defined(__CFA_NO_STATISTICS__)
    277                                 if(unlikely(external)) __atomic_fetch_add(&cltr->stats->ready.push.extrn.attempt, 1, __ATOMIC_RELAXED);
    278                                 else if(local) __tls_stats()->ready.push.local.attempt++;
    279                                 else __tls_stats()->ready.push.share.attempt++;
     271                                if(external) {
     272                                        if(local) __atomic_fetch_add(&cltr->stats->ready.pick.ext.local, 1, __ATOMIC_RELAXED);
     273                                        __atomic_fetch_add(&cltr->stats->ready.pick.ext.attempt, 1, __ATOMIC_RELAXED);
     274                                }
     275                                else {
     276                                        if(local) __tls_stats()->ready.pick.push.local++;
     277                                        __tls_stats()->ready.pick.push.attempt++;
     278                                }
    280279                        #endif
    281280
     
    303302                // Update statistics
    304303                #if !defined(__CFA_NO_STATISTICS__)
    305                         if(unlikely(external)) __atomic_fetch_add(&cltr->stats->ready.push.extrn.success, 1, __ATOMIC_RELAXED);
    306                         else if(local) __tls_stats()->ready.push.local.success++;
    307                         else __tls_stats()->ready.push.share.success++;
     304                        if(external) {
     305                                if(local) __atomic_fetch_add(&cltr->stats->ready.pick.ext.lsuccess, 1, __ATOMIC_RELAXED);
     306                                __atomic_fetch_add(&cltr->stats->ready.pick.ext.success, 1, __ATOMIC_RELAXED);
     307                        }
     308                        else {
     309                                if(local) __tls_stats()->ready.pick.push.lsuccess++;
     310                                __tls_stats()->ready.pick.push.success++;
     311                        }
    308312                #endif
    309313        }
     
    330334                        [j, localj] = idx_from_r(rj, preferred);
    331335
     336                        #if !defined(__CFA_NO_STATISTICS__)
     337                                if(locali && localj) {
     338                                        __tls_stats()->ready.pick.pop.local++;
     339                                }
     340                        #endif
     341
    332342                        i %= count;
    333343                        j %= count;
    334344
    335345                        // try popping from the 2 picked lists
    336                         struct $thread * thrd = try_pop(cltr, i, j __STATS(, *(locali || localj ? &__tls_stats()->ready.pop.local : &__tls_stats()->ready.pop.help)));
     346                        struct $thread * thrd = try_pop(cltr, i, j);
    337347                        if(thrd) {
     348                                #if !defined(__CFA_NO_STATISTICS__)
     349                                        if( locali || localj ) __tls_stats()->ready.pick.pop.lsuccess++;
     350                                #endif
    338351                                return thrd;
    339352                        }
     
    361374                unsigned i;
    362375                do {
    363                         #if !defined(__CFA_NO_STATISTICS__)
    364                                 if(unlikely(external)) __atomic_fetch_add(&cltr->stats->ready.push.extrn.attempt, 1, __ATOMIC_RELAXED);
    365                                 else __tls_stats()->ready.push.local.attempt++;
    366                         #endif
    367 
    368376                        if(unlikely(external)) {
    369377                                i = __tls_rand() % lanes.count;
     
    390398                        // Unlock and return
    391399                        __atomic_unlock( &lanes.data[i].lock );
    392                 #endif
    393 
    394                 #if !defined(__CFA_NO_STATISTICS__)
    395                         if(unlikely(external)) __atomic_fetch_add(&cltr->stats->ready.push.extrn.success, 1, __ATOMIC_RELAXED);
    396                         else __tls_stats()->ready.push.local.success++;
    397400                #endif
    398401
     
    419422                }
    420423                else if(lanes.tscs[proc->rdq.target].tv < proc->rdq.cutoff) {
    421                         $thread * t = try_pop(cltr, proc->rdq.target __STATS(, __tls_stats()->ready.pop.help));
     424                        $thread * t = try_pop(cltr, proc->rdq.target);
    422425                        proc->rdq.target = -1u;
    423426                        if(t) return t;
     
    426429                for(READYQ_SHARD_FACTOR) {
    427430                        unsigned i = proc->rdq.id + (--proc->rdq.itr % READYQ_SHARD_FACTOR);
    428                         if($thread * t = try_pop(cltr, i __STATS(, __tls_stats()->ready.pop.local))) return t;
     431                        if($thread * t = try_pop(cltr, i)) return t;
    429432                }
    430433                return 0p;
     
    434437                for(25) {
    435438                        unsigned i = __tls_rand() % lanes.count;
    436                         $thread * t = try_pop(cltr, i __STATS(, __tls_stats()->ready.pop.steal));
     439                        $thread * t = try_pop(cltr, i);
    437440                        if(t) return t;
    438441                }
     
    450453//-----------------------------------------------------------------------
    451454// try to pop from a lane given by index w
    452 static inline struct $thread * try_pop(struct cluster * cltr, unsigned w __STATS(, __stats_readyQ_pop_t & stats)) with (cltr->ready_queue) {
    453         __STATS( stats.attempt++; )
    454 
     455static inline struct $thread * try_pop(struct cluster * cltr, unsigned w) with (cltr->ready_queue) {
    455456        // Get relevant elements locally
    456457        __intrusive_lane_t & lane = lanes.data[w];
    457458
    458459        // If list looks empty retry
    459         if( is_empty(lane) ) {
    460                 __STATS( stats.espec++; )
    461                 return 0p;
    462         }
     460        if( is_empty(lane) ) return 0p;
    463461
    464462        // If we can't get the lock retry
    465         if( !__atomic_try_acquire(&lane.lock) ) {
    466                 __STATS( stats.elock++; )
    467                 return 0p;
    468         }
     463        if( !__atomic_try_acquire(&lane.lock) ) return 0p;
    469464
    470465        // If list is empty, unlock and retry
    471466        if( is_empty(lane) ) {
    472467                __atomic_unlock(&lane.lock);
    473                 __STATS( stats.eempty++; )
    474468                return 0p;
    475469        }
     
    486480
    487481        // Update statistics
    488         __STATS( stats.success++; )
     482        #if !defined(__CFA_NO_STATISTICS__)
     483                __tls_stats()->ready.pick.pop.success++;
     484        #endif
    489485
    490486        #if defined(USE_WORK_STEALING)
     
    505501        for(i; count) {
    506502                unsigned idx = (offset + i) % count;
    507                 struct $thread * thrd = try_pop(cltr, idx __STATS(, __tls_stats()->ready.pop.search));
     503                struct $thread * thrd = try_pop(cltr, idx);
    508504                if(thrd) {
    509505                        return thrd;
     
    543539//-----------------------------------------------------------------------
    544540// Given 2 indexes, pick the list with the oldest push an try to pop from it
    545 static inline struct $thread * try_pop(struct cluster * cltr, unsigned i, unsigned j __STATS(, __stats_readyQ_pop_t & stats)) with (cltr->ready_queue) {
     541static inline struct $thread * try_pop(struct cluster * cltr, unsigned i, unsigned j) with (cltr->ready_queue) {
     542        #if !defined(__CFA_NO_STATISTICS__)
     543                __tls_stats()->ready.pick.pop.attempt++;
     544        #endif
     545
    546546        // Pick the bet list
    547547        int w = i;
     
    550550        }
    551551
    552         return try_pop(cltr, w __STATS(, stats));
     552        return try_pop(cltr, w);
    553553}
    554554
Note: See TracChangeset for help on using the changeset viewer.