Bug 1865597 - Add error checking when initializing parallel marking and disable on...
[gecko.git] / mozglue / misc / WinUtils.h
blob2291a352a5a33d89cbc1b1ffd8f8ef7b7fdd4f46
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_glue_MozglueUtils_h
8 #define mozilla_glue_MozglueUtils_h
10 #include <windows.h>
12 #include "mozilla/Atomics.h"
13 #include "mozilla/Attributes.h"
15 namespace mozilla {
16 namespace glue {
18 #ifdef DEBUG
20 class MOZ_STATIC_CLASS Win32SRWLock final {
21 public:
22 // Microsoft guarantees that '0' is never a valid thread id
23 // https://docs.microsoft.com/en-ca/windows/desktop/ProcThread/thread-handles-and-identifiers
24 static const DWORD kInvalidThreadId = 0;
26 constexpr Win32SRWLock()
27 : mExclusiveThreadId(kInvalidThreadId), mLock(SRWLOCK_INIT) {}
29 ~Win32SRWLock() { MOZ_ASSERT(mExclusiveThreadId == kInvalidThreadId); }
31 void LockShared() {
32 MOZ_ASSERT(
33 mExclusiveThreadId != GetCurrentThreadId(),
34 "Deadlock detected - A thread attempted to acquire a shared lock on "
35 "a SRWLOCK when it already owns the exclusive lock on it.");
37 ::AcquireSRWLockShared(&mLock);
40 void UnlockShared() { ::ReleaseSRWLockShared(&mLock); }
42 void LockExclusive() {
43 MOZ_ASSERT(
44 mExclusiveThreadId != GetCurrentThreadId(),
45 "Deadlock detected - A thread attempted to acquire an exclusive lock "
46 "on a SRWLOCK when it already owns the exclusive lock on it.");
48 ::AcquireSRWLockExclusive(&mLock);
49 mExclusiveThreadId = GetCurrentThreadId();
52 void UnlockExclusive() {
53 MOZ_ASSERT(mExclusiveThreadId == GetCurrentThreadId());
55 mExclusiveThreadId = kInvalidThreadId;
56 ::ReleaseSRWLockExclusive(&mLock);
59 Win32SRWLock(const Win32SRWLock&) = delete;
60 Win32SRWLock(Win32SRWLock&&) = delete;
61 Win32SRWLock& operator=(const Win32SRWLock&) = delete;
62 Win32SRWLock& operator=(Win32SRWLock&&) = delete;
64 private:
65 // "Relaxed" memory ordering is fine. Threads will see other thread IDs
66 // appear here in some non-deterministic ordering (or not at all) and simply
67 // ignore them.
69 // But a thread will only read its own ID if it previously wrote it, and a
70 // single thread doesn't need a memory barrier to read its own write.
72 Atomic<DWORD, Relaxed> mExclusiveThreadId;
73 SRWLOCK mLock;
76 #else // DEBUG
78 class MOZ_STATIC_CLASS Win32SRWLock final {
79 public:
80 constexpr Win32SRWLock() : mLock(SRWLOCK_INIT) {}
82 void LockShared() { ::AcquireSRWLockShared(&mLock); }
84 void UnlockShared() { ::ReleaseSRWLockShared(&mLock); }
86 void LockExclusive() { ::AcquireSRWLockExclusive(&mLock); }
88 void UnlockExclusive() { ::ReleaseSRWLockExclusive(&mLock); }
90 ~Win32SRWLock() = default;
92 Win32SRWLock(const Win32SRWLock&) = delete;
93 Win32SRWLock(Win32SRWLock&&) = delete;
94 Win32SRWLock& operator=(const Win32SRWLock&) = delete;
95 Win32SRWLock& operator=(Win32SRWLock&&) = delete;
97 private:
98 SRWLOCK mLock;
101 #endif
103 class MOZ_RAII AutoSharedLock final {
104 public:
105 explicit AutoSharedLock(Win32SRWLock& aLock) : mLock(aLock) {
106 mLock.LockShared();
109 ~AutoSharedLock() { mLock.UnlockShared(); }
111 AutoSharedLock(const AutoSharedLock&) = delete;
112 AutoSharedLock(AutoSharedLock&&) = delete;
113 AutoSharedLock& operator=(const AutoSharedLock&) = delete;
114 AutoSharedLock& operator=(AutoSharedLock&&) = delete;
116 private:
117 Win32SRWLock& mLock;
120 class MOZ_RAII AutoExclusiveLock final {
121 public:
122 explicit AutoExclusiveLock(Win32SRWLock& aLock) : mLock(aLock) {
123 mLock.LockExclusive();
126 ~AutoExclusiveLock() { mLock.UnlockExclusive(); }
128 AutoExclusiveLock(const AutoExclusiveLock&) = delete;
129 AutoExclusiveLock(AutoExclusiveLock&&) = delete;
130 AutoExclusiveLock& operator=(const AutoExclusiveLock&) = delete;
131 AutoExclusiveLock& operator=(AutoExclusiveLock&&) = delete;
133 private:
134 Win32SRWLock& mLock;
137 } // namespace glue
138 } // namespace mozilla
140 #endif // mozilla_glue_MozglueUtils_h