Ignore:
File:
1 edited

Legend:

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

    r39fc03e r1eb239e4  
    1717// #define __CFA_DEBUG_PRINT_READY_QUEUE__
    1818
     19// #define USE_SNZI
     20
    1921#include "bits/defs.hfa"
    2022#include "kernel_private.hfa"
     
    192194void ^?{}(__ready_queue_t & this) with (this) {
    193195        verify( 1 == lanes.count );
    194         verify( !query( snzi ) );
     196        #ifdef USE_SNZI
     197                verify( !query( snzi ) );
     198        #endif
    195199        free(lanes.data);
    196200}
     
    198202//-----------------------------------------------------------------------
    199203__attribute__((hot)) bool query(struct cluster * cltr) {
    200         return query(cltr->ready_queue.snzi);
     204        #ifdef USE_SNZI
     205                return query(cltr->ready_queue.snzi);
     206        #endif
     207        return true;
    201208}
    202209
     
    262269        bool lane_first = push(lanes.data[i], thrd);
    263270
    264         // If this lane used to be empty we need to do more
    265         if(lane_first) {
    266                 // Check if the entire queue used to be empty
    267                 first = !query(snzi);
    268 
    269                 // Update the snzi
    270                 arrive( snzi, i );
    271         }
     271        #ifdef USE_SNZI
     272                // If this lane used to be empty we need to do more
     273                if(lane_first) {
     274                        // Check if the entire queue used to be empty
     275                        first = !query(snzi);
     276
     277                        // Update the snzi
     278                        arrive( snzi, i );
     279                }
     280        #endif
    272281
    273282        // Unlock and return
     
    294303__attribute__((hot)) $thread * pop(struct cluster * cltr) with (cltr->ready_queue) {
    295304        /* paranoid */ verify( lanes.count > 0 );
     305        unsigned count = __atomic_load_n( &lanes.count, __ATOMIC_RELAXED );
    296306        #if defined(BIAS)
    297307                // Don't bother trying locally too much
     
    300310
    301311        // As long as the list is not empty, try finding a lane that isn't empty and pop from it
    302         while( query(snzi) ) {
     312        #ifdef USE_SNZI
     313                while( query(snzi) ) {
     314        #else
     315                for(25) {
     316        #endif
    303317                // Pick two lists at random
    304318                unsigned i,j;
     
    336350                #endif
    337351
    338                 i %= __atomic_load_n( &lanes.count, __ATOMIC_RELAXED );
    339                 j %= __atomic_load_n( &lanes.count, __ATOMIC_RELAXED );
     352                i %= count;
     353                j %= count;
    340354
    341355                // try popping from the 2 picked lists
     
    353367}
    354368
     369__attribute__((hot)) struct $thread * pop_slow(struct cluster * cltr) with (cltr->ready_queue) {
     370        /* paranoid */ verify( lanes.count > 0 );
     371        unsigned count = __atomic_load_n( &lanes.count, __ATOMIC_RELAXED );
     372        unsigned offset = __tls_rand();
     373        for(i; count) {
     374                unsigned idx = (offset + i) % count;
     375                struct $thread * thrd = try_pop(cltr, idx);
     376                if(thrd) {
     377                        return thrd;
     378                }
     379        }
     380
     381        // All lanes where empty return 0p
     382        return 0p;
     383}
     384
     385
    355386//-----------------------------------------------------------------------
    356387// Given 2 indexes, pick the list with the oldest push an try to pop from it
     
    394425        /* paranoid */ verify(lane.lock);
    395426
    396         // If this was the last element in the lane
    397         if(emptied) {
    398                 depart( snzi, w );
    399         }
     427        #ifdef USE_SNZI
     428                // If this was the last element in the lane
     429                if(emptied) {
     430                        depart( snzi, w );
     431                }
     432        #endif
    400433
    401434        // Unlock and return
     
    430463
    431464                                removed = true;
    432                                 if(emptied) {
    433                                         depart( snzi, i );
    434                                 }
     465                                #ifdef USE_SNZI
     466                                        if(emptied) {
     467                                                depart( snzi, i );
     468                                        }
     469                                #endif
    435470                        }
    436471                __atomic_unlock(&lane.lock);
     
    494529        // grow the ready queue
    495530        with( cltr->ready_queue ) {
    496                 ^(snzi){};
     531                #ifdef USE_SNZI
     532                        ^(snzi){};
     533                #endif
    497534
    498535                // Find new count
     
    516553                lanes.count = ncount;
    517554
    518                 // Re-create the snzi
    519                 snzi{ log2( lanes.count / 8 ) };
    520                 for( idx; (size_t)lanes.count ) {
    521                         if( !is_empty(lanes.data[idx]) ) {
    522                                 arrive(snzi, idx);
    523                         }
    524                 }
     555                #ifdef USE_SNZI
     556                        // Re-create the snzi
     557                        snzi{ log2( lanes.count / 8 ) };
     558                        for( idx; (size_t)lanes.count ) {
     559                                if( !is_empty(lanes.data[idx]) ) {
     560                                        arrive(snzi, idx);
     561                                }
     562                        }
     563                #endif
    525564        }
    526565
     
    542581
    543582        with( cltr->ready_queue ) {
    544                 ^(snzi){};
     583                #ifdef USE_SNZI
     584                        ^(snzi){};
     585                #endif
    545586
    546587                // Remember old count
     
    596637                }
    597638
    598                 // Re-create the snzi
    599                 snzi{ log2( lanes.count / 8 ) };
    600                 for( idx; (size_t)lanes.count ) {
    601                         if( !is_empty(lanes.data[idx]) ) {
    602                                 arrive(snzi, idx);
    603                         }
    604                 }
     639                #ifdef USE_SNZI
     640                        // Re-create the snzi
     641                        snzi{ log2( lanes.count / 8 ) };
     642                        for( idx; (size_t)lanes.count ) {
     643                                if( !is_empty(lanes.data[idx]) ) {
     644                                        arrive(snzi, idx);
     645                                }
     646                        }
     647                #endif
    605648        }
    606649
Note: See TracChangeset for help on using the changeset viewer.