#ifndef V8_EXECUTION_V8THREADS_H_
#define V8_EXECUTION_V8THREADS_H_
#include <atomic>
#include "src/execution/isolate.h"
namespace v8 {
namespace internal {
class RootVisitor;
class ThreadLocalTop;
class ThreadState {
public:
ThreadState* Next();
enum List { FREE_LIST, IN_USE_LIST };
void LinkInto(List list);
void Unlink();
void set_id(ThreadId id) { id_ = id; }
ThreadId id() { return id_; }
char* data() { return data_; }
private:
explicit ThreadState(ThreadManager* thread_manager);
~ThreadState();
void AllocateSpace();
ThreadId id_;
char* data_;
ThreadState* next_;
ThreadState* previous_;
ThreadManager* thread_manager_;
friend class ThreadManager;
};
class ThreadVisitor {
public:
virtual void VisitThread(Isolate* isolate, ThreadLocalTop* top) = 0;
protected:
virtual ~ThreadVisitor() = default;
};
class ThreadManager {
public:
void Lock();
V8_EXPORT_PRIVATE void Unlock();
void InitThread(const ExecutionAccess&);
void ArchiveThread();
bool RestoreThread();
void FreeThreadResources();
bool IsArchived();
void Iterate(RootVisitor* v);
void IterateArchivedThreads(ThreadVisitor* v);
bool IsLockedByCurrentThread() const {
return mutex_owner_.load(std::memory_order_relaxed) == ThreadId::Current();
}
bool IsLockedByThread(ThreadId id) const {
return mutex_owner_.load(std::memory_order_relaxed) == id;
}
ThreadId CurrentId();
ThreadState* FirstThreadStateInUse();
ThreadState* GetFreeThreadState();
private:
explicit ThreadManager(Isolate* isolate);
~ThreadManager();
void DeleteThreadStateList(ThreadState* anchor);
void EagerlyArchiveThread();
base::Mutex mutex_;
ASSERT_TRIVIALLY_COPYABLE(i::ThreadId);
std::atomic<ThreadId> mutex_owner_;
ThreadId lazily_archived_thread_;
ThreadState* lazily_archived_thread_state_;
ThreadState* free_anchor_;
ThreadState* in_use_anchor_;
Isolate* isolate_;
friend class Isolate;
friend class ThreadState;
};
}
}
#endif