I have pretty simple scenario to track thread indices that are sleeping so 
i can wakeup them when it is required:

// we only allow no more than 8 workers in pool
std::atomic_uint_fast8_t idle_mask = {0};
 
// this function is called by each thread when it is about to sleep
void register_idle(const size_t thread_id)
{
        idle_mask.fetch_or(1u << thread_id, std::memory_order_release);
}
 
// this function can be called from anywhere at anytime
void wakeup_idle()
{
        uint_fast8_t snap(idle_mask.load(std::memory_order_relaxed));
        // Turn off the rightmost 1-bit.
        while(!idle_mask.compare_exchange_weak(snap, snap & (snap-1), 
                                                std::memory_order_acquire, 
std::memory_order_relaxed))
        {}
        // snap now should be the state before we turn off 1-bit.
        if(snap == 0) return;
        // Isolate the rightmost 1-bit.
        uint_fast8_t idle_bit = snap & (-snap);
        // find the bit
        for(size_t i = 0; i < 8; ++i)
        {
                if((idle_bit&(1u<<i)) != 0)
                {
                        signal_thread(i);
                        break;
                }
        }
}


 this is indeed pretty simple how ever i was wondering if i defined memory 
orders for operations correctly?
on mobile platforms relaxing memory orders for compare_exchange for example 
can really give you nice speedup.

-- 

--- 
You received this message because you are subscribed to the Google Groups 
"Scalable Synchronization Algorithms" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/lock-free/f8b25ab6-4824-4373-aa33-5bc895a56f55%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to