46 lines
1.1 KiB
C
46 lines
1.1 KiB
C
|
#ifndef COUNTING_SEMAPHORE_H
|
||
|
#define COUNTING_SEMAPHORE_H
|
||
|
#include <mutex>
|
||
|
#include <condition_variable>
|
||
|
#include <algorithm>
|
||
|
#include <thread>
|
||
|
#include <mutex>
|
||
|
#include <condition_variable>
|
||
|
#include <thread>
|
||
|
|
||
|
class CountingSemaphore {
|
||
|
public:
|
||
|
static CountingSemaphore& getInstance()
|
||
|
{
|
||
|
static CountingSemaphore instance;
|
||
|
return instance;
|
||
|
}
|
||
|
// Delete copy constructor and assignment operator
|
||
|
CountingSemaphore(const CountingSemaphore&) = delete;
|
||
|
CountingSemaphore& operator=(const CountingSemaphore&) = delete;
|
||
|
void acquire()
|
||
|
{
|
||
|
std::unique_lock<std::mutex> lock(mtx_);
|
||
|
cv_.wait(lock, [this]() { return count_ > 0; });
|
||
|
--count_;
|
||
|
}
|
||
|
void release()
|
||
|
{
|
||
|
std::lock_guard<std::mutex> lock(mtx_);
|
||
|
++count_;
|
||
|
if (count_ <= max_count_) {
|
||
|
cv_.notify_one();
|
||
|
}
|
||
|
}
|
||
|
private:
|
||
|
CountingSemaphore()
|
||
|
: max_count_(std::max(1u, static_cast<uint>(0.95 * std::thread::hardware_concurrency()))),
|
||
|
count_(max_count_)
|
||
|
{
|
||
|
}
|
||
|
std::mutex mtx_;
|
||
|
std::condition_variable cv_;
|
||
|
const uint max_count_;
|
||
|
uint count_;
|
||
|
};
|
||
|
#endif
|