Skip to content

Commit 24721a4

Browse files
[WTF] Implement WTF::ThreadGroup
https://bugs.webkit.org/show_bug.cgi?id=174081 Reviewed by Mark Lam. Source/JavaScriptCore: Large part of MachineThreads are now removed and replaced with WTF::ThreadGroup. And SamplingProfiler and others interact with WTF::Thread directly. * API/tests/ExecutionTimeLimitTest.cpp: * heap/MachineStackMarker.cpp: (JSC::MachineThreads::MachineThreads): (JSC::captureStack): (JSC::MachineThreads::tryCopyOtherThreadStack): (JSC::MachineThreads::tryCopyOtherThreadStacks): (JSC::MachineThreads::gatherConservativeRoots): (JSC::ActiveMachineThreadsManager::Locker::Locker): Deleted. (JSC::ActiveMachineThreadsManager::add): Deleted. (JSC::ActiveMachineThreadsManager::remove): Deleted. (JSC::ActiveMachineThreadsManager::contains): Deleted. (JSC::ActiveMachineThreadsManager::ActiveMachineThreadsManager): Deleted. (JSC::activeMachineThreadsManager): Deleted. (JSC::MachineThreads::~MachineThreads): Deleted. (JSC::MachineThreads::addCurrentThread): Deleted. (): Deleted. (JSC::MachineThreads::removeThread): Deleted. (JSC::MachineThreads::removeThreadIfFound): Deleted. (JSC::MachineThreads::MachineThread::MachineThread): Deleted. (JSC::MachineThreads::MachineThread::getRegisters): Deleted. (JSC::MachineThreads::MachineThread::Registers::stackPointer): Deleted. (JSC::MachineThreads::MachineThread::Registers::framePointer): Deleted. (JSC::MachineThreads::MachineThread::Registers::instructionPointer): Deleted. (JSC::MachineThreads::MachineThread::Registers::llintPC): Deleted. (JSC::MachineThreads::MachineThread::captureStack): Deleted. * heap/MachineStackMarker.h: (JSC::MachineThreads::addCurrentThread): (JSC::MachineThreads::getLock): (JSC::MachineThreads::threads): (JSC::MachineThreads::MachineThread::suspend): Deleted. (JSC::MachineThreads::MachineThread::resume): Deleted. (JSC::MachineThreads::MachineThread::threadID): Deleted. (JSC::MachineThreads::MachineThread::stackBase): Deleted. (JSC::MachineThreads::MachineThread::stackEnd): Deleted. (JSC::MachineThreads::threadsListHead): Deleted. * runtime/SamplingProfiler.cpp: (JSC::FrameWalker::isValidFramePointer): (JSC::SamplingProfiler::SamplingProfiler): (JSC::SamplingProfiler::takeSample): (JSC::SamplingProfiler::noticeCurrentThreadAsJSCExecutionThread): * runtime/SamplingProfiler.h: * wasm/WasmMachineThreads.cpp: (JSC::Wasm::resetInstructionCacheOnAllThreads): Source/WebCore: * page/ResourceUsageThread.h: Source/WebKit2: * Shared/AsyncRequest.h: * UIProcess/Storage/ResourceLoadStatisticsStore.h: Source/WTF: This patch implements WTF::ThreadGroup. It implements core of JSC::MachineThreads with more reliable way. JSC::MachineThreads was complicated because of managing dead threads. Each JSC::MachineThreads has its own TLS with a registered destructor. And everytime a thread dies, the registered TLS destructor is called. And this destructor will remove the current dying thread from JSC::MachineThreads. However the above implementation is tricky. And each JSC::MachineThreads requires own TLS space, which is not considered in WTF's Windows ThreadSpecific implementation. Current design works well since we only have small number of MachineThreads right now. Instead, we use more reliable way. After introducing WTF::Thread, WTF::Thread has WTF::Thread::didExit, which is called when associated TLS (with WTF::Thread) is destroyed. We leverage this mechanism to remove WTF::Thread from MachineThreads. This patch introduces WTF::ThreadGroup. It is tightly integrated with WTF::Thread: WTF::Thread knows ThreadGroups which includes this thread. And WTF::ThreadGroup of course knows WTF::Threads added to it. WTF::Thread::didExit carefully remove itself from WTF::ThreadGroups. The most important part of this patch is locking. WTF::Thread can die. And WTF::ThreadGroup can die. If we take a design using two fine grain locks in WTF::Thread and WTF::ThreadGroup, we easily encounter dead lock. Consider the following case. 1. When adding WTF::Thread (TH) to WTF::ThreadGroup (THG), we first hold a lock of THG, and hold a lock of TH (locking order is THG -> TH). 2. When TH dies, TH need to hold a lock of TH to iterate THGs. And we hold a lock of THG to unregister TH from it (locking order is TH -> THG). 3. When suspending and resuming THs in THG, we first hold a lock of THG. And then, we hold a lock of TH to suspend and resume it (locking order is THG -> TH). 4. When destroying THG, we need to hold a lock of TH to unregister THG from TH. We can hold a lock of THG before that (locking order is THG -> TH). Then, it easily causes dead lock. We cannot swap the locking order of (2) since iterating THG requires a lock of TH. To solve this problem, we introduce one global lock ThreadGroup::destructionMutex (GL). 1. When adding WTF::Thread (TH) to WTF::ThreadGroup (THG), we first hold GL, and hold a lock of THG. Do not hold a lock of TH. TH's thread groups information is guarded by GL instead of a lock of TH (locking order is GL -> THG). 2. When TH dies, TH need to hold GL to iterate THGs. And we hold a lock of THG to unregister TH from it (locking order is GL -> THG). 3. When suspending and resuming THs in THG, we first hold a lock of THG. And then, we hold a lock of TH to suspend and resume it (locking order is THG -> TH). 4. When destroying THG, we need to hold GL to unregister THG from TH. We can hold a lock of THG after that (locking order is GL -> THG). We still have a lock of THG. By separating GL and THG's lock, we can hold a lock of THG while completely unrelated TH is destructed which takes a lock of GL and unrelated THG. * WTF.xcodeproj/project.pbxproj: * wtf/AutomaticThread.cpp: * wtf/CMakeLists.txt: * wtf/CrossThreadCopier.h: * wtf/ParkingLot.h: * wtf/ThreadGroup.cpp: Copied from Source/JavaScriptCore/wasm/WasmMachineThreads.cpp. (WTF::ThreadGroup::destructionMutex): (WTF::ThreadGroup::~ThreadGroup): (WTF::ThreadGroup::add): (WTF::ThreadGroup::addCurrentThread): (WTF::ThreadGroup::removeCurrentThread): * wtf/ThreadGroup.h: Copied from Source/JavaScriptCore/wasm/WasmMachineThreads.cpp. (WTF::ThreadGroup::create): (WTF::ThreadGroup::threads): (WTF::ThreadGroup::getLock): * wtf/Threading.cpp: (WTF::Thread::didExit): (WTF::Thread::addToThreadGroup): (WTF::Thread::removeFromThreadGroup): * wtf/Threading.h: (WTF::Thread::canAddToThreadGroup): Tools: Add WTF::ThreadGroup tests. * TestWebKitAPI/CMakeLists.txt: * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WTF/ThreadGroup.cpp: Added. (TestWebKitAPI::TEST): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@219238 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent c4579a0 commit 24721a4

