OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "platform/heap/SafePoint.h" | 5 #include "platform/heap/SafePoint.h" |
6 | 6 |
7 #include "platform/heap/Heap.h" | 7 #include "platform/heap/Heap.h" |
8 #include "wtf/Atomics.h" | 8 #include "wtf/Atomics.h" |
9 #include "wtf/CurrentTime.h" | 9 #include "wtf/CurrentTime.h" |
10 | 10 |
(...skipping 10 matching lines...) Expand all Loading... |
21 // Wait time for parking all threads is at most 100 ms. | 21 // Wait time for parking all threads is at most 100 ms. |
22 return 0.100; | 22 return 0.100; |
23 } | 23 } |
24 | 24 |
25 SafePointBarrier::SafePointBarrier() | 25 SafePointBarrier::SafePointBarrier() |
26 : m_unparkedThreadCount(0), m_parkingRequested(0) {} | 26 : m_unparkedThreadCount(0), m_parkingRequested(0) {} |
27 | 27 |
28 SafePointBarrier::~SafePointBarrier() {} | 28 SafePointBarrier::~SafePointBarrier() {} |
29 | 29 |
30 bool SafePointBarrier::parkOthers() { | 30 bool SafePointBarrier::parkOthers() { |
31 ASSERT(ThreadState::current()->isAtSafePoint()); | 31 DCHECK(ThreadState::current()->isAtSafePoint()); |
32 | 32 |
33 ThreadState* current = ThreadState::current(); | 33 ThreadState* current = ThreadState::current(); |
34 // Lock threadAttachMutex() to prevent threads from attaching. | 34 // Lock threadAttachMutex() to prevent threads from attaching. |
35 current->lockThreadAttachMutex(); | 35 current->lockThreadAttachMutex(); |
36 const ThreadStateSet& threads = current->heap().threads(); | 36 const ThreadStateSet& threads = current->heap().threads(); |
37 | 37 |
38 MutexLocker locker(m_mutex); | 38 MutexLocker locker(m_mutex); |
39 atomicAdd(&m_unparkedThreadCount, threads.size()); | 39 atomicAdd(&m_unparkedThreadCount, threads.size()); |
40 releaseStore(&m_parkingRequested, 1); | 40 releaseStore(&m_parkingRequested, 1); |
41 | 41 |
(...skipping 27 matching lines...) Expand all Loading... |
69 if (UNLIKELY(barrierLocked)) { | 69 if (UNLIKELY(barrierLocked)) { |
70 m_resume.broadcast(); | 70 m_resume.broadcast(); |
71 } else { | 71 } else { |
72 // FIXME: Resumed threads will all contend for m_mutex just | 72 // FIXME: Resumed threads will all contend for m_mutex just |
73 // to unlock it later which is a waste of resources. | 73 // to unlock it later which is a waste of resources. |
74 MutexLocker locker(m_mutex); | 74 MutexLocker locker(m_mutex); |
75 m_resume.broadcast(); | 75 m_resume.broadcast(); |
76 } | 76 } |
77 | 77 |
78 current->unlockThreadAttachMutex(); | 78 current->unlockThreadAttachMutex(); |
79 ASSERT(ThreadState::current()->isAtSafePoint()); | 79 DCHECK(ThreadState::current()->isAtSafePoint()); |
80 } | 80 } |
81 | 81 |
82 void SafePointBarrier::checkAndPark(ThreadState* state, | 82 void SafePointBarrier::checkAndPark(ThreadState* state, |
83 SafePointAwareMutexLocker* locker) { | 83 SafePointAwareMutexLocker* locker) { |
84 ASSERT(!state->sweepForbidden()); | 84 DCHECK(!state->sweepForbidden()); |
85 if (acquireLoad(&m_parkingRequested)) { | 85 if (acquireLoad(&m_parkingRequested)) { |
86 // If we are leaving the safepoint from a SafePointAwareMutexLocker | 86 // If we are leaving the safepoint from a SafePointAwareMutexLocker |
87 // call out to release the lock before going to sleep. This enables the | 87 // call out to release the lock before going to sleep. This enables the |
88 // lock to be acquired in the sweep phase, e.g. during weak processing | 88 // lock to be acquired in the sweep phase, e.g. during weak processing |
89 // or finalization. The SafePointAwareLocker will reenter the safepoint | 89 // or finalization. The SafePointAwareLocker will reenter the safepoint |
90 // and reacquire the lock after leaving this safepoint. | 90 // and reacquire the lock after leaving this safepoint. |
91 if (locker) | 91 if (locker) |
92 locker->reset(); | 92 locker->reset(); |
93 pushAllRegisters(this, state, parkAfterPushRegisters); | 93 pushAllRegisters(this, state, parkAfterPushRegisters); |
94 } | 94 } |
95 } | 95 } |
96 | 96 |
97 void SafePointBarrier::enterSafePoint(ThreadState* state) { | 97 void SafePointBarrier::enterSafePoint(ThreadState* state) { |
98 ASSERT(!state->sweepForbidden()); | 98 DCHECK(!state->sweepForbidden()); |
99 pushAllRegisters(this, state, enterSafePointAfterPushRegisters); | 99 pushAllRegisters(this, state, enterSafePointAfterPushRegisters); |
100 } | 100 } |
101 | 101 |
102 void SafePointBarrier::leaveSafePoint(ThreadState* state, | 102 void SafePointBarrier::leaveSafePoint(ThreadState* state, |
103 SafePointAwareMutexLocker* locker) { | 103 SafePointAwareMutexLocker* locker) { |
104 if (atomicIncrement(&m_unparkedThreadCount) > 0) | 104 if (atomicIncrement(&m_unparkedThreadCount) > 0) |
105 checkAndPark(state, locker); | 105 checkAndPark(state, locker); |
106 } | 106 } |
107 | 107 |
108 void SafePointBarrier::doPark(ThreadState* state, intptr_t* stackEnd) { | 108 void SafePointBarrier::doPark(ThreadState* state, intptr_t* stackEnd) { |
(...skipping 10 matching lines...) Expand all Loading... |
119 intptr_t* stackEnd) { | 119 intptr_t* stackEnd) { |
120 state->recordStackEnd(stackEnd); | 120 state->recordStackEnd(stackEnd); |
121 state->copyStackUntilSafePointScope(); | 121 state->copyStackUntilSafePointScope(); |
122 if (!atomicDecrement(&m_unparkedThreadCount)) { | 122 if (!atomicDecrement(&m_unparkedThreadCount)) { |
123 MutexLocker locker(m_mutex); | 123 MutexLocker locker(m_mutex); |
124 m_parked.signal(); // Safe point reached. | 124 m_parked.signal(); // Safe point reached. |
125 } | 125 } |
126 } | 126 } |
127 | 127 |
128 } // namespace blink | 128 } // namespace blink |
OLD | NEW |