Как известно, достаточно, чтобы использовать релиз-Acquire заказа (std::memory_order_acq_rel) когда мы используем только одну атомных переменные для хранения или загрузить его: https://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.htmlДостаточно использовать std :: memory_order_acq_rel с одним атомным var для add/sub/inc/dec?
Но, это верно и для других элементарных ожидания свободных функций, таких как: сложение, вычитание, приращение и декремент?
ie next()
функция потокобезопасна в следующем коде C++ для слабых (arm-cpu, ...) и сильных (x86-cpu, ...) моделей памяти или требуется другой барьерный порядок (ниже/выше)?
#include <iostream>
#include <atomic>
using namespace std;
class progression_lf {
public:
progression_lf() : n(0) {}
int next() {
// memory_order_acq_rel - enough, and increases performance for the weak memory models: arm, ...
int const current_n = n.fetch_add(1, std::memory_order_acq_rel);
int result = 2 + (current_n - 1)*3;
return result;
}
bool is_lock_free() { return ATOMIC_INT_LOCK_FREE; }
private:
std::atomic<int> n;
};
int main() {
// reference (single thread)
for(int n = 0; n < 10; ++n) {
std::cout << (2+(n-1)*3) << ", ";
}
std::cout << std::endl;
// wait-free (multi-thread safety)
progression_lf p;
for(int n = 0; n < 10; ++n) {
std::cout << (p.next()) << ", ";
}
std::cout << std::endl;
std::cout << "lock-free & wait-free: " <<
std::boolalpha << p.is_lock_free() <<
std::endl;
return 0;
}
Большое спасибо, и особое спасибо за ссылку. – Alex