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
12namespace v8 {
13namespace internal {
14
15class RootVisitor;
16class ThreadLocalTop;
17
18class 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 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 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
58class 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 virtual ~ThreadVisitor() = default;
65};
66
67class 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_
126