user1235183 user1235183 - 1 month ago 21
C++ Question

Is this a C++ Semaphore?

I have a thread-save-resource (a OpenCl-Command Queue to a device),but i want restrict the number of threads that have access to this ressource at the same time(i want to calculate on my cpu if the gpu command-queue is 'to full'). Unfortunately i'm relatively new to c++11 atomic operations. So i want to know if the following source code works as intended.

class SpinSemaphore{
public:
SpinSemaphore(int max_count):
_cnt(0),
_max_cnt(max_count){}

bool try_lock(){
bool run = true;
while(run){
int cnt = _cnt.load();
if(++cnt > _max_cnt) return false;

run = !std::atomic_compare_exchange_weak(&_cnt, &cnt,
std::memory_order_acquire);
}
return true;
}

void unlock(){
--_cnt;
}

private:
std::atomic<int> _cnt;
int _max_cnt;
};

//

SpinSemaphore m(4);

void foo(){ //..
if(m.try_lock()){//..
my_queue.enqueueNDRangeKernel(/**/);
}
else
//fallback

}

Answer

No, that won't behave as expected - consider the situation where 2 threads get to int cnt = _cnt.load(); at the same time. They will both read the same value, and both set the counter to the same value, even though it might be that only 1 of them should've got though.

That might be considered an acceptably rare occurrence for you to ignore, apart from when you unlock, your count will become negative.