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 #include "threading/Mutex.h"
13 MOZ_THREAD_LOCAL(js::Mutex
*) js::Mutex::HeldMutexStack
;
16 bool js::Mutex::Init() { return HeldMutexStack
.init(); }
18 void js::Mutex::lock() {
24 bool js::Mutex::tryLock() {
26 if (!impl_
.tryLock()) {
34 void js::Mutex::preLockChecks() const {
35 Mutex
* prev
= HeldMutexStack
.get();
37 if (id_
.order
<= prev
->id_
.order
) {
39 "Attempt to acquire mutex %s with order %u while holding %s with "
41 id_
.name
, id_
.order
, prev
->id_
.name
, prev
->id_
.order
);
42 MOZ_CRASH("Mutex ordering violation");
47 void js::Mutex::postLockChecks() {
48 MOZ_ASSERT(!owningThread_
);
49 owningThread_
= ThreadId::ThisThreadId();
51 MOZ_ASSERT(prev_
== nullptr);
52 prev_
= HeldMutexStack
.get();
53 HeldMutexStack
.set(this);
56 void js::Mutex::unlock() {
61 void js::Mutex::preUnlockChecks() {
62 Mutex
* stack
= HeldMutexStack
.get();
63 MOZ_ASSERT(stack
== this);
64 HeldMutexStack
.set(prev_
);
67 MOZ_ASSERT(ThreadId::ThisThreadId() == owningThread_
);
68 owningThread_
= ThreadId();
71 void js::Mutex::assertOwnedByCurrentThread() const {
72 // This check is only thread-safe if it succeeds.
73 MOZ_ASSERT(ThreadId::ThisThreadId() == owningThread_
);
75 MOZ_ASSERT(isOwnedByCurrentThread());
78 bool js::Mutex::isOwnedByCurrentThread() const {
79 // Check whether the mutex is on the thread-local mutex stack.
80 for (Mutex
* mutex
= HeldMutexStack
.get(); mutex
; mutex
= mutex
->prev_
) {