Changes in / [e2f601f:69914cbc]


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

Legend:

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

    re2f601f r69914cbc  
    182182                MAIN_LOOP:
    183183                for() {
    184                         #define OLD_MAIN 1
    185                         #if OLD_MAIN
     184                        #if 1
    186185                        // Check if there is pending io
    187186                        __maybe_io_drain( this );
     
    263262
    264263                        #else
    265                                 #warning new kernel loop
     264
    266265                        SEARCH: {
    267266                                /* 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(5) {
     280                                for(25) {
    281281                                        __maybe_io_drain( this );
    282282                                        readyThread = pop_fast( this->cltr );
     
    285285
    286286                                // no luck, try stealing a few times
    287                                         for(5) {
     287                                for(25) {
    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->unique_id, rdtscl()); )
     325                                __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->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->unique_id, rdtscl()); )
     333                                __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->id, rdtscl()); )
    334334
    335335                                // We were woken up, remove self from idle
     
    341341
    342342                RUN_THREAD:
     343                        /* paranoid */ verify( kernelTLS().this_proc_id );
    343344                        /* paranoid */ verify( ! __preemption_enabled() );
    344345                        /* paranoid */ verify( readyThread );
     
    352353                        // Are we done?
    353354                        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
    354363
    355364                        if(this->io.pending && !this->io.dirty) {
     
    868877                unsigned tail = *ctx->cq.tail;
    869878                if(head == tail) return false;
    870                 #if OLD_MAIN
    871879                ready_schedule_lock();
    872880                ret = __cfa_io_drain( proc );
    873881                ready_schedule_unlock();
    874                 #else
    875                         ret = __cfa_io_drain( proc );
    876         #endif
    877882        #endif
    878883        return ret;
  • libcfa/src/concurrency/kernel.hfa

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

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

    re2f601f r69914cbc  
    398398
    399399                if(proc->rdq.target == -1u) {
    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;
     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]);
    406405                        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;
    407409                }
    408410                else {
     
    702704        /* paranoid */ verify( ready_mutate_islocked() );
    703705}
    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

    re2f601f r69914cbc  
    1111        // spin lock protecting the queue
    1212        volatile bool lock;
    13 
    14         #if !defined(__CFA_NO_STATISTICS__)
    15                 unsigned cnt;
    16         #endif
    1713
    1814        __thread_desc_link anchor;
     
    3329        this.anchor.next = 0p;
    3430        this.anchor.ts   = 0;
    35         #if !defined(__CFA_NO_STATISTICS__)
    36                 this.cnt  = 0;
    37         #endif
    3831
    3932        // 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) );
    4133        /* paranoid */ verify( offsetof( $thread, link ) == offsetof(__intrusive_lane_t, anchor) );
    4234        /* paranoid */ verify( ((uintptr_t)( mock_head(this) ) + offsetof( $thread, link )) == (uintptr_t)(&this.anchor) );
     
    6254// returns true of lane was empty before push, false otherwise
    6355static inline void push( __intrusive_lane_t & this, $thread * node ) {
    64         /* paranoid */ verify( this.lock );
    6556        /* paranoid */ verify( node->link.next == 0p );
    6657        /* paranoid */ verify( node->link.ts   == 0  );
     
    8172        this.prev->link.ts   = rdtscl();
    8273        this.prev = node;
    83         #if !defined(__CFA_NO_STATISTICS__)
    84                 this.cnt++;
    85         #endif
    8674}
    8775
     
    9078// returns true of lane was empty before push, false otherwise
    9179static inline [* $thread, unsigned long long] pop( __intrusive_lane_t & this ) {
    92         /* paranoid */ verify( this.lock );
    9380        /* paranoid */ verify( this.anchor.next != 0p );
    9481        /* paranoid */ verify( this.anchor.ts   != 0  );
     
    10289        node->link.next = 0p;
    10390        node->link.ts   = 0;
    104         #if !defined(__CFA_NO_STATISTICS__)
    105                 this.cnt--;
    106         #endif
    10791
    10892        // Update head time stamp
     
    124108        return this.anchor.ts;
    125109}
     110
     111// Aligned timestamps which are used by the relaxed ready queue
     112struct __attribute__((aligned(128))) __timestamp_t {
     113        volatile unsigned long long tv;
     114};
     115
     116void  ?{}(__timestamp_t & this) { this.tv = 0; }
     117void ^?{}(__timestamp_t & this) {}
Note: See TracChangeset for help on using the changeset viewer.