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 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