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")]] SpinLocker
120{
121 public:
123 {
125 }
126
127 SpinLocker(const SpinLocker &) = delete;
128 SpinLocker &operator=(const SpinLocker &) = delete;
129
130 // move constructor
132 {
133 other.m_lock = nullptr;
134 }
135
136 // move assignment
138 {
139 if (this != &other)
140 {
141 m_lock = other.m_lock;
142 other.m_lock = nullptr;
143 }
144 return *this;
145 }
146
148 {
149 if (m_lock)
151 }
152
153 private:
155};
156
158{
159 return SpinLocker(this);
160}
SpinLocker & operator=(SpinLocker &&other)
Definition spinlock.hpp:137
spinlock_t * m_lock
Definition spinlock.hpp:154
SpinLocker(const SpinLocker &)=delete
SpinLocker(SpinLocker &&other)
Definition spinlock.hpp:131
SpinLocker(spinlock_t *lock)
Definition spinlock.hpp:122
SpinLocker & operator=(const SpinLocker &)=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:157