11cb0ef41Sopenharmony_ci// Copyright 2012 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_EXECUTION_V8THREADS_H_ 61cb0ef41Sopenharmony_ci#define V8_EXECUTION_V8THREADS_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <atomic> 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include "src/execution/isolate.h" 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_cinamespace v8 { 131cb0ef41Sopenharmony_cinamespace internal { 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ciclass RootVisitor; 161cb0ef41Sopenharmony_ciclass ThreadLocalTop; 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ciclass ThreadState { 191cb0ef41Sopenharmony_ci public: 201cb0ef41Sopenharmony_ci // Returns nullptr after the last one. 211cb0ef41Sopenharmony_ci ThreadState* Next(); 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ci enum List { FREE_LIST, IN_USE_LIST }; 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ci void LinkInto(List list); 261cb0ef41Sopenharmony_ci void Unlink(); 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci // Id of thread. 291cb0ef41Sopenharmony_ci void set_id(ThreadId id) { id_ = id; } 301cb0ef41Sopenharmony_ci ThreadId id() { return id_; } 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci // Get data area for archiving a thread. 331cb0ef41Sopenharmony_ci char* data() { return data_; } 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci private: 361cb0ef41Sopenharmony_ci explicit ThreadState(ThreadManager* thread_manager); 371cb0ef41Sopenharmony_ci ~ThreadState(); 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci void AllocateSpace(); 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci ThreadId id_; 421cb0ef41Sopenharmony_ci char* data_; 431cb0ef41Sopenharmony_ci ThreadState* next_; 441cb0ef41Sopenharmony_ci ThreadState* previous_; 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci ThreadManager* thread_manager_; 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ci friend class ThreadManager; 491cb0ef41Sopenharmony_ci}; 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ciclass ThreadVisitor { 521cb0ef41Sopenharmony_ci public: 531cb0ef41Sopenharmony_ci // ThreadLocalTop may be only available during this call. 541cb0ef41Sopenharmony_ci virtual void VisitThread(Isolate* isolate, ThreadLocalTop* top) = 0; 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci protected: 571cb0ef41Sopenharmony_ci virtual ~ThreadVisitor() = default; 581cb0ef41Sopenharmony_ci}; 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ciclass ThreadManager { 611cb0ef41Sopenharmony_ci public: 621cb0ef41Sopenharmony_ci void Lock(); 631cb0ef41Sopenharmony_ci V8_EXPORT_PRIVATE void Unlock(); 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci void InitThread(const ExecutionAccess&); 661cb0ef41Sopenharmony_ci void ArchiveThread(); 671cb0ef41Sopenharmony_ci bool RestoreThread(); 681cb0ef41Sopenharmony_ci void FreeThreadResources(); 691cb0ef41Sopenharmony_ci bool IsArchived(); 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci void Iterate(RootVisitor* v); 721cb0ef41Sopenharmony_ci void IterateArchivedThreads(ThreadVisitor* v); 731cb0ef41Sopenharmony_ci bool IsLockedByCurrentThread() const { 741cb0ef41Sopenharmony_ci return mutex_owner_.load(std::memory_order_relaxed) == ThreadId::Current(); 751cb0ef41Sopenharmony_ci } 761cb0ef41Sopenharmony_ci bool IsLockedByThread(ThreadId id) const { 771cb0ef41Sopenharmony_ci return mutex_owner_.load(std::memory_order_relaxed) == id; 781cb0ef41Sopenharmony_ci } 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci ThreadId CurrentId(); 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci // Iterate over in-use states. 831cb0ef41Sopenharmony_ci ThreadState* FirstThreadStateInUse(); 841cb0ef41Sopenharmony_ci ThreadState* GetFreeThreadState(); 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci private: 871cb0ef41Sopenharmony_ci explicit ThreadManager(Isolate* isolate); 881cb0ef41Sopenharmony_ci ~ThreadManager(); 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci void DeleteThreadStateList(ThreadState* anchor); 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci void EagerlyArchiveThread(); 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci base::Mutex mutex_; 951cb0ef41Sopenharmony_ci // {ThreadId} must be trivially copyable to be stored in {std::atomic}. 961cb0ef41Sopenharmony_ci ASSERT_TRIVIALLY_COPYABLE(i::ThreadId); 971cb0ef41Sopenharmony_ci std::atomic<ThreadId> mutex_owner_; 981cb0ef41Sopenharmony_ci ThreadId lazily_archived_thread_; 991cb0ef41Sopenharmony_ci ThreadState* lazily_archived_thread_state_; 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci // In the following two lists there is always at least one object on the list. 1021cb0ef41Sopenharmony_ci // The first object is a flying anchor that is only there to simplify linking 1031cb0ef41Sopenharmony_ci // and unlinking. 1041cb0ef41Sopenharmony_ci // Head of linked list of free states. 1051cb0ef41Sopenharmony_ci ThreadState* free_anchor_; 1061cb0ef41Sopenharmony_ci // Head of linked list of states in use. 1071cb0ef41Sopenharmony_ci ThreadState* in_use_anchor_; 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci Isolate* isolate_; 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci friend class Isolate; 1121cb0ef41Sopenharmony_ci friend class ThreadState; 1131cb0ef41Sopenharmony_ci}; 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci} // namespace internal 1161cb0ef41Sopenharmony_ci} // namespace v8 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_ci#endif // V8_EXECUTION_V8THREADS_H_ 119