Atomic Bitfields to track status

40 views
Skip to first unread message

Eugene Zatepyakin

unread,
Jun 20, 2015, 1:01:38 PM6/20/15
to lock...@googlegroups.com
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.
Reply all
Reply to author
Forward
0 new messages