Line data Source code
1 : // Copyright 2012 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_V8THREADS_H_
6 : #define V8_V8THREADS_H_
7 :
8 : #include <atomic>
9 :
10 : #include "src/isolate.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 : class RootVisitor;
16 : class ThreadLocalTop;
17 :
18 : class ThreadState {
19 : public:
20 : // Returns nullptr after the last one.
21 : ThreadState* Next();
22 :
23 : enum List {FREE_LIST, IN_USE_LIST};
24 :
25 : void LinkInto(List list);
26 : void Unlink();
27 :
28 : // Id of thread.
29 68770 : void set_id(ThreadId id) { id_ = id; }
30 : ThreadId id() { return id_; }
31 :
32 : // Should the thread be terminated when it is restored?
33 : bool terminate_on_restore() { return terminate_on_restore_; }
34 : void set_terminate_on_restore(bool terminate_on_restore) {
35 0 : terminate_on_restore_ = terminate_on_restore;
36 : }
37 :
38 : // Get data area for archiving a thread.
39 : char* data() { return data_; }
40 :
41 : private:
42 : explicit ThreadState(ThreadManager* thread_manager);
43 : ~ThreadState();
44 :
45 : void AllocateSpace();
46 :
47 : ThreadId id_;
48 : bool terminate_on_restore_;
49 : char* data_;
50 : ThreadState* next_;
51 : ThreadState* previous_;
52 :
53 : ThreadManager* thread_manager_;
54 :
55 : friend class ThreadManager;
56 : };
57 :
58 81461 : class ThreadVisitor {
59 : public:
60 : // ThreadLocalTop may be only available during this call.
61 : virtual void VisitThread(Isolate* isolate, ThreadLocalTop* top) = 0;
62 :
63 : protected:
64 81461 : virtual ~ThreadVisitor() = default;
65 : };
66 :
67 : class ThreadManager {
68 : public:
69 : void Lock();
70 : void Unlock();
71 :
72 : void InitThread(const ExecutionAccess&);
73 : void ArchiveThread();
74 : bool RestoreThread();
75 : void FreeThreadResources();
76 : bool IsArchived();
77 :
78 : void Iterate(RootVisitor* v);
79 : void IterateArchivedThreads(ThreadVisitor* v);
80 : bool IsLockedByCurrentThread() const {
81 : return mutex_owner_.load(std::memory_order_relaxed) == ThreadId::Current();
82 : }
83 :
84 : ThreadId CurrentId();
85 :
86 : void TerminateExecution(ThreadId thread_id);
87 :
88 : // Iterate over in-use states.
89 : ThreadState* FirstThreadStateInUse();
90 : ThreadState* GetFreeThreadState();
91 :
92 : private:
93 : explicit ThreadManager(Isolate* isolate);
94 : ~ThreadManager();
95 :
96 : void DeleteThreadStateList(ThreadState* anchor);
97 :
98 : void EagerlyArchiveThread();
99 :
100 : base::Mutex mutex_;
101 : // {ThreadId} must be trivially copyable to be stored in {std::atomic}.
102 : ASSERT_TRIVIALLY_COPYABLE(i::ThreadId);
103 : std::atomic<ThreadId> mutex_owner_;
104 : ThreadId lazily_archived_thread_;
105 : ThreadState* lazily_archived_thread_state_;
106 :
107 : // In the following two lists there is always at least one object on the list.
108 : // The first object is a flying anchor that is only there to simplify linking
109 : // and unlinking.
110 : // Head of linked list of free states.
111 : ThreadState* free_anchor_;
112 : // Head of linked list of states in use.
113 : ThreadState* in_use_anchor_;
114 :
115 : Isolate* isolate_;
116 :
117 : friend class Isolate;
118 : friend class ThreadState;
119 : };
120 :
121 :
122 : } // namespace internal
123 : } // namespace v8
124 :
125 : #endif // V8_V8THREADS_H_
|