• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_EXECUTION_V8THREADS_H_
6 #define V8_EXECUTION_V8THREADS_H_
7 
8 #include <atomic>
9 
10 #include "src/execution/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.
set_id(ThreadId id)29   void set_id(ThreadId id) { id_ = id; }
id()30   ThreadId id() { return id_; }
31 
32   // Get data area for archiving a thread.
data()33   char* data() { return data_; }
34 
35  private:
36   explicit ThreadState(ThreadManager* thread_manager);
37   ~ThreadState();
38 
39   void AllocateSpace();
40 
41   ThreadId id_;
42   char* data_;
43   ThreadState* next_;
44   ThreadState* previous_;
45 
46   ThreadManager* thread_manager_;
47 
48   friend class ThreadManager;
49 };
50 
51 class ThreadVisitor {
52  public:
53   // ThreadLocalTop may be only available during this call.
54   virtual void VisitThread(Isolate* isolate, ThreadLocalTop* top) = 0;
55 
56  protected:
57   virtual ~ThreadVisitor() = default;
58 };
59 
60 class ThreadManager {
61  public:
62   void Lock();
63   V8_EXPORT_PRIVATE void Unlock();
64 
65   void InitThread(const ExecutionAccess&);
66   void ArchiveThread();
67   bool RestoreThread();
68   void FreeThreadResources();
69   bool IsArchived();
70 
71   void Iterate(RootVisitor* v);
72   void IterateArchivedThreads(ThreadVisitor* v);
IsLockedByCurrentThread()73   bool IsLockedByCurrentThread() const {
74     return mutex_owner_.load(std::memory_order_relaxed) == ThreadId::Current();
75   }
IsLockedByThread(ThreadId id)76   bool IsLockedByThread(ThreadId id) const {
77     return mutex_owner_.load(std::memory_order_relaxed) == id;
78   }
79 
80   ThreadId CurrentId();
81 
82   // Iterate over in-use states.
83   ThreadState* FirstThreadStateInUse();
84   ThreadState* GetFreeThreadState();
85 
86  private:
87   explicit ThreadManager(Isolate* isolate);
88   ~ThreadManager();
89 
90   void DeleteThreadStateList(ThreadState* anchor);
91 
92   void EagerlyArchiveThread();
93 
94   base::Mutex mutex_;
95   // {ThreadId} must be trivially copyable to be stored in {std::atomic}.
96   ASSERT_TRIVIALLY_COPYABLE(i::ThreadId);
97   std::atomic<ThreadId> mutex_owner_;
98   ThreadId lazily_archived_thread_;
99   ThreadState* lazily_archived_thread_state_;
100 
101   // In the following two lists there is always at least one object on the list.
102   // The first object is a flying anchor that is only there to simplify linking
103   // and unlinking.
104   // Head of linked list of free states.
105   ThreadState* free_anchor_;
106   // Head of linked list of states in use.
107   ThreadState* in_use_anchor_;
108 
109   Isolate* isolate_;
110 
111   friend class Isolate;
112   friend class ThreadState;
113 };
114 
115 }  // namespace internal
116 }  // namespace v8
117 
118 #endif  // V8_EXECUTION_V8THREADS_H_
119