Is there atomic increment with the check preconditions, that the atomic value was less than the specified value?

喜你入骨 提交于 2019-12-22 09:49:17

问题


Is in the new standard C++ atomic increment operation with the check preconditions before the incremented the value, that the atomic value was less than the specified value?

Can I do it easier and faster than the following code?

int atomic_inc(std::atomic_int& val, int less_than) {
 int new_val;
 int old_val = val.load();
 do
 {
   if (old_val > less_than) return old_val;
   new_val = old_val + 1;
 } while (!val.compare_exchange_weak(old_val, new_val));

 return new_val;
}

If somebody don't know how works compare_exchange_weak: compare_exchange_weak reads val, compares with old_val, and if they are not equal then saves val to old_val. If it is equal then save new_val to val.


回答1:


No, there is no special support for incrementing values less than a value. Your code is as efficient as you can get. There is no wait-free variant in C++11

There is an unlimited number of possible "increment if X" patterns. The hardware manufacturers decided that "increment if not changed" is the only thing they need to support.

In theory you could invent a hardware platform with a special assembly code for it, but C++11 does not directly target that.




回答2:


Something I have done in the past, might work for you depending on what you're using this for.

If you can assume that val won't clip very often -- so that the possible optimization of not doing a CAS isn't going to save you much --, you can just blindly increment the value and adjust it after you read:

int atomic_inc(std::atomic_int& val, int less_than) {
    return std::min(++val, less_than);
}

And then occasionally clip val back down to less_than if needed, often enough that you don't have to worry about the int overflowing, and you're golden.




回答3:


If you're using threads, you can use mutex to do an atomic increment. Here's how you'd do it in this case:

Declare and initialize mutex globally:

pthread_mutex_t lock;
pthread_mutex_init(&lock, NULL)

In one thread:

int atomic_inc(std::atomic_int& val, int less_than) {
    pthread_mutex_lock(&lock);
    int newVal = val.load();
    if (newVal < less_than)
        newVal++
    pthread_mutex_unlock(&lock);
    return new_val;
}

You would have to lock and unlock the mutex before modifying val in any other thread.

For more information on mutex: http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html#SYNCHRONIZATION



来源:https://stackoverflow.com/questions/13778110/is-there-atomic-increment-with-the-check-preconditions-that-the-atomic-value-wa

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!