20 #include "pedigree/kernel/Spinlock.h" 21 #include "pedigree/kernel/processor/Processor.h" 22 #include "pedigree/kernel/processor/ProcessorInformation.h" 25 #include "pedigree/kernel/debugger/commands/LocksCommand.h" 28 #include "pedigree/kernel/Log.h" 29 #include "pedigree/kernel/panic.h" 35 Spinlock::Spinlock() =
default;
37 Spinlock::Spinlock(
bool bLocked,
bool bAvoidTracking) :
Spinlock()
40 m_bAvoidTracking = bAvoidTracking;
63 if (m_Magic != 0xdeadbaba)
66 reinterpret_cast<uintptr_t
>(__builtin_return_address(0));
67 WARNING(
" --> fail: thread=" << pThread);
68 WARNING(
" --> fail: sentinels: before=" <<
Hex << m_Sentinel <<
" after=" << m_MagicAlign <<
" " << m_pOwner);
70 "Wrong magic in acquire [" 71 <<
Hex << m_Magic <<
" should be 0xdeadbaba] [this=" << reinterpret_cast<uintptr_t>(
this)
72 <<
"] return=" << myra);
76 if (!m_bAvoidTracking)
78 g_LocksCommand.clearFatal();
79 if (!g_LocksCommand.lockAttempted(
this,
Processor::id(), bInterrupts))
82 reinterpret_cast<uintptr_t
>(__builtin_return_address(0));
84 "Spinlock: LocksCommand disallows this acquire [return=" 85 <<
Hex << myra <<
"].");
91 while (m_Atom.compareAndSwap(
true,
false) ==
false)
94 if (m_bOwned && (m_pOwner == pThread) && recurse)
104 if (!m_bAvoidTracking)
106 g_LocksCommand.clearFatal();
110 reinterpret_cast<uintptr_t
>(__builtin_return_address(0));
112 "Spinlock: LocksCommand failed a state check [return=" 113 <<
Hex << myra <<
"].");
119 #ifdef MULTIPROCESSOR 145 size_t atom = m_Atom;
149 reinterpret_cast<uintptr_t
>(__builtin_return_address(0));
150 ERROR_NOLOCK(
"Spinlock has deadlocked in acquire");
151 ERROR_NOLOCK(
" -> level is " << m_Level);
152 ERROR_NOLOCK(
" -> my return address is " <<
Hex << myra);
153 ERROR_NOLOCK(
" -> return address of other locker is " <<
Hex << m_Ra);
155 "Spinlock has deadlocked, spinlock is " 156 <<
Hex << reinterpret_cast<uintptr_t>(
this) <<
", atom is " << atom
161 panic(
"Spinlock has deadlocked");
163 m_Ra =
reinterpret_cast<uintptr_t
>(__builtin_return_address(0));
166 if (!m_bAvoidTracking)
168 g_LocksCommand.clearFatal();
169 if (!g_LocksCommand.lockAcquired(
this,
Processor::id(), bInterrupts))
172 reinterpret_cast<uintptr_t
>(__builtin_return_address(0));
174 "Spinlock: LocksCommand disallows this acquire [return=" 175 <<
Hex << myra <<
"].");
181 if (recurse && !m_bOwned)
183 m_pOwner =
static_cast<void *
>(pThread);
188 m_bInterrupts = bInterrupts;
197 if (!m_bAvoidTracking)
199 g_LocksCommand.clearFatal();
203 reinterpret_cast<uintptr_t
>(__builtin_return_address(0));
205 "Spinlock: LocksCommand disallows this release [return=" 206 <<
Hex << myra <<
"].");
216 if (bWasInterrupts ==
true)
218 FATAL_NOLOCK(
"Spinlock: release() called with interrupts enabled.");
221 if (m_Magic != 0xdeadbaba)
223 FATAL_NOLOCK(
"Wrong magic in release.");
241 m_OwnedProcessor = ~0;
247 if (m_Atom.compareAndSwap(
false,
true) ==
false)
254 size_t atom = m_Atom;
258 reinterpret_cast<uintptr_t
>(__builtin_return_address(0));
260 "Spinlock has deadlocked in release, my return address is " 261 <<
Hex << myra <<
", return address of other locker is " << m_Ra
262 <<
", spinlock is " << reinterpret_cast<uintptr_t>(
this)
263 <<
", atom is " <<
Dec << atom <<
".");
267 panic(
"Spinlock has deadlocked");
275 bool bInterrupts = m_bInterrupts;
292 m_OwnedProcessor = ~0;
296 bool Spinlock::acquired()
301 bool Spinlock::interrupts()
const 303 return m_bInterrupts;
static bool getInterrupts()
bool acquire(bool recurse=false, bool safe=true)
bool lockReleased(const Spinlock *pLock, size_t nCpu=~0U)
static ProcessorInformation & information()
void trackRelease() const
bool checkState(const Spinlock *pLock, size_t nCpu=~0U)
static void setInterrupts(bool bEnable)
void EXPORTED_PUBLIC panic(const char *msg) NORETURN