#ifndef spinlock_h #define spinlock_h #include #include #include #include #include #include #include using namespace std::literals; class spinlock { public: void lock() { auto backoff = 1us; while (flag.test(std::memory_order_relaxed) || flag.test_and_set(std::memory_order_acquire)) std::this_thread::sleep_for(backoff *= 2); } void unlock() { flag.clear(std::memory_order_release); } private: std::atomic_flag flag; }; template class stack { public: void push(T t) { std::lock_guard lock(s); container.push(t); } std::optional pop() { std::lock_guard lock(s); if (!container.empty()) { T data = container.top(); container.pop(); return std::optional(data); } else { return std::nullopt; } } private: spinlock s; std::stack container; }; #endif // spinlock_h // #include // class spinlock // { // public: // void lock() // { // auto backoff = 1us; // while (flag.test(std::memory_order_relaxed) || // flag.test_and_set(std::memory_order_acquire)) // std::this_thread::sleep_for(backoff *= 2); // ANNOTATE_HAPPENS_AFTER(&flag); // } // void unlock() // { // ANNOTATE_HAPPENS_BEFORE(&flag); // flag.clear(std::memory_order_release); // } // private: // std::atomic_flag flag; // };