//! \~\file pispinlock.h //! \~\ingroup Thread //! \~\brief //! \~english Spinlock with busy waiting //! \~russian Спинлок с активным ожиданием /* PIP - Platform Independent Primitives PISpinlock Ivan Pelipenko peri4ko@yandex.ru This program 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 3 of the License, or (at your option) any later version. This program 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 this program. If not, see . */ #ifndef PISPINLOCK_H #define PISPINLOCK_H #include "piinit.h" #include //! \~\ingroup Thread //! \~\brief //! \~english Lock based on atomic spinning for very short critical sections. //! \~russian Блокировка на основе атомарного вращения для очень коротких критических секций. class PIP_EXPORT PISpinlock { public: NO_COPY_CLASS(PISpinlock); //! \~english Constructs unlocked spinlock //! \~russian Создает незаблокированный спинлок explicit PISpinlock() { flag.clear(); } //! \~english Destroy spinlock //! \~russian Деструктор спинлока ~PISpinlock() {} //! \~english Acquires the spinlock, busy-waiting until it becomes free. //! \~russian Захватывает спинлок, активно ожидая его освобождения. void lock() { while (flag.test_and_set(std::memory_order_acquire)) ; } //! \~english Releases the spinlock. //! \~russian Освобождает спинлок. void unlock() { flag.clear(std::memory_order_release); } private: std::atomic_flag flag; }; //! \~\ingroup Thread //! \~\brief //! \~english Scope guard that locks a %PISpinlock in constructor and unlocks it in destructor. //! \~russian Защитник области видимости, который блокирует %PISpinlock в конструкторе и разблокирует его в деструкторе. class PIP_EXPORT PISpinlockLocker { public: NO_COPY_CLASS(PISpinlockLocker); //! \~english Constructs and lock "s" if "condition" is \c true //! \~russian Создает и блокирует спинлок "s" если "condition" \c true PISpinlockLocker(PISpinlock & s, bool condition = true): spinlock(s), cond(condition) { if (cond) spinlock.lock(); } //! \~english Unlock "s" if "condition" was \c true //! \~russian Разблокирует спинлок "s" если "condition" был \c true ~PISpinlockLocker() { if (cond) spinlock.unlock(); } private: PISpinlock & spinlock; bool cond; }; #endif // PISPINLOCK_H