Ignore:
File:
1 edited

Legend:

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

    r7cf3b1d r5b7a3662  
    205205                                // Don't block if we are done
    206206                                if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP;
     207
     208                                #if !defined(__CFA_NO_STATISTICS__)
     209                                        __tls_stats()->ready.sleep.halts++;
     210                                #endif
    207211
    208212                                // Push self to idle stack
     
    728732// Wake a thread from the front if there are any
    729733static void __wake_one(cluster * this) {
     734        /* paranoid */ verify( ! __preemption_enabled() );
     735        /* paranoid */ verify( ready_schedule_islocked() );
     736
     737        // Check if there is a sleeping processor
     738        // int fd = __atomic_load_n(&this->procs.fd, __ATOMIC_SEQ_CST);
     739        int fd = 0;
     740        if( __atomic_load_n(&this->procs.fd, __ATOMIC_SEQ_CST) != 0 ) {
     741                fd = __atomic_exchange_n(&this->procs.fd, 0, __ATOMIC_RELAXED);
     742        }
     743
     744        // If no one is sleeping, we are done
     745        if( fd == 0 ) return;
     746
     747        // We found a processor, wake it up
    730748        eventfd_t val;
    731 
    732         /* paranoid */ verify( ! __preemption_enabled() );
    733         /* paranoid */ verify( ready_schedule_islocked() );
    734 
    735         // Check if there is a sleeping processor
    736         struct __fd_waitctx * fdp = __atomic_load_n(&this->procs.fdw, __ATOMIC_SEQ_CST);
    737 
    738         // If no one is sleeping: we are done
    739         if( fdp == 0p ) return;
    740 
    741         int fd = 1;
    742         if( __atomic_load_n(&fdp->fd, __ATOMIC_SEQ_CST) != 1 ) {
    743                 fd = __atomic_exchange_n(&fdp->fd, 1, __ATOMIC_RELAXED);
    744         }
    745 
    746         switch(fd) {
    747         case 0:
    748                 // If the processor isn't ready to sleep then the exchange will already wake it up
    749                 #if !defined(__CFA_NO_STATISTICS__)
    750                         if( kernelTLS().this_stats ) { __tls_stats()->ready.sleep.early++;
    751                         } else { __atomic_fetch_add(&this->stats->ready.sleep.early, 1, __ATOMIC_RELAXED); }
    752                 #endif
    753                 break;
    754         case 1:
    755                 // If someone else already said they will wake them: we are done
    756                 #if !defined(__CFA_NO_STATISTICS__)
    757                         if( kernelTLS().this_stats ) { __tls_stats()->ready.sleep.seen++;
    758                         } else { __atomic_fetch_add(&this->stats->ready.sleep.seen, 1, __ATOMIC_RELAXED); }
    759                 #endif
    760                 break;
    761         default:
    762                 // If the processor was ready to sleep, we need to wake it up with an actual write
    763                 val = 1;
    764                 eventfd_write( fd, val );
    765 
    766                 #if !defined(__CFA_NO_STATISTICS__)
    767                         if( kernelTLS().this_stats ) { __tls_stats()->ready.sleep.wakes++;
    768                         } else { __atomic_fetch_add(&this->stats->ready.sleep.wakes, 1, __ATOMIC_RELAXED); }
    769                 #endif
    770                 break;
    771         }
     749        val = 1;
     750        eventfd_write( fd, val );
     751
     752        #if !defined(__CFA_NO_STATISTICS__)
     753                if( kernelTLS().this_stats ) {
     754                        __tls_stats()->ready.sleep.wakes++;
     755                }
     756                else {
     757                        __atomic_fetch_add(&this->stats->ready.sleep.wakes, 1, __ATOMIC_RELAXED);
     758                }
     759        #endif
    772760
    773761        /* paranoid */ verify( ready_schedule_islocked() );
     
    782770
    783771        __cfadbg_print_safe(runtime_core, "Kernel : waking Processor %p\n", this);
    784 
    785         this->idle_wctx.fd = 1;
    786772
    787773        eventfd_t val;
     
    793779
    794780static void idle_sleep(processor * this, io_future_t & future, iovec & iov) {
    795         // Tell everyone we are ready to go do sleep
    796         for() {
    797                 int expected = this->idle_wctx.fd;
    798 
    799                 // Someone already told us to wake-up! No time for a nap.
    800                 if(expected == 1) { return; }
    801 
    802                 // Try to mark that we are going to sleep
    803                 if(__atomic_compare_exchange_n(&this->idle_wctx.fd, &expected, this->idle_fd, false,  __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ) {
    804                         // Every one agreed, taking a nap
    805                         break;
    806                 }
    807         }
    808 
    809 
    810781        #if !defined(CFA_WITH_IO_URING_IDLE)
    811782                #if !defined(__CFA_NO_STATISTICS__)
     
    854825
    855826static bool mark_idle(__cluster_proc_list & this, processor & proc) {
    856         #if !defined(__CFA_NO_STATISTICS__)
    857                 __tls_stats()->ready.sleep.halts++;
    858         #endif
    859 
    860         proc.idle_wctx.fd = 0;
    861 
    862827        /* paranoid */ verify( ! __preemption_enabled() );
    863828        if(!try_lock( this )) return false;
     
    867832                insert_first(this.idles, proc);
    868833
    869                 __atomic_store_n(&this.fdw, &proc.idle_wctx, __ATOMIC_SEQ_CST);
     834                __atomic_store_n(&this.fd, proc.idle_fd, __ATOMIC_SEQ_CST);
    870835        unlock( this );
    871836        /* paranoid */ verify( ! __preemption_enabled() );
     
    883848
    884849                {
    885                         struct __fd_waitctx * wctx = 0;
    886                         if(!this.idles`isEmpty) wctx = &this.idles`first.idle_wctx;
    887                         __atomic_store_n(&this.fdw, wctx, __ATOMIC_SEQ_CST);
     850                        int fd = 0;
     851                        if(!this.idles`isEmpty) fd = this.idles`first.idle_fd;
     852                        __atomic_store_n(&this.fd, fd, __ATOMIC_SEQ_CST);
    888853                }
    889854
Note: See TracChangeset for help on using the changeset viewer.