Last active
August 29, 2015 14:23
-
-
Save inspirit/a14b0a1f227a2d288b46 to your computer and use it in GitHub Desktop.
lock-free 8bit mask
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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