fork download
  1. #include <atomic>
  2. #include <iostream>
  3.  
  4. template <class T> class Seqlock {
  5. std::atomic<int> seq_;
  6. T val_;
  7.  
  8. public:
  9. Seqlock(T value = T())
  10. : val_(value) {
  11. }
  12.  
  13. // concurrent calls are NOT allowed
  14. void store(T value) {
  15. const int seq0 = seq_.load(std::memory_order_relaxed);
  16. seq_.store(seq0 + 1, std::memory_order_relaxed);
  17.  
  18. std::atomic_thread_fence(std::memory_order_release);
  19.  
  20. val_ = value;
  21. std::atomic_thread_fence(std::memory_order_release);
  22.  
  23. seq_.store(seq0 + 2, std::memory_order_relaxed);
  24. }
  25.  
  26. // concurrent calls are allowed
  27. T load() const {
  28. for (;;) {
  29. const int seq0 = seq_.load(std::memory_order_relaxed);
  30. if (seq0 & 1) {
  31. // cpu_relax()
  32. continue;
  33. }
  34.  
  35. std::atomic_thread_fence(std::memory_order_acquire);
  36.  
  37. T ret = val_;
  38. std::atomic_thread_fence(std::memory_order_acquire);
  39.  
  40. const int seq1 = seq_.load(std::memory_order_relaxed);
  41. if (seq0 == seq1) {
  42. return ret;
  43. }
  44. }
  45. }
  46. };
  47.  
  48. int main() {
  49. Seqlock<int> sl;
  50. sl.store(123);
  51. std::cout << sl.load() << "\n";
  52. return 0;
  53. }
Success #stdin #stdout 0s 4508KB
stdin
Standard input is empty
stdout
123