Line data Source code
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/. */
6 :
7 : #include "threading/Mutex.h"
8 :
9 : #include "js/Utility.h"
10 :
11 : using namespace js;
12 :
13 : #ifdef DEBUG
14 :
15 : MOZ_THREAD_LOCAL(js::Mutex::MutexVector*) js::Mutex::HeldMutexStack;
16 :
17 : /* static */ bool
18 3 : js::Mutex::Init()
19 : {
20 3 : return HeldMutexStack.init();
21 : }
22 :
23 : /* static */ void
24 0 : js::Mutex::ShutDown()
25 : {
26 0 : js_delete(HeldMutexStack.get());
27 0 : HeldMutexStack.set(nullptr);
28 0 : }
29 :
30 : /* static */ js::Mutex::MutexVector&
31 1535692 : js::Mutex::heldMutexStack()
32 : {
33 1535692 : auto stack = HeldMutexStack.get();
34 1535804 : if (!stack) {
35 82 : AutoEnterOOMUnsafeRegion oomUnsafe;
36 41 : stack = js_new<MutexVector>();
37 41 : if (!stack)
38 0 : oomUnsafe.crash("js::Mutex::heldMutexStack");
39 41 : HeldMutexStack.set(stack);
40 : }
41 1535804 : return *stack;
42 : }
43 :
44 : void
45 224654 : js::Mutex::lock()
46 : {
47 224654 : auto& stack = heldMutexStack();
48 224654 : if (!stack.empty()) {
49 322 : const Mutex& prev = *stack.back();
50 322 : if (id_.order <= prev.id_.order) {
51 : fprintf(stderr,
52 : "Attempt to acquire mutex %s with order %d while holding %s with order %d\n",
53 0 : id_.name, id_.order, prev.id_.name, prev.id_.order);
54 0 : MOZ_CRASH("Mutex ordering violation");
55 : }
56 : }
57 :
58 224653 : MutexImpl::lock();
59 :
60 449414 : AutoEnterOOMUnsafeRegion oomUnsafe;
61 224713 : if (!stack.append(this))
62 0 : oomUnsafe.crash("js::Mutex::lock");
63 224703 : }
64 :
65 : void
66 224663 : js::Mutex::unlock()
67 : {
68 224663 : auto& stack = heldMutexStack();
69 224663 : MOZ_ASSERT(stack.back() == this);
70 224663 : MutexImpl::unlock();
71 224681 : stack.popBack();
72 224679 : }
73 :
74 : bool
75 1088261 : js::Mutex::ownedByCurrentThread() const
76 : {
77 1088261 : auto& stack = heldMutexStack();
78 1088336 : for (size_t i = 0; i < stack.length(); i++) {
79 634758 : if (stack[i] == this)
80 634728 : return true;
81 : }
82 454188 : return false;
83 : }
84 :
85 : #endif
|