MOS Source Code
Loading...
Searching...
No Matches
spinlock.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#pragma once
4
5#include "mos/platform/platform_defs.hpp"
6
7#include <mos/mos_global.h>
8#include <mos/types.hpp>
9
10#define barrier() MOS_PLATFORM_MEMORY_BARRIER()
11
12class SpinLocker;
14{
15 bool flag = false;
16#if MOS_DEBUG_FEATURE(spinlock)
17 const char *file = nullptr;
18 int line = 0;
19#endif
20
22};
23
24#define spinlock_init(lock) \
25 do \
26 { \
27 (lock)->flag = 0; \
28 } while (0)
29
30// clang-format off
31#define SPINLOCK_INIT { 0 }
32// clang-format on
33
34#define _spinlock_real_acquire(lock) \
35 do \
36 { \
37 barrier(); \
38 while (__atomic_test_and_set(&(lock)->flag, __ATOMIC_ACQUIRE)) \
39 ; \
40 } while (0)
41
42#define _spinlock_real_release(lock) \
43 do \
44 { \
45 __atomic_clear(&(lock)->flag, __ATOMIC_RELEASE); \
46 } while (0)
47
48#if MOS_DEBUG_FEATURE(spinlock)
49#define spinlock_acquire(lock) \
50 do \
51 { \
52 _spinlock_real_acquire(lock); \
53 (lock)->file = __FILE__; \
54 (lock)->line = __LINE__; \
55 } while (0)
56#define spinlock_release(lock) \
57 do \
58 { \
59 (lock)->file = NULL; \
60 (lock)->line = 0; \
61 _spinlock_real_release(lock); \
62 } while (0)
63#else
64#define spinlock_acquire(lock) _spinlock_real_acquire(lock)
65#define spinlock_release(lock) _spinlock_real_release(lock)
66#endif
67
68#define spinlock_acquire_nodebug(lock) _spinlock_real_acquire(lock)
69#define spinlock_release_nodebug(lock) _spinlock_real_release(lock)
70
72{
73 return lock->flag;
74}
75
76typedef struct
77{
79 void *owner;
80 size_t count;
82
83// clang-format off
84#define RECURSIVE_SPINLOCK_INIT { SPINLOCK_INIT, NULL, 0 }
85// clang-format on
86
88{
89 if (lock->owner == owner)
90 {
91 lock->count++;
92 }
93 else
94 {
95 spinlock_acquire(&lock->lock);
96 lock->owner = owner;
97 lock->count = 1;
98 }
99}
100
102{
103 if (lock->owner == owner)
104 {
105 lock->count--;
106 if (lock->count == 0)
107 {
108 lock->owner = NULL;
109 spinlock_release(&lock->lock);
110 }
111 }
112}
113
118
119class [[nodiscard("don't discard")]] SpinUnlocker
120{
121 public:
122 explicit SpinUnlocker(spinlock_t *lock) : m_lock(lock)
123 {
125 }
126
127 SpinUnlocker(const SpinUnlocker &) = delete;
131
132 void discard()
133 {
134 m_lock = nullptr;
135 }
136
138 {
139 if (m_lock)
141 }
142
143 private:
145};
146
147class [[nodiscard("don't discard")]] SpinLocker
148{
149 public:
150 explicit SpinLocker(spinlock_t *lock) : m_lock(lock)
151 {
153 }
154
155 SpinLocker(const SpinLocker &) = delete;
156 SpinLocker &operator=(const SpinLocker &) = delete;
157 SpinLocker(SpinLocker &&) = delete;
159
160 void discard()
161 {
162 m_lock = nullptr;
163 }
164
166 {
167 if (m_lock)
169 }
170
175
176 private:
178};
179
181{
182 return SpinLocker(this);
183}
spinlock_t * m_lock
Definition spinlock.hpp:177
void discard()
Definition spinlock.hpp:160
SpinLocker & operator=(SpinLocker &&)=delete
SpinUnlocker UnlockTemporarily()
Definition spinlock.hpp:171
SpinLocker(SpinLocker &&)=delete
SpinLocker(const SpinLocker &)=delete
SpinLocker(spinlock_t *lock)
Definition spinlock.hpp:150
SpinLocker & operator=(const SpinLocker &)=delete
spinlock_t * m_lock
Definition spinlock.hpp:144
SpinUnlocker & operator=(SpinUnlocker &&)=delete
void discard()
Definition spinlock.hpp:132
SpinUnlocker(const SpinUnlocker &)=delete
SpinUnlocker(spinlock_t *lock)
Definition spinlock.hpp:122
SpinUnlocker(SpinUnlocker &&)=delete
SpinUnlocker & operator=(const SpinUnlocker &)=delete
#define should_inline
Definition mos_global.h:37
#define NULL
Definition pb_syshdr.h:46
should_inline bool spinlock_is_locked(const spinlock_t *lock)
Definition spinlock.hpp:71
should_inline void recursive_spinlock_release(recursive_spinlock_t *lock, void *owner)
Definition spinlock.hpp:101
#define spinlock_acquire(lock)
Definition spinlock.hpp:64
should_inline bool recursive_spinlock_is_locked(recursive_spinlock_t *lock)
Definition spinlock.hpp:114
should_inline void recursive_spinlock_acquire(recursive_spinlock_t *lock, void *owner)
Definition spinlock.hpp:87
#define spinlock_release(lock)
Definition spinlock.hpp:65
SpinLocker lock()
Definition spinlock.hpp:180