summaryrefslogtreecommitdiffhomepage
path: root/compat/spinlock.hpp
blob: b94df7c885cbd7820053d93b0194d0e25e981c21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#pragma once

#include "export.hpp"
#include "macros1.h"
#include <atomic>

struct OTR_COMPAT_EXPORT spinlock_guard final
{
    spinlock_guard(const spinlock_guard&) = delete;
    spinlock_guard& operator=(const spinlock_guard&) = delete;
    constexpr spinlock_guard(spinlock_guard&&) noexcept = default;

    cc_forceinline
    spinlock_guard(std::atomic_flag* lock) noexcept : spinlock_guard(*lock) {}

    cc_forceinline
    spinlock_guard(std::atomic_flag& lock) noexcept : lock(lock)
    {
        while (lock.test_and_set(std::memory_order_acquire))
            (void)0;
    }

    cc_forceinline
    ~spinlock_guard() noexcept
    {
        lock.clear(std::memory_order_release);
    }

private:
    std::atomic_flag& lock;
};