Changes in / [b14ec5f:84a6e70]


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

Legend:

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

    rb14ec5f r84a6e70  
    126126static bool mark_idle (__cluster_proc_list & idles, processor & proc);
    127127static void mark_awake(__cluster_proc_list & idles, processor & proc);
     128static [unsigned idle, unsigned total, * processor] query_idles( & __cluster_proc_list idles );
    128129
    129130extern void __cfa_io_start( processor * );
     
    765766
    766767        // Check if there is a sleeping processor
    767         int fd = __atomic_load_n(&this->procs.fd, __ATOMIC_SEQ_CST);
     768        processor * p;
     769        unsigned idle;
     770        unsigned total;
     771        [idle, total, p] = query_idles(this->procs);
    768772
    769773        // If no one is sleeping, we are done
    770         if( fd == 0 ) return;
     774        if( idle == 0 ) return;
    771775
    772776        // We found a processor, wake it up
    773777        eventfd_t val;
    774778        val = 1;
    775         eventfd_write( fd, val );
     779        eventfd_write( p->idle, val );
    776780
    777781        #if !defined(__CFA_NO_STATISTICS__)
     
    809813                remove(proc);
    810814                insert_first(this.idles, proc);
    811 
    812                 __atomic_store_n(&this.fd, proc.idle, __ATOMIC_SEQ_CST);
    813815        unlock( this );
    814816        /* paranoid */ verify( ! __preemption_enabled() );
     
    824826                remove(proc);
    825827                insert_last(this.actives, proc);
    826 
    827                 __atomic_store_n(&this.fd, this.idles`first.idle, __ATOMIC_SEQ_CST);
    828828        unlock( this );
     829        /* paranoid */ verify( ! __preemption_enabled() );
     830}
     831
     832static [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() );
    829849        /* paranoid */ verify( ! __preemption_enabled() );
    830850}
     
    888908                if(head == tail) return false;
    889909                #if OLD_MAIN
    890                         ready_schedule_lock();
    891                         ret = __cfa_io_drain( proc );
    892                         ready_schedule_unlock();
     910                ready_schedule_lock();
     911                ret = __cfa_io_drain( proc );
     912                ready_schedule_unlock();
    893913                #else
    894914                        ret = __cfa_io_drain( proc );
    895                 #endif
     915        #endif
    896916        #endif
    897917        return ret;
  • libcfa/src/concurrency/kernel.hfa

    rb14ec5f r84a6e70  
    195195struct __cluster_proc_list {
    196196        // Spin lock protecting the queue
    197         __spinlock_t lock;
    198 
    199         // FD to use to wake a processor
    200         volatile int fd;
     197        volatile uint64_t lock;
    201198
    202199        // Total number of processors
  • libcfa/src/concurrency/kernel/startup.cfa

    rb14ec5f r84a6e70  
    584584// Cluster
    585585static void ?{}(__cluster_proc_list & this) {
    586         this.fd    = 0;
     586        this.lock  = 0;
    587587        this.idle  = 0;
    588588        this.total = 0;
Note: See TracChangeset for help on using the changeset viewer.