Skip to content

Instantly share code, notes, and snippets.

@inspirit
Last active August 29, 2015 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save inspirit/a14b0a1f227a2d288b46 to your computer and use it in GitHub Desktop.
Save inspirit/a14b0a1f227a2d288b46 to your computer and use it in GitHub Desktop.
lock-free 8bit mask
// we only allow no more than 8 worker 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;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment