vendredi 4 août 2017

Are there "bounded atomic integers" libraries?

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