I've been looking around for a way to protect an integer to be incremented atomically but with bound checking. I've seen other treads about the same but none seem to have a good solution (and some are pre-C++11).
What I need is a library something similar to:
class bounded_atomic_uint
{
private:
uint32_t ctr;
uint32_t max;
mutex mtx;
public:
bounded_atomic_uint(uint32_t max = UINT32_MAX) : ctr(0), max(max) {}
~bounded_atomic_uint() = default;
// make in uncopyable and un-movable
bounded_atomic_uint(bounded_atomic_uint&&) = delete;
bounded_atomic_uint& operator=(bounded_atomic_uint&&) = delete;
bool inc();
bool dec();
uint32_t get();
};
bool bounded_atomic_uint::inc() {
lock_guard<mutex> lck (mtx);
if (ctr < max) {
ctr++;
return true;
}
else
{
cout << "max reached (" << max << ")" << endl; // to be removed!
return false; // reached max value
}
}
bool bounded_atomic_uint::dec() {
lock_guard<mutex> lck (mtx);
if (ctr > 0) {
ctr--;
return true;
}
else {
cout << "min reached (0)" << endl; // to be removed!
return false; // reached min value
}
}
uint32_t bounded_atomic_uint::get() {
lock_guard<mutex> lck (mtx);
return ctr;
}
to be used like:
#include <iostream>
#include <mutex>
#include <cstdint>
using namespace std;
int main() {
bounded_atomic_uint val(3);
if (val.dec())
cout << "error: dec from 0 succeeded !!" << endl;
cout << val.get() << endl; // make sure it prints 0
val.inc();
val.inc();
cout << val.get() << endl;
if (!val.inc())
cout << "error: havent reached max but failed!!" << endl;
if (val.inc())
cout << "error max not detected!!" << endl;
cout << val.get() << endl;
return 0;
}
Is there anything similar available somewhere? neither std::atomic nor boost::atomic seem to have a way to avoid out-bounding check (inside a lock).
If not, is this simplistic class good enough? Or am I missing anything here?
Note that the couts on the library are to be removed on real usage!
Aucun commentaire:
Enregistrer un commentaire