Skip to content

Instantly share code, notes, and snippets.

@thealexcons
Last active March 14, 2022 09:32
Show Gist options
  • Save thealexcons/638912e3f83b67b78ff6e431a5b4f1a3 to your computer and use it in GitHub Desktop.
Save thealexcons/638912e3f83b67b78ff6e431a5b4f1a3 to your computer and use it in GitHub Desktop.
Atomic CAS counting semphore
#include <atomic>
#include <thread>
#include <emmintrin.h>
class Semaphore {
public:
explicit Semaphore(uint32_t init_value);
void acquire();
void release();
private:
std::atomic<uint32_t> counter;
};
Semaphore::Semaphore(uint32_t init_value) : counter(init_value) {}
void Semaphore::acquire() {
while (true) {
uint32_t curr;
do {
// Busy wait while checking for updates
_mm_pause();
curr = counter.load();
} while (curr == 0);
/* Acquire if no other thread has updated the counter since
we last read the counter into our local register */
if (counter.compare_exchange_strong(curr, curr - 1)) {
return;
}
/* If we fail, another thread updated counter before us, so
we need to retry */
}
}
void Semaphore::release() {
counter.fetch_add(1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment