#ifndef stack_h #define stack_h 1 #include #include #include #include using namespace std::chrono_literals; class mutex { public: void lock() { auto delay = 64us; while (!m.try_lock()) std::this_thread::sleep_for(delay *= 2); } void unlock() { m.unlock(); } private: std::mutex m; }; template class lock_guard { public: lock_guard(lock& l): l(l) { l.lock(); } lock_guard(const lock_guard&) = delete; lock_guard& operator=(const lock_guard&) = delete; ~lock_guard() { l.unlock(); } private: lock& l; }; template class stack { public: using empty = std::exception; stack(): head(nullptr) {} ~stack() { while (head != nullptr) pop(); } void push(const T& t) { lock_guard l(m); head = new node{head, t}; } T pop() { lock_guard l(m); if (head != nullptr) { node* n = head; head = head->next; T t = n->data; delete n; return t; } throw empty(); } private: struct node { node* next; T data; }; mutex m; node* head; }; #endif // stack_h