// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#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:
  // Returns nullptr after the last one.
  ThreadState* Next();

  enum List { FREE_LIST, IN_USE_LIST };

  void LinkInto(List list);
  void Unlink();

  // Id of thread.
  void set_id(ThreadId id) { id_ = id; }
  ThreadId id() { return id_; }

  // Get data area for archiving a thread.
  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:
  // ThreadLocalTop may be only available during this call.
  virtual void VisitThread(Isolate* isolate, ThreadLocalTop* top) = 0;

 protected:
  virtual ~ThreadVisitor() = default;
};

class ThreadManager {
 public:
  void Lock();
  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();
  }

  ThreadId CurrentId();

  // Iterate over in-use states.
  ThreadState* FirstThreadStateInUse();
  ThreadState* GetFreeThreadState();

 private:
  explicit ThreadManager(Isolate* isolate);
  ~ThreadManager();

  void DeleteThreadStateList(ThreadState* anchor);

  void EagerlyArchiveThread();

  base::Mutex mutex_;
  // {ThreadId} must be trivially copyable to be stored in {std::atomic}.
  ASSERT_TRIVIALLY_COPYABLE(i::ThreadId);
  std::atomic<ThreadId> mutex_owner_;
  ThreadId lazily_archived_thread_;
  ThreadState* lazily_archived_thread_state_;

  // In the following two lists there is always at least one object on the list.
  // The first object is a flying anchor that is only there to simplify linking
  // and unlinking.
  // Head of linked list of free states.
  ThreadState* free_anchor_;
  // Head of linked list of states in use.
  ThreadState* in_use_anchor_;

  Isolate* isolate_;

  friend class Isolate;
  friend class ThreadState;
};

}  // namespace internal
}  // namespace v8

#endif  // V8_EXECUTION_V8THREADS_H_
