/* This file is part of TON Blockchain Library. TON Blockchain Library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. TON Blockchain Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . Copyright 2017-2019 Telegram Systems LLP */ #pragma once #include "td/utils/port/thread.h" #include #include namespace td { class SpinLock { struct Unlock { void operator()(SpinLock *ptr) { ptr->unlock(); } }; class InfBackoff { int cnt = 0; public: bool next() { cnt++; if (cnt < 50) { //TODO pause return true; } else { td::this_thread::yield(); return true; } } }; public: using Lock = std::unique_ptr; Lock lock() { InfBackoff backoff; while (!try_lock()) { backoff.next(); } return Lock(this); } bool try_lock() { return !flag_.test_and_set(std::memory_order_acquire); } private: std::atomic_flag flag_ = ATOMIC_FLAG_INIT; void unlock() { flag_.clear(std::memory_order_release); } }; } // namespace td