//=-- lsan_thread.cc ------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is a part of LeakSanitizer.
// See lsan_thread.h for details.
//
//===----------------------------------------------------------------------===//

#include "lsan_thread.h"

#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_placement_new.h"
#include "sanitizer_common/sanitizer_thread_registry.h"
#include "sanitizer_common/sanitizer_tls_get_addr.h"
#include "lsan_allocator.h"

namespace __lsan {

const u32 kInvalidTid = (u32) -1;

static ThreadRegistry *thread_registry;
static THREADLOCAL u32 current_thread_tid = kInvalidTid;

static ThreadContextBase *CreateThreadContext(u32 tid) {
  void *mem = MmapOrDie(sizeof(ThreadContext), "ThreadContext");
  return new(mem) ThreadContext(tid);
}

static const uptr kMaxThreads = 1 << 13;
static const uptr kThreadQuarantineSize = 64;

void InitializeThreadRegistry() {
  static ALIGNED(64) char thread_registry_placeholder[sizeof(ThreadRegistry)];
  thread_registry = new(thread_registry_placeholder)
    ThreadRegistry(CreateThreadContext, kMaxThreads, kThreadQuarantineSize);
}

u32 GetCurrentThread() {
  return current_thread_tid;
}

void SetCurrentThread(u32 tid) {
  current_thread_tid = tid;
}

ThreadContext::ThreadContext(int tid)
    : ThreadContextBase(tid),
      stack_begin_(0),
      stack_end_(0),
      cache_begin_(0),
      cache_end_(0),
      tls_begin_(0),
      tls_end_(0),
      dtls_(nullptr) {}

struct OnStartedArgs {
  uptr stack_begin, stack_end,
       cache_begin, cache_end,
       tls_begin, tls_end;
  DTLS *dtls;
};

void ThreadContext::OnStarted(void *arg) {
  OnStartedArgs *args = reinterpret_cast<OnStartedArgs *>(arg);
  stack_begin_ = args->stack_begin;
  stack_end_ = args->stack_end;
  tls_begin_ = args->tls_begin;
  tls_end_ = args->tls_end;
  cache_begin_ = args->cache_begin;
  cache_end_ = args->cache_end;
  dtls_ = args->dtls;
}

void ThreadContext::OnFinished() {
  AllocatorThreadFinish();
  DTLS_Destroy();
}

u32 ThreadCreate(u32 parent_tid, uptr user_id, bool detached) {
  return thread_registry->CreateThread(user_id, detached, parent_tid,
                                       /* arg */ nullptr);
}

void ThreadStart(u32 tid, uptr os_id) {
  OnStartedArgs args;
  uptr stack_size = 0;
  uptr tls_size = 0;
  GetThreadStackAndTls(tid == 0, &args.stack_begin, &stack_size,
                       &args.tls_begin, &tls_size);
  args.stack_end = args.stack_begin + stack_size;
  args.tls_end = args.tls_begin + tls_size;
  GetAllocatorCacheRange(&args.cache_begin, &args.cache_end);
  args.dtls = DTLS_Get();
  thread_registry->StartThread(tid, os_id, /*workerthread*/ false, &args);
}

void ThreadFinish() {
  thread_registry->FinishThread(GetCurrentThread());
}

ThreadContext *CurrentThreadContext() {
  if (!thread_registry) return nullptr;
  if (GetCurrentThread() == kInvalidTid)
    return nullptr;
  // No lock needed when getting current thread.
  return (ThreadContext *)thread_registry->GetThreadLocked(GetCurrentThread());
}

static bool FindThreadByUid(ThreadContextBase *tctx, void *arg) {
  uptr uid = (uptr)arg;
  if (tctx->user_id == uid && tctx->status != ThreadStatusInvalid) {
    return true;
  }
  return false;
}

u32 ThreadTid(uptr uid) {
  return thread_registry->FindThread(FindThreadByUid, (void*)uid);
}

void ThreadJoin(u32 tid) {
  CHECK_NE(tid, kInvalidTid);
  thread_registry->JoinThread(tid, /* arg */nullptr);
}

void EnsureMainThreadIDIsCorrect() {
  if (GetCurrentThread() == 0)
    CurrentThreadContext()->os_id = GetTid();
}

///// Interface to the common LSan module. /////

bool GetThreadRangesLocked(uptr os_id, uptr *stack_begin, uptr *stack_end,
                           uptr *tls_begin, uptr *tls_end, uptr *cache_begin,
                           uptr *cache_end, DTLS **dtls) {
  ThreadContext *context = static_cast<ThreadContext *>(
      thread_registry->FindThreadContextByOsIDLocked(os_id));
  if (!context) return false;
  *stack_begin = context->stack_begin();
  *stack_end = context->stack_end();
  *tls_begin = context->tls_begin();
  *tls_end = context->tls_end();
  *cache_begin = context->cache_begin();
  *cache_end = context->cache_end();
  *dtls = context->dtls();
  return true;
}

void ForEachExtraStackRange(uptr os_id, RangeIteratorCallback callback,
                            void *arg) {
}

void LockThreadRegistry() {
  thread_registry->Lock();
}

void UnlockThreadRegistry() {
  thread_registry->Unlock();
}

} // namespace __lsan