26 files changed

+569
-355
lines changed

Source/JavaScriptCore/API/tests/ExecutionTimeLimitTest.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <wtf/Condition.h>
3737
#include <wtf/CurrentTime.h>
3838
#include <wtf/Lock.h>
39+
#include <wtf/Threading.h>
3940
#include <wtf/text/StringBuilder.h>
4041

4142
#if HAVE(MACH_EXCEPTIONS)

Source/JavaScriptCore/ChangeLog

+54
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,57 @@
1+
2017-07-05 Yusuke Suzuki <[email protected]>
2+
3+
[WTF] Implement WTF::ThreadGroup
4+
https://bugs.webkit.org/show_bug.cgi?id=174081
5+
6+
Reviewed by Mark Lam.
7+
8+
Large part of MachineThreads are now removed and replaced with WTF::ThreadGroup.
9+
And SamplingProfiler and others interact with WTF::Thread directly.
10+
11+
* API/tests/ExecutionTimeLimitTest.cpp:
12+
* heap/MachineStackMarker.cpp:
13+
(JSC::MachineThreads::MachineThreads):
14+
(JSC::captureStack):
15+
(JSC::MachineThreads::tryCopyOtherThreadStack):
16+
(JSC::MachineThreads::tryCopyOtherThreadStacks):
17+
(JSC::MachineThreads::gatherConservativeRoots):
18+
(JSC::ActiveMachineThreadsManager::Locker::Locker): Deleted.
19+
(JSC::ActiveMachineThreadsManager::add): Deleted.
20+
(JSC::ActiveMachineThreadsManager::remove): Deleted.
21+
(JSC::ActiveMachineThreadsManager::contains): Deleted.
22+
(JSC::ActiveMachineThreadsManager::ActiveMachineThreadsManager): Deleted.
23+
(JSC::activeMachineThreadsManager): Deleted.
24+
(JSC::MachineThreads::~MachineThreads): Deleted.
25+
(JSC::MachineThreads::addCurrentThread): Deleted.
26+
(): Deleted.
27+
(JSC::MachineThreads::removeThread): Deleted.
28+
(JSC::MachineThreads::removeThreadIfFound): Deleted.
29+
(JSC::MachineThreads::MachineThread::MachineThread): Deleted.
30+
(JSC::MachineThreads::MachineThread::getRegisters): Deleted.
31+
(JSC::MachineThreads::MachineThread::Registers::stackPointer): Deleted.
32+
(JSC::MachineThreads::MachineThread::Registers::framePointer): Deleted.
33+
(JSC::MachineThreads::MachineThread::Registers::instructionPointer): Deleted.
34+
(JSC::MachineThreads::MachineThread::Registers::llintPC): Deleted.
35+
(JSC::MachineThreads::MachineThread::captureStack): Deleted.
36+
* heap/MachineStackMarker.h:
37+
(JSC::MachineThreads::addCurrentThread):
38+
(JSC::MachineThreads::getLock):
39+
(JSC::MachineThreads::threads):
40+
(JSC::MachineThreads::MachineThread::suspend): Deleted.
41+
(JSC::MachineThreads::MachineThread::resume): Deleted.
42+
(JSC::MachineThreads::MachineThread::threadID): Deleted.
43+
(JSC::MachineThreads::MachineThread::stackBase): Deleted.
44+
(JSC::MachineThreads::MachineThread::stackEnd): Deleted.
45+
(JSC::MachineThreads::threadsListHead): Deleted.
46+
* runtime/SamplingProfiler.cpp:
47+
(JSC::FrameWalker::isValidFramePointer):
48+
(JSC::SamplingProfiler::SamplingProfiler):
49+
(JSC::SamplingProfiler::takeSample):
50+
(JSC::SamplingProfiler::noticeCurrentThreadAsJSCExecutionThread):
51+
* runtime/SamplingProfiler.h:
52+
* wasm/WasmMachineThreads.cpp:
53+
(JSC::Wasm::resetInstructionCacheOnAllThreads):
54+
155
2017-07-06 Saam Barati <[email protected]>
256

357
We are missing places where we invalidate the for-in context

0 commit comments

Comments
 (0)