Changes in / [a0e7d3c:92b9958]


Ignore:
Location:
libcfa/src/concurrency
Files:
3 edited

Legend:

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

    ra0e7d3c r92b9958  
    145145void ^?{}(__intrusive_lane_t & this);
    146146
     147// Counter used for wether or not the lanes are all empty
     148struct __attribute__((aligned(128))) __snzi_node_t;
     149struct __snzi_t {
     150        unsigned mask;
     151        int root;
     152        __snzi_node_t * nodes;
     153};
     154
     155void  ?{}( __snzi_t & this, unsigned depth );
     156void ^?{}( __snzi_t & this );
     157
    147158//TODO adjust cache size to ARCHITECTURE
    148159// Structure holding the relaxed ready queue
    149160struct __ready_queue_t {
     161        // Data tracking how many/which lanes are used
     162        // Aligned to 128 for cache locality
     163        __snzi_t snzi;
     164
    150165        // Data tracking the actual lanes
    151166        // On a seperate cacheline from the used struct since
  • libcfa/src/concurrency/kernel_private.hfa

    ra0e7d3c r92b9958  
    284284// Ready-Queue API
    285285//-----------------------------------------------------------------------
     286// pop thread from the ready queue of a cluster
     287// returns 0p if empty
     288__attribute__((hot)) bool query(struct cluster * cltr);
     289
     290//-----------------------------------------------------------------------
    286291// push thread onto a ready queue for a cluster
    287292// returns true if the list was previously empty, false otherwise
  • libcfa/src/concurrency/ready_queue.cfa

    ra0e7d3c r92b9958  
    1717// #define __CFA_DEBUG_PRINT_READY_QUEUE__
    1818
     19// #define USE_SNZI
    1920// #define USE_MPSC
    2021
     
    2829#include <unistd.h>
    2930
     31#include "snzi.hfa"
    3032#include "ready_subqueue.hfa"
    3133
     
    200202void ^?{}(__ready_queue_t & this) with (this) {
    201203        verify( 1 == lanes.count );
     204        #ifdef USE_SNZI
     205                verify( !query( snzi ) );
     206        #endif
    202207        free(lanes.data);
    203208}
    204209
    205210//-----------------------------------------------------------------------
     211__attribute__((hot)) bool query(struct cluster * cltr) {
     212        #ifdef USE_SNZI
     213                return query(cltr->ready_queue.snzi);
     214        #endif
     215        return true;
     216}
     217
    206218static inline [unsigned, bool] idx_from_r(unsigned r, unsigned preferred) {
    207219        unsigned i;
     
    281293
    282294        // Actually push it
     295        #ifdef USE_SNZI
     296                bool lane_first =
     297        #endif
     298
    283299        push(lanes.data[i], thrd);
     300
     301        #ifdef USE_SNZI
     302                // If this lane used to be empty we need to do more
     303                if(lane_first) {
     304                        // Check if the entire queue used to be empty
     305                        first = !query(snzi);
     306
     307                        // Update the snzi
     308                        arrive( snzi, i );
     309                }
     310        #endif
    284311
    285312        #if !defined(USE_MPSC)
     
    324351
    325352        // As long as the list is not empty, try finding a lane that isn't empty and pop from it
    326         for(25) {
     353        #ifdef USE_SNZI
     354                while( query(snzi) ) {
     355        #else
     356                for(25) {
     357        #endif
    327358                // Pick two lists at random
    328359                // unsigned ri = __tls_rand();
     
    416447        /* paranoid */ verify(lane.lock);
    417448
     449        #ifdef USE_SNZI
     450                // If this was the last element in the lane
     451                if(emptied) {
     452                        depart( snzi, w );
     453                }
     454        #endif
     455
    418456        // Unlock and return
    419457        __atomic_unlock(&lane.lock);
     
    446484
    447485                                removed = true;
     486                                #ifdef USE_SNZI
     487                                        if(emptied) {
     488                                                depart( snzi, i );
     489                                        }
     490                                #endif
    448491                        }
    449492                __atomic_unlock(&lane.lock);
     
    528571        // grow the ready queue
    529572        with( cltr->ready_queue ) {
     573                #ifdef USE_SNZI
     574                        ^(snzi){};
     575                #endif
     576
    530577                // Find new count
    531578                // Make sure we always have atleast 1 list
     
    551598                // Update original
    552599                lanes.count = ncount;
     600
     601                #ifdef USE_SNZI
     602                        // Re-create the snzi
     603                        snzi{ log2( lanes.count / 8 ) };
     604                        for( idx; (size_t)lanes.count ) {
     605                                if( !is_empty(lanes.data[idx]) ) {
     606                                        arrive(snzi, idx);
     607                                }
     608                        }
     609                #endif
    553610        }
    554611
     
    574631
    575632        with( cltr->ready_queue ) {
     633                #ifdef USE_SNZI
     634                        ^(snzi){};
     635                #endif
     636
    576637                // Remember old count
    577638                size_t ocount = lanes.count;
     
    624685                        fix(lanes.data[idx]);
    625686                }
     687
     688                #ifdef USE_SNZI
     689                        // Re-create the snzi
     690                        snzi{ log2( lanes.count / 8 ) };
     691                        for( idx; (size_t)lanes.count ) {
     692                                if( !is_empty(lanes.data[idx]) ) {
     693                                        arrive(snzi, idx);
     694                                }
     695                        }
     696                #endif
    626697        }
    627698
Note: See TracChangeset for help on using the changeset viewer.