Ignore:
File:
1 edited

Legend:

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

    r5f5a729 r34b8cb7  
    124124static void __wake_one(cluster * cltr);
    125125
    126 static bool mark_idle (__cluster_proc_list & idles, processor & proc);
     126static void mark_idle (__cluster_proc_list & idles, processor & proc);
    127127static void mark_awake(__cluster_proc_list & idles, processor & proc);
    128 static [unsigned idle, unsigned total, * processor] query_idles( & __cluster_proc_list idles );
    129128
    130129extern void __cfa_io_start( processor * );
     
    213212
    214213                                // Push self to idle stack
    215                                 if(!mark_idle(this->cltr->procs, * this)) continue MAIN_LOOP;
     214                                mark_idle(this->cltr->procs, * this);
    216215
    217216                                // Confirm the ready-queue is empty
     
    331330                                // Push self to idle stack
    332331                                ready_schedule_unlock();
    333                                 if(!mark_idle(this->cltr->procs, * this)) goto SEARCH;
     332                                mark_idle(this->cltr->procs, * this);
    334333                                ready_schedule_lock();
    335334
     
    766765
    767766        // Check if there is a sleeping processor
    768         processor * p;
    769         unsigned idle;
    770         unsigned total;
    771         [idle, total, p] = query_idles(this->procs);
     767        int fd = __atomic_load_n(&this->procs.fd, __ATOMIC_SEQ_CST);
    772768
    773769        // If no one is sleeping, we are done
    774         if( idle == 0 ) return;
     770        if( fd == 0 ) return;
    775771
    776772        // We found a processor, wake it up
    777773        eventfd_t val;
    778774        val = 1;
    779         eventfd_write( p->idle, val );
     775        eventfd_write( fd, val );
    780776
    781777        #if !defined(__CFA_NO_STATISTICS__)
     
    806802}
    807803
    808 static bool mark_idle(__cluster_proc_list & this, processor & proc) {
    809         /* paranoid */ verify( ! __preemption_enabled() );
    810         if(!try_lock( this )) return false;
     804static void mark_idle(__cluster_proc_list & this, processor & proc) {
     805        /* paranoid */ verify( ! __preemption_enabled() );
     806        lock( this );
    811807                this.idle++;
    812808                /* paranoid */ verify( this.idle <= this.total );
    813809                remove(proc);
    814810                insert_first(this.idles, proc);
     811
     812                __atomic_store_n(&this.fd, proc.idle, __ATOMIC_SEQ_CST);
    815813        unlock( this );
    816814        /* paranoid */ verify( ! __preemption_enabled() );
    817 
    818         return true;
    819815}
    820816
     
    826822                remove(proc);
    827823                insert_last(this.actives, proc);
     824
     825                __atomic_store_n(&this.fd, this.idles`first.idle, __ATOMIC_SEQ_CST);
    828826        unlock( this );
    829         /* paranoid */ verify( ! __preemption_enabled() );
    830 }
    831 
    832 static [unsigned idle, unsigned total, * processor] query_idles( & __cluster_proc_list this ) {
    833         /* paranoid */ verify( ! __preemption_enabled() );
    834         /* paranoid */ verify( ready_schedule_islocked() );
    835 
    836         for() {
    837                 uint64_t l = __atomic_load_n(&this.lock, __ATOMIC_SEQ_CST);
    838                 if( 1 == (l % 2) ) { Pause(); continue; }
    839                 unsigned idle    = this.idle;
    840                 unsigned total   = this.total;
    841                 processor * proc = &this.idles`first;
    842                 // Compiler fence is unnecessary, but gcc-8 and older incorrectly reorder code without it
    843                 asm volatile("": : :"memory");
    844                 if(l != __atomic_load_n(&this.lock, __ATOMIC_SEQ_CST)) { Pause(); continue; }
    845                 return [idle, total, proc];
    846         }
    847 
    848         /* paranoid */ verify( ready_schedule_islocked() );
    849827        /* paranoid */ verify( ! __preemption_enabled() );
    850828}
     
    908886                if(head == tail) return false;
    909887                #if OLD_MAIN
    910                 ready_schedule_lock();
    911                 ret = __cfa_io_drain( proc );
    912                 ready_schedule_unlock();
     888                        ready_schedule_lock();
     889                        ret = __cfa_io_drain( proc );
     890                        ready_schedule_unlock();
    913891                #else
    914892                        ret = __cfa_io_drain( proc );
    915         #endif
     893                #endif
    916894        #endif
    917895        return ret;
Note: See TracChangeset for help on using the changeset viewer.