Changes in / [69914cbc:e2f601f]


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

Legend:

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

    r69914cbc re2f601f  
    182182                MAIN_LOOP:
    183183                for() {
    184                         #if 1
     184                        #define OLD_MAIN 1
     185                        #if OLD_MAIN
    185186                        // Check if there is pending io
    186187                        __maybe_io_drain( this );
     
    262263
    263264                        #else
    264 
     265                                #warning new kernel loop
    265266                        SEARCH: {
    266267                                /* paranoid */ verify( ! __preemption_enabled() );
    267                                 /* paranoid */ verify( kernelTLS().this_proc_id );
    268268
    269269                                // First, lock the scheduler since we are searching for a thread
     
    278278
    279279                                // Spin a little on I/O, just in case
    280                                 for(25) {
     280                                        for(5) {
    281281                                        __maybe_io_drain( this );
    282282                                        readyThread = pop_fast( this->cltr );
     
    285285
    286286                                // no luck, try stealing a few times
    287                                 for(25) {
     287                                        for(5) {
    288288                                        if( __maybe_io_drain( this ) ) {
    289289                                                readyThread = pop_fast( this->cltr );
     
    323323                                }
    324324
    325                                 __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->id, rdtscl()); )
     325                                        __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->unique_id, rdtscl()); )
    326326                                __cfadbg_print_safe(runtime_core, "Kernel : core %p waiting on eventfd %d\n", this, this->idle);
    327327
     
    331331                                // __enable_interrupts_hard();
    332332
    333                                 __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->id, rdtscl()); )
     333                                        __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->unique_id, rdtscl()); )
    334334
    335335                                // We were woken up, remove self from idle
     
    341341
    342342                RUN_THREAD:
    343                         /* paranoid */ verify( kernelTLS().this_proc_id );
    344343                        /* paranoid */ verify( ! __preemption_enabled() );
    345344                        /* paranoid */ verify( readyThread );
     
    353352                        // Are we done?
    354353                        if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP;
    355 
    356                         #if !defined(__CFA_NO_STATISTICS__)
    357                                 unsigned long long curr = rdtscl();
    358                                 if(curr > (last_tally + 500000000)) {
    359                                         __tally_stats(this->cltr->stats, __cfaabi_tls.this_stats);
    360                                         last_tally = curr;
    361                                 }
    362                         #endif
    363354
    364355                        if(this->io.pending && !this->io.dirty) {
     
    877868                unsigned tail = *ctx->cq.tail;
    878869                if(head == tail) return false;
     870                #if OLD_MAIN
    879871                ready_schedule_lock();
    880872                ret = __cfa_io_drain( proc );
    881873                ready_schedule_unlock();
     874                #else
     875                        ret = __cfa_io_drain( proc );
     876        #endif
    882877        #endif
    883878        return ret;
  • libcfa/src/concurrency/kernel.hfa

    r69914cbc re2f601f  
    147147
    148148// Aligned timestamps which are used by the relaxed ready queue
    149 struct __attribute__((aligned(128))) __timestamp_t;
    150 void  ?{}(__timestamp_t & this);
    151 void ^?{}(__timestamp_t & this);
     149struct __attribute__((aligned(128))) __timestamp_t {
     150        volatile unsigned long long tv;
     151};
     152
     153static inline void  ?{}(__timestamp_t & this) { this.tv = 0; }
     154static inline void ^?{}(__timestamp_t & this) {}
    152155
    153156//TODO adjust cache size to ARCHITECTURE
     
    172175void  ?{}(__ready_queue_t & this);
    173176void ^?{}(__ready_queue_t & this);
     177#if !defined(__CFA_NO_STATISTICS__)
     178        unsigned cnt(const __ready_queue_t & this, unsigned idx);
     179#endif
    174180
    175181// Idle Sleep
  • libcfa/src/concurrency/kernel/startup.cfa

    r69914cbc re2f601f  
    496496        this.rdq.id  = -1u;
    497497        this.rdq.target = -1u;
    498         this.rdq.cutoff = -1ull;
     498        this.rdq.cutoff = 0ull;
    499499        do_terminate = false;
    500500        preemption_alarm = 0p;
  • libcfa/src/concurrency/ready_queue.cfa

    r69914cbc re2f601f  
    398398
    399399                if(proc->rdq.target == -1u) {
    400                         _Static_assert(READYQ_SHARD_FACTOR == 2);
    401                         unsigned idx1 = proc->rdq.id + 0;
    402                         unsigned idx2 = proc->rdq.id + 1;
    403                         unsigned long long tsc1 = ts(lanes.data[idx1]);
    404                         unsigned long long tsc2 = ts(lanes.data[idx2]);
     400                        unsigned long long min = ts(lanes.data[proc->rdq.id]);
     401                        for(int i = 0; i < READYQ_SHARD_FACTOR; i++) {
     402                                unsigned long long tsc = ts(lanes.data[proc->rdq.id + i]);
     403                                if(tsc < min) min = tsc;
     404                        }
     405                        proc->rdq.cutoff = min;
    405406                        proc->rdq.target = __tls_rand() % lanes.count;
    406 
    407                         // WARNING: std::min is polymorphic and therefore causes 500% slowdown instead of the expected 2%
    408                         proc->rdq.cutoff = tsc1 < tsc2 ? tsc1 : tsc2;
    409407                }
    410408                else {
     
    704702        /* paranoid */ verify( ready_mutate_islocked() );
    705703}
     704
     705#if !defined(__CFA_NO_STATISTICS__)
     706        unsigned cnt(const __ready_queue_t & this, unsigned idx) {
     707                /* paranoid */ verify(this.lanes.count > idx);
     708                return this.lanes.data[idx].cnt;
     709        }
     710#endif
  • libcfa/src/concurrency/ready_subqueue.hfa

    r69914cbc re2f601f  
    1111        // spin lock protecting the queue
    1212        volatile bool lock;
     13
     14        #if !defined(__CFA_NO_STATISTICS__)
     15                unsigned cnt;
     16        #endif
    1317
    1418        __thread_desc_link anchor;
     
    2933        this.anchor.next = 0p;
    3034        this.anchor.ts   = 0;
     35        #if !defined(__CFA_NO_STATISTICS__)
     36                this.cnt  = 0;
     37        #endif
    3138
    3239        // We add a boat-load of assertions here because the anchor code is very fragile
     40        /* paranoid */ _Static_assert( offsetof( $thread, link ) == offsetof(__intrusive_lane_t, anchor) );
    3341        /* paranoid */ verify( offsetof( $thread, link ) == offsetof(__intrusive_lane_t, anchor) );
    3442        /* paranoid */ verify( ((uintptr_t)( mock_head(this) ) + offsetof( $thread, link )) == (uintptr_t)(&this.anchor) );
     
    5462// returns true of lane was empty before push, false otherwise
    5563static inline void push( __intrusive_lane_t & this, $thread * node ) {
     64        /* paranoid */ verify( this.lock );
    5665        /* paranoid */ verify( node->link.next == 0p );
    5766        /* paranoid */ verify( node->link.ts   == 0  );
     
    7281        this.prev->link.ts   = rdtscl();
    7382        this.prev = node;
     83        #if !defined(__CFA_NO_STATISTICS__)
     84                this.cnt++;
     85        #endif
    7486}
    7587
     
    7890// returns true of lane was empty before push, false otherwise
    7991static inline [* $thread, unsigned long long] pop( __intrusive_lane_t & this ) {
     92        /* paranoid */ verify( this.lock );
    8093        /* paranoid */ verify( this.anchor.next != 0p );
    8194        /* paranoid */ verify( this.anchor.ts   != 0  );
     
    89102        node->link.next = 0p;
    90103        node->link.ts   = 0;
     104        #if !defined(__CFA_NO_STATISTICS__)
     105                this.cnt--;
     106        #endif
    91107
    92108        // Update head time stamp
     
    108124        return this.anchor.ts;
    109125}
    110 
    111 // Aligned timestamps which are used by the relaxed ready queue
    112 struct __attribute__((aligned(128))) __timestamp_t {
    113         volatile unsigned long long tv;
    114 };
    115 
    116 void  ?{}(__timestamp_t & this) { this.tv = 0; }
    117 void ^?{}(__timestamp_t & this) {}
Note: See TracChangeset for help on using the changeset viewer.