Ignore:
File:
1 edited

Legend:

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

    rb808625 rb7fd2db6  
    163163        #if !defined(__CFA_NO_STATISTICS__)
    164164                if( this->print_halts ) {
    165                         __cfaabi_bits_print_safe( STDOUT_FILENO, "Processor : %d - %s (%p)\n", this->unique_id, this->name, (void*)this);
     165                        __cfaabi_bits_print_safe( STDOUT_FILENO, "Processor : %d - %s (%p)\n", this->id, this->name, (void*)this);
    166166                }
    167167        #endif
     
    170170                // Setup preemption data
    171171                preemption_scope scope = { this };
     172
     173                __STATS( unsigned long long last_tally = rdtscl(); )
    172174
    173175                // if we need to run some special setup, now is the time to do it.
     
    182184                MAIN_LOOP:
    183185                for() {
    184                         #define OLD_MAIN 1
    185                         #if OLD_MAIN
    186186                        // Check if there is pending io
    187187                        __maybe_io_drain( this );
     
    223223                                #if !defined(__CFA_NO_STATISTICS__)
    224224                                        if(this->print_halts) {
    225                                                 __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->unique_id, rdtscl());
     225                                                __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->id, rdtscl());
    226226                                        }
    227227                                #endif
     
    236236                                #if !defined(__CFA_NO_STATISTICS__)
    237237                                        if(this->print_halts) {
    238                                                 __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->unique_id, rdtscl());
     238                                                __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->id, rdtscl());
    239239                                        }
    240240                                #endif
     
    258258                        if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP;
    259259
     260                        #if !defined(__CFA_NO_STATISTICS__)
     261                                unsigned long long curr = rdtscl();
     262                                if(curr > (last_tally + 500000000)) {
     263                                        __tally_stats(this->cltr->stats, __cfaabi_tls.this_stats);
     264                                        last_tally = curr;
     265                                }
     266                        #endif
     267
    260268                        if(this->io.pending && !this->io.dirty) {
    261269                                __cfa_io_flush( this );
    262270                        }
    263271
    264                         #else
    265                                 #warning new kernel loop
    266                         SEARCH: {
    267                                 /* paranoid */ verify( ! __preemption_enabled() );
    268 
    269                                 // First, lock the scheduler since we are searching for a thread
    270                                 ready_schedule_lock();
    271 
    272                                 // Try to get the next thread
    273                                 readyThread = pop_fast( this->cltr );
    274                                 if(readyThread) { ready_schedule_unlock(); break SEARCH; }
    275 
    276                                 // If we can't find a thread, might as well flush any outstanding I/O
    277                                 if(this->io.pending) { __cfa_io_flush( this ); }
    278 
    279                                 // Spin a little on I/O, just in case
    280                                         for(5) {
    281                                         __maybe_io_drain( this );
    282                                         readyThread = pop_fast( this->cltr );
    283                                         if(readyThread) { ready_schedule_unlock(); break SEARCH; }
    284                                 }
    285 
    286                                 // no luck, try stealing a few times
    287                                         for(5) {
    288                                         if( __maybe_io_drain( this ) ) {
    289                                                 readyThread = pop_fast( this->cltr );
    290                                         } else {
    291                                                 readyThread = pop_slow( this->cltr );
    292                                         }
    293                                         if(readyThread) { ready_schedule_unlock(); break SEARCH; }
    294                                 }
    295 
    296                                 // still no luck, search for a thread
    297                                 readyThread = pop_search( this->cltr );
    298                                 if(readyThread) { ready_schedule_unlock(); break SEARCH; }
    299 
    300                                 // Don't block if we are done
    301                                 if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP;
    302 
    303                                 __STATS( __tls_stats()->ready.sleep.halts++; )
    304 
    305                                 // Push self to idle stack
    306                                 ready_schedule_unlock();
    307                                 mark_idle(this->cltr->procs, * this);
    308                                 ready_schedule_lock();
    309 
    310                                 // Confirm the ready-queue is empty
    311                                 __maybe_io_drain( this );
    312                                 readyThread = pop_search( this->cltr );
    313                                 ready_schedule_unlock();
    314 
    315                                 if( readyThread ) {
    316                                         // A thread was found, cancel the halt
    317                                         mark_awake(this->cltr->procs, * this);
    318 
    319                                         __STATS( __tls_stats()->ready.sleep.cancels++; )
    320 
    321                                         // continue the main loop
    322                                         break SEARCH;
    323                                 }
    324 
    325                                         __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->unique_id, rdtscl()); )
    326                                 __cfadbg_print_safe(runtime_core, "Kernel : core %p waiting on eventfd %d\n", this, this->idle);
    327 
    328                                 // __disable_interrupts_hard();
    329                                 eventfd_t val;
    330                                 eventfd_read( this->idle, &val );
    331                                 // __enable_interrupts_hard();
    332 
    333                                         __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->unique_id, rdtscl()); )
    334 
    335                                 // We were woken up, remove self from idle
    336                                 mark_awake(this->cltr->procs, * this);
    337 
    338                                 // DON'T just proceed, start looking again
    339                                 continue MAIN_LOOP;
    340                         }
    341 
    342                 RUN_THREAD:
    343                         /* paranoid */ verify( ! __preemption_enabled() );
    344                         /* paranoid */ verify( readyThread );
    345 
    346                         // Reset io dirty bit
    347                         this->io.dirty = false;
    348 
    349                         // We found a thread run it
    350                         __run_thread(this, readyThread);
    351 
    352                         // Are we done?
    353                         if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP;
    354 
    355                         if(this->io.pending && !this->io.dirty) {
    356                                 __cfa_io_flush( this );
    357                         }
    358 
    359                         ready_schedule_lock();
    360                         __maybe_io_drain( this );
    361                         ready_schedule_unlock();
    362                         #endif
     272                //      SEARCH: {
     273                //              /* paranoid */ verify( ! __preemption_enabled() );
     274                //              /* paranoid */ verify( kernelTLS().this_proc_id );
     275
     276                //              // First, lock the scheduler since we are searching for a thread
     277
     278                //              // Try to get the next thread
     279                //              ready_schedule_lock();
     280                //              readyThread = pop_fast( this->cltr );
     281                //              ready_schedule_unlock();
     282                //              if(readyThread) {  break SEARCH; }
     283
     284                //              // If we can't find a thread, might as well flush any outstanding I/O
     285                //              if(this->io.pending) { __cfa_io_flush( this ); }
     286
     287                //              // Spin a little on I/O, just in case
     288                //              for(25) {
     289                //                      __maybe_io_drain( this );
     290                //                      ready_schedule_lock();
     291                //                      readyThread = pop_fast( this->cltr );
     292                //                      ready_schedule_unlock();
     293                //                      if(readyThread) {  break SEARCH; }
     294                //              }
     295
     296                //              // no luck, try stealing a few times
     297                //              for(25) {
     298                //                      if( __maybe_io_drain( this ) ) {
     299                //                              ready_schedule_lock();
     300                //                              readyThread = pop_fast( this->cltr );
     301                //                      } else {
     302                //                              ready_schedule_lock();
     303                //                              readyThread = pop_slow( this->cltr );
     304                //                      }
     305                //                      ready_schedule_unlock();
     306                //                      if(readyThread) {  break SEARCH; }
     307                //              }
     308
     309                //              // still no luck, search for a thread
     310                //              ready_schedule_lock();
     311                //              readyThread = pop_search( this->cltr );
     312                //              ready_schedule_unlock();
     313                //              if(readyThread) { break SEARCH; }
     314
     315                //              // Don't block if we are done
     316                //              if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP;
     317
     318                //              __STATS( __tls_stats()->ready.sleep.halts++; )
     319
     320                //              // Push self to idle stack
     321                //              mark_idle(this->cltr->procs, * this);
     322
     323                //              // Confirm the ready-queue is empty
     324                //              __maybe_io_drain( this );
     325                //              ready_schedule_lock();
     326                //              readyThread = pop_search( this->cltr );
     327                //              ready_schedule_unlock();
     328
     329                //              if( readyThread ) {
     330                //                      // A thread was found, cancel the halt
     331                //                      mark_awake(this->cltr->procs, * this);
     332
     333                //                      __STATS( __tls_stats()->ready.sleep.cancels++; )
     334
     335                //                      // continue the main loop
     336                //                      break SEARCH;
     337                //              }
     338
     339                //              __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->id, rdtscl()); )
     340                //              __cfadbg_print_safe(runtime_core, "Kernel : core %p waiting on eventfd %d\n", this, this->idle);
     341
     342                //              // __disable_interrupts_hard();
     343                //              eventfd_t val;
     344                //              eventfd_read( this->idle, &val );
     345                //              // __enable_interrupts_hard();
     346
     347                //              __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->id, rdtscl()); )
     348
     349                //              // We were woken up, remove self from idle
     350                //              mark_awake(this->cltr->procs, * this);
     351
     352                //              // DON'T just proceed, start looking again
     353                //              continue MAIN_LOOP;
     354                //      }
     355
     356                // RUN_THREAD:
     357                //      /* paranoid */ verify( kernelTLS().this_proc_id );
     358                //      /* paranoid */ verify( ! __preemption_enabled() );
     359                //      /* paranoid */ verify( readyThread );
     360
     361                //      // Reset io dirty bit
     362                //      this->io.dirty = false;
     363
     364                //      // We found a thread run it
     365                //      __run_thread(this, readyThread);
     366
     367                //      // Are we done?
     368                //      if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP;
     369
     370                //      #if !defined(__CFA_NO_STATISTICS__)
     371                //              unsigned long long curr = rdtscl();
     372                //              if(curr > (last_tally + 500000000)) {
     373                //                      __tally_stats(this->cltr->stats, __cfaabi_tls.this_stats);
     374                //                      last_tally = curr;
     375                //              }
     376                //      #endif
     377
     378                //      if(this->io.pending && !this->io.dirty) {
     379                //              __cfa_io_flush( this );
     380                //      }
     381
     382                //      // Check if there is pending io
     383                //      __maybe_io_drain( this );
    363384                }
    364385
     
    369390
    370391        post( this->terminated );
     392
    371393
    372394        if(this == mainProcessor) {
     
    531553static void __schedule_thread( $thread * thrd ) {
    532554        /* paranoid */ verify( ! __preemption_enabled() );
     555        /* paranoid */ verify( kernelTLS().this_proc_id );
    533556        /* paranoid */ verify( ready_schedule_islocked());
    534557        /* paranoid */ verify( thrd );
     
    544567        /* paranoid */ verify( 0x0D15EA5E0D15EA5Ep == thrd->canary );
    545568
    546         const bool local = thrd->state != Start;
     569
    547570        if (thrd->preempted == __NO_PREEMPTION) thrd->state = Ready;
    548571
     
    552575
    553576        // push the thread to the cluster ready-queue
    554         push( cl, thrd, local );
     577        push( cl, thrd );
    555578
    556579        // variable thrd is no longer safe to use
     
    588611static inline $thread * __next_thread(cluster * this) with( *this ) {
    589612        /* paranoid */ verify( ! __preemption_enabled() );
     613        /* paranoid */ verify( kernelTLS().this_proc_id );
    590614
    591615        ready_schedule_lock();
     
    593617        ready_schedule_unlock();
    594618
     619        /* paranoid */ verify( kernelTLS().this_proc_id );
    595620        /* paranoid */ verify( ! __preemption_enabled() );
    596621        return thrd;
     
    600625static inline $thread * __next_thread_slow(cluster * this) with( *this ) {
    601626        /* paranoid */ verify( ! __preemption_enabled() );
     627        /* paranoid */ verify( kernelTLS().this_proc_id );
    602628
    603629        ready_schedule_lock();
     
    612638        ready_schedule_unlock();
    613639
     640        /* paranoid */ verify( kernelTLS().this_proc_id );
    614641        /* paranoid */ verify( ! __preemption_enabled() );
    615642        return thrd;
     
    868895                unsigned tail = *ctx->cq.tail;
    869896                if(head == tail) return false;
    870                 #if OLD_MAIN
    871897                ready_schedule_lock();
    872898                ret = __cfa_io_drain( proc );
    873899                ready_schedule_unlock();
    874                 #else
    875                         ret = __cfa_io_drain( proc );
    876         #endif
    877900        #endif
    878901        return ret;
     
    903926        }
    904927
    905         static void crawl_list( cluster * cltr, dlist(processor) & list, unsigned count ) {
    906                 /* paranoid */ verify( cltr->stats );
    907 
    908                 processor * it = &list`first;
    909                 for(unsigned i = 0; i < count; i++) {
    910                         /* paranoid */ verifyf( it, "Unexpected null iterator, at index %u of %u\n", i, count);
    911                         /* paranoid */ verify( it->local_data->this_stats );
    912                         __tally_stats( cltr->stats, it->local_data->this_stats );
    913                         it = &(*it)`next;
    914                 }
    915         }
    916 
    917         void crawl_cluster_stats( cluster & this ) {
    918                 // Stop the world, otherwise stats could get really messed-up
    919                 // this doesn't solve all problems but does solve many
    920                 // so it's probably good enough
    921                 uint_fast32_t last_size = ready_mutate_lock();
    922 
    923                         crawl_list(&this, this.procs.actives, this.procs.total - this.procs.idle);
    924                         crawl_list(&this, this.procs.idles  , this.procs.idle );
    925 
    926                 // Unlock the RWlock
    927                 ready_mutate_unlock( last_size );
    928         }
    929 
    930 
    931928        void print_stats_now( cluster & this, int flags ) {
    932                 crawl_cluster_stats( this );
    933929                __print_stats( this.stats, this.print_stats, "Cluster", this.name, (void*)&this );
    934930        }
Note: See TracChangeset for help on using the changeset viewer.