//===-- sanitizer_thread_registry.h -----------------------------*- C++ -*-===//
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is shared between sanitizer tools.
//
// General thread bookkeeping functionality.
//===----------------------------------------------------------------------===//

#ifndef SANITIZER_THREAD_REGISTRY_H
#define SANITIZER_THREAD_REGISTRY_H

#include "sanitizer_common.h"
#include "sanitizer_list.h"
#include "sanitizer_mutex.h"

namespace __sanitizer {

enum ThreadStatus {
  ThreadStatusInvalid,   // Non-existent thread, data is invalid.
  ThreadStatusCreated,   // Created but not yet running.
  ThreadStatusRunning,   // The thread is currently running.
  ThreadStatusFinished,  // Joinable thread is finished but not yet joined.
  ThreadStatusDead       // Joined, but some info is still available.
};

// Generic thread context. Specific sanitizer tools may inherit from it.
// If thread is dead, context may optionally be reused for a new thread.
class ThreadContextBase {
 public:
  explicit ThreadContextBase(u32 tid);
  ~ThreadContextBase();  // Should never be called.

  const u32 tid;  // Thread ID. Main thread should have tid = 0.
  u64 unique_id;  // Unique thread ID.
  u32 reuse_count;  // Number of times this tid was reused.
  tid_t os_id;     // PID (used for reporting).
  uptr user_id;   // Some opaque user thread id (e.g. pthread_t).
  char name[64];  // As annotated by user.

  ThreadStatus status;
  bool detached;
  bool workerthread;

  u32 parent_tid;
  ThreadContextBase *next;  // For storing thread contexts in a list.

  void SetName(const char *new_name);

  void SetDead();
  void SetJoined(void *arg);
  void SetFinished();
  void SetStarted(tid_t _os_id, bool _workerthread, void *arg);
  void SetCreated(uptr _user_id, u64 _unique_id, bool _detached,
                  u32 _parent_tid, void *arg);
  void Reset();

  // The following methods may be overriden by subclasses.
  // Some of them take opaque arg that may be optionally be used
  // by subclasses.
  virtual void OnDead() {}
  virtual void OnJoined(void *arg) {}
  virtual void OnFinished() {}
  virtual void OnStarted(void *arg) {}
  virtual void OnCreated(void *arg) {}
  virtual void OnReset() {}
  virtual void OnDetached(void *arg) {}
};

typedef ThreadContextBase* (*ThreadContextFactory)(u32 tid);

class ThreadRegistry {
 public:
  static const u32 kUnknownTid;

  ThreadRegistry(ThreadContextFactory factory, u32 max_threads,
                 u32 thread_quarantine_size, u32 max_reuse = 0);
  void GetNumberOfThreads(uptr *total = nullptr, uptr *running = nullptr,
                          uptr *alive = nullptr);
  uptr GetMaxAliveThreads();

  void Lock() { mtx_.Lock(); }
  void CheckLocked() { mtx_.CheckLocked(); }
  void Unlock() { mtx_.Unlock(); }

  // Should be guarded by ThreadRegistryLock.
  ThreadContextBase *GetThreadLocked(u32 tid) {
    DCHECK_LT(tid, n_contexts_);
    return threads_[tid];
  }

  u32 CreateThread(uptr user_id, bool detached, u32 parent_tid, void *arg);

  typedef void (*ThreadCallback)(ThreadContextBase *tctx, void *arg);
  // Invokes callback with a specified arg for each thread context.
  // Should be guarded by ThreadRegistryLock.
  void RunCallbackForEachThreadLocked(ThreadCallback cb, void *arg);

  typedef bool (*FindThreadCallback)(ThreadContextBase *tctx, void *arg);
  // Finds a thread using the provided callback. Returns kUnknownTid if no
  // thread is found.
  u32 FindThread(FindThreadCallback cb, void *arg);
  // Should be guarded by ThreadRegistryLock. Return 0 if no thread
  // is found.
  ThreadContextBase *FindThreadContextLocked(FindThreadCallback cb,
                                             void *arg);
  ThreadContextBase *FindThreadContextByOsIDLocked(tid_t os_id);

  void SetThreadName(u32 tid, const char *name);
  void SetThreadNameByUserId(uptr user_id, const char *name);
  void DetachThread(u32 tid, void *arg);
  void JoinThread(u32 tid, void *arg);
  void FinishThread(u32 tid);
  void StartThread(u32 tid, tid_t os_id, bool workerthread, void *arg);

 private:
  const ThreadContextFactory context_factory_;
  const u32 max_threads_;
  const u32 thread_quarantine_size_;
  const u32 max_reuse_;

  BlockingMutex mtx_;

  u32 n_contexts_;      // Number of created thread contexts,
                        // at most max_threads_.
  u64 total_threads_;   // Total number of created threads. May be greater than
                        // max_threads_ if contexts were reused.
  uptr alive_threads_;  // Created or running.
  uptr max_alive_threads_;
  uptr running_threads_;

  ThreadContextBase **threads_;  // Array of thread contexts is leaked.
  IntrusiveList<ThreadContextBase> dead_threads_;
  IntrusiveList<ThreadContextBase> invalid_threads_;

  void QuarantinePush(ThreadContextBase *tctx);
  ThreadContextBase *QuarantinePop();
};

typedef GenericScopedLock<ThreadRegistry> ThreadRegistryLock;

} // namespace __sanitizer

#endif // SANITIZER_THREAD_REGISTRY_H
