Changes in / [34b8cb7:b14ec5f]


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

Legend:

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

    r34b8cb7 rb14ec5f  
    124124static void __wake_one(cluster * cltr);
    125125
    126 static void mark_idle (__cluster_proc_list & idles, processor & proc);
     126static bool mark_idle (__cluster_proc_list & idles, processor & proc);
    127127static void mark_awake(__cluster_proc_list & idles, processor & proc);
    128128
     
    212212
    213213                                // Push self to idle stack
    214                                 mark_idle(this->cltr->procs, * this);
     214                                if(!mark_idle(this->cltr->procs, * this)) continue MAIN_LOOP;
    215215
    216216                                // Confirm the ready-queue is empty
     
    330330                                // Push self to idle stack
    331331                                ready_schedule_unlock();
    332                                 mark_idle(this->cltr->procs, * this);
     332                                if(!mark_idle(this->cltr->procs, * this)) goto SEARCH;
    333333                                ready_schedule_lock();
    334334
     
    802802}
    803803
    804 static void mark_idle(__cluster_proc_list & this, processor & proc) {
    805         /* paranoid */ verify( ! __preemption_enabled() );
    806         lock( this );
     804static bool mark_idle(__cluster_proc_list & this, processor & proc) {
     805        /* paranoid */ verify( ! __preemption_enabled() );
     806        if(!try_lock( this )) return false;
    807807                this.idle++;
    808808                /* paranoid */ verify( this.idle <= this.total );
     
    813813        unlock( this );
    814814        /* paranoid */ verify( ! __preemption_enabled() );
     815
     816        return true;
    815817}
    816818
  • libcfa/src/concurrency/kernel_private.hfa

    r34b8cb7 rb14ec5f  
    282282}
    283283
     284static inline bool try_lock(__cluster_proc_list & this) {
     285        /* paranoid */ verify( ! __preemption_enabled() );
     286
     287        // Start by locking the global RWlock so that we know no-one is
     288        // adding/removing processors while we mess with the idle lock
     289        ready_schedule_lock();
     290
     291        // Simple counting lock, acquired, acquired by incrementing the counter
     292        // to an odd number
     293        uint64_t l = this.lock;
     294        if(
     295                (0 == (l % 2))
     296                && __atomic_compare_exchange_n(&this.lock, &l, l + 1, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
     297        ) {
     298                // success
     299                /* paranoid */ verify( ! __preemption_enabled() );
     300                return true;
     301        }
     302
     303        // failed to lock
     304        ready_schedule_unlock();
     305
     306        /* paranoid */ verify( ! __preemption_enabled() );
     307        return false;
     308}
     309
    284310static inline void unlock(__cluster_proc_list & this) {
    285311        /* paranoid */ verify( ! __preemption_enabled() );
Note: See TracChangeset for help on using the changeset viewer.