//===-- tsan_rtl_mutex.cpp ------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of ThreadSanitizer (TSan), a race detector.
//
//===----------------------------------------------------------------------===//

#include <sanitizer_common/sanitizer_deadlock_detector_interface.h>
#include <sanitizer_common/sanitizer_stackdepot.h>

#include "tsan_rtl.h"
#include "tsan_flags.h"
#include "tsan_sync.h"
#include "tsan_report.h"
#include "tsan_symbolize.h"
#include "tsan_platform.h"

namespace __tsan {

void ReportDeadlock(ThreadState *thr, uptr pc, DDReport *r);
void ReportDestroyLocked(ThreadState *thr, uptr pc, uptr addr,
                         FastState last_lock, StackID creation_stack_id);

struct Callback final : public DDCallback {
  ThreadState *thr;
  uptr pc;

  Callback(ThreadState *thr, uptr pc)
      : thr(thr)
      , pc(pc) {
    DDCallback::pt = thr->proc()->dd_pt;
    DDCallback::lt = thr->dd_lt;
  }

  StackID Unwind() override { return CurrentStackId(thr, pc); }
  int UniqueTid() override { return thr->tid; }
};

void DDMutexInit(ThreadState *thr, uptr pc, SyncVar *s) {
  Callback cb(thr, pc);
  ctx->dd->MutexInit(&cb, &s->dd);
  s->dd.ctx = s->addr;
}

static void ReportMutexMisuse(ThreadState *thr, uptr pc, ReportType typ,
                              uptr addr, StackID creation_stack_id) {
  // In Go, these misuses are either impossible, or detected by std lib,
  // or false positives (e.g. unlock in a different thread).
  if (SANITIZER_GO)
    return;
  if (!ShouldReport(thr, typ))
    return;
  ThreadRegistryLock l(&ctx->thread_registry);
  ScopedReport rep(typ);
  rep.AddMutex(addr, creation_stack_id);
  VarSizeStackTrace trace;
  ObtainCurrentStack(thr, pc, &trace);
  rep.AddStack(trace, true);
  rep.AddLocation(addr, 1);
  OutputReport(thr, rep);
}

static void RecordMutexLock(ThreadState *thr, uptr pc, uptr addr,
                            StackID stack_id, bool write) {
  auto typ = write ? EventType::kLock : EventType::kRLock;
  // Note: it's important to trace before modifying mutex set
  // because tracing can switch trace part and we write the current
  // mutex set in the beginning of each part.
  // If we do it in the opposite order, we will write already reduced
  // mutex set in the beginning of the part and then trace unlock again.
  TraceMutexLock(thr, typ, pc, addr, stack_id);
  thr->mset.AddAddr(addr, stack_id, write);
}

static void RecordMutexUnlock(ThreadState *thr, uptr addr) {
  // See the comment in RecordMutexLock re order of operations.
  TraceMutexUnlock(thr, addr);
  thr->mset.DelAddr(addr);
}

void MutexCreate(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
  DPrintf("#%d: MutexCreate %zx flagz=0x%x\n", thr->tid, addr, flagz);
  if (!(flagz & MutexFlagLinkerInit) && pc && IsAppMem(addr))
    MemoryAccess(thr, pc, addr, 1, kAccessWrite);
  SlotLocker locker(thr);
  auto s = ctx->metamap.GetSyncOrCreate(thr, pc, addr, true);
  s->SetFlags(flagz & MutexCreationFlagMask);
  // Save stack in the case the sync object was created before as atomic.
  if (!SANITIZER_GO && s->creation_stack_id == kInvalidStackID)
    s->creation_stack_id = CurrentStackId(thr, pc);
}

void MutexDestroy(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
  DPrintf("#%d: MutexDestroy %zx\n", thr->tid, addr);
  bool unlock_locked = false;
  StackID creation_stack_id;
  FastState last_lock;
  {
    auto s = ctx->metamap.GetSyncIfExists(addr);
    if (!s)
      return;
    SlotLocker locker(thr);
    {
      Lock lock(&s->mtx);
      creation_stack_id = s->creation_stack_id;
      last_lock = s->last_lock;
      if ((flagz & MutexFlagLinkerInit) || s->IsFlagSet(MutexFlagLinkerInit) ||
          ((flagz & MutexFlagNotStatic) && !s->IsFlagSet(MutexFlagNotStatic))) {
        // Destroy is no-op for linker-initialized mutexes.
        return;
      }
      if (common_flags()->detect_deadlocks) {
        Callback cb(thr, pc);
        ctx->dd->MutexDestroy(&cb, &s->dd);
        ctx->dd->MutexInit(&cb, &s->dd);
      }
      if (flags()->report_destroy_locked && s->owner_tid != kInvalidTid &&
          !s->IsFlagSet(MutexFlagBroken)) {
        s->SetFlags(MutexFlagBroken);
        unlock_locked = true;
      }
      s->Reset();
    }
    // Imitate a memory write to catch unlock-destroy races.
    if (pc && IsAppMem(addr))
      MemoryAccess(thr, pc, addr, 1, kAccessWrite | kAccessFree);
  }
  if (unlock_locked && ShouldReport(thr, ReportTypeMutexDestroyLocked))
    ReportDestroyLocked(thr, pc, addr, last_lock, creation_stack_id);
  thr->mset.DelAddr(addr, true);
  // s will be destroyed and freed in MetaMap::FreeBlock.
}

void MutexPreLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
  DPrintf("#%d: MutexPreLock %zx flagz=0x%x\n", thr->tid, addr, flagz);
  if (flagz & MutexFlagTryLock)
    return;
  if (!common_flags()->detect_deadlocks)
    return;
  Callback cb(thr, pc);
  {
    SlotLocker locker(thr);
    auto s = ctx->metamap.GetSyncOrCreate(thr, pc, addr, true);
    ReadLock lock(&s->mtx);
    s->UpdateFlags(flagz);
    if (s->owner_tid != thr->tid)
      ctx->dd->MutexBeforeLock(&cb, &s->dd, true);
  }
  ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));
}

void MutexPostLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz, int rec) {
  DPrintf("#%d: MutexPostLock %zx flag=0x%x rec=%d\n",
      thr->tid, addr, flagz, rec);
  if (flagz & MutexFlagRecursiveLock)
    CHECK_GT(rec, 0);
  else
    rec = 1;
  if (pc && IsAppMem(addr))
    MemoryAccess(thr, pc, addr, 1, kAccessRead | kAccessAtomic);
  bool report_double_lock = false;
  bool pre_lock = false;
  bool first = false;
  StackID creation_stack_id = kInvalidStackID;
  {
    SlotLocker locker(thr);
    auto s = ctx->metamap.GetSyncOrCreate(thr, pc, addr, true);
    creation_stack_id = s->creation_stack_id;
    RecordMutexLock(thr, pc, addr, creation_stack_id, true);
    {
      Lock lock(&s->mtx);
      first = s->recursion == 0;
      s->UpdateFlags(flagz);
      if (s->owner_tid == kInvalidTid) {
        CHECK_EQ(s->recursion, 0);
        s->owner_tid = thr->tid;
        s->last_lock = thr->fast_state;
      } else if (s->owner_tid == thr->tid) {
        CHECK_GT(s->recursion, 0);
      } else if (flags()->report_mutex_bugs && !s->IsFlagSet(MutexFlagBroken)) {
        s->SetFlags(MutexFlagBroken);
        report_double_lock = true;
      }
      s->recursion += rec;
      if (first) {
        if (!thr->ignore_sync) {
          thr->clock.Acquire(s->clock);
          thr->clock.Acquire(s->read_clock);
        }
      }
      if (first && common_flags()->detect_deadlocks) {
        pre_lock = (flagz & MutexFlagDoPreLockOnPostLock) &&
                   !(flagz & MutexFlagTryLock);
        Callback cb(thr, pc);
        if (pre_lock)
          ctx->dd->MutexBeforeLock(&cb, &s->dd, true);
        ctx->dd->MutexAfterLock(&cb, &s->dd, true, flagz & MutexFlagTryLock);
      }
    }
  }
  if (report_double_lock)
    ReportMutexMisuse(thr, pc, ReportTypeMutexDoubleLock, addr,
                      creation_stack_id);
  if (first && pre_lock && common_flags()->detect_deadlocks) {
    Callback cb(thr, pc);
    ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));
  }
}

int MutexUnlock(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
  DPrintf("#%d: MutexUnlock %zx flagz=0x%x\n", thr->tid, addr, flagz);
  if (pc && IsAppMem(addr))
    MemoryAccess(thr, pc, addr, 1, kAccessRead | kAccessAtomic);
  StackID creation_stack_id;
  RecordMutexUnlock(thr, addr);
  bool report_bad_unlock = false;
  int rec = 0;
  {
    SlotLocker locker(thr);
    auto s = ctx->metamap.GetSyncOrCreate(thr, pc, addr, true);
    bool released = false;
    {
      Lock lock(&s->mtx);
      creation_stack_id = s->creation_stack_id;
      if (!SANITIZER_GO && (s->recursion == 0 || s->owner_tid != thr->tid)) {
        if (flags()->report_mutex_bugs && !s->IsFlagSet(MutexFlagBroken)) {
          s->SetFlags(MutexFlagBroken);
          report_bad_unlock = true;
        }
      } else {
        rec = (flagz & MutexFlagRecursiveUnlock) ? s->recursion : 1;
        s->recursion -= rec;
        if (s->recursion == 0) {
          s->owner_tid = kInvalidTid;
          if (!thr->ignore_sync) {
            thr->clock.ReleaseStore(&s->clock);
            released = true;
          }
        }
      }
      if (common_flags()->detect_deadlocks && s->recursion == 0 &&
          !report_bad_unlock) {
        Callback cb(thr, pc);
        ctx->dd->MutexBeforeUnlock(&cb, &s->dd, true);
      }
    }
    if (released)
      IncrementEpoch(thr);
  }
  if (report_bad_unlock)
    ReportMutexMisuse(thr, pc, ReportTypeMutexBadUnlock, addr,
                      creation_stack_id);
  if (common_flags()->detect_deadlocks && !report_bad_unlock) {
    Callback cb(thr, pc);
    ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));
  }
  return rec;
}

void MutexPreReadLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
  DPrintf("#%d: MutexPreReadLock %zx flagz=0x%x\n", thr->tid, addr, flagz);
  if ((flagz & MutexFlagTryLock) || !common_flags()->detect_deadlocks)
    return;
  Callback cb(thr, pc);
  {
    SlotLocker locker(thr);
    auto s = ctx->metamap.GetSyncOrCreate(thr, pc, addr, true);
    ReadLock lock(&s->mtx);
    s->UpdateFlags(flagz);
    ctx->dd->MutexBeforeLock(&cb, &s->dd, false);
  }
  ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));
}

void MutexPostReadLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
  DPrintf("#%d: MutexPostReadLock %zx flagz=0x%x\n", thr->tid, addr, flagz);
  if (pc && IsAppMem(addr))
    MemoryAccess(thr, pc, addr, 1, kAccessRead | kAccessAtomic);
  bool report_bad_lock = false;
  bool pre_lock = false;
  StackID creation_stack_id = kInvalidStackID;
  {
    SlotLocker locker(thr);
    auto s = ctx->metamap.GetSyncOrCreate(thr, pc, addr, true);
    creation_stack_id = s->creation_stack_id;
    RecordMutexLock(thr, pc, addr, creation_stack_id, false);
    {
      ReadLock lock(&s->mtx);
      s->UpdateFlags(flagz);
      if (s->owner_tid != kInvalidTid) {
        if (flags()->report_mutex_bugs && !s->IsFlagSet(MutexFlagBroken)) {
          s->SetFlags(MutexFlagBroken);
          report_bad_lock = true;
        }
      }
      if (!thr->ignore_sync)
        thr->clock.Acquire(s->clock);
      s->last_lock = thr->fast_state;
      if (common_flags()->detect_deadlocks) {
        pre_lock = (flagz & MutexFlagDoPreLockOnPostLock) &&
                   !(flagz & MutexFlagTryLock);
        Callback cb(thr, pc);
        if (pre_lock)
          ctx->dd->MutexBeforeLock(&cb, &s->dd, false);
        ctx->dd->MutexAfterLock(&cb, &s->dd, false, flagz & MutexFlagTryLock);
      }
    }
  }
  if (report_bad_lock)
    ReportMutexMisuse(thr, pc, ReportTypeMutexBadReadLock, addr,
                      creation_stack_id);
  if (pre_lock  && common_flags()->detect_deadlocks) {
    Callback cb(thr, pc);
    ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));
  }
}

void MutexReadUnlock(ThreadState *thr, uptr pc, uptr addr) {
  DPrintf("#%d: MutexReadUnlock %zx\n", thr->tid, addr);
  if (pc && IsAppMem(addr))
    MemoryAccess(thr, pc, addr, 1, kAccessRead | kAccessAtomic);
  RecordMutexUnlock(thr, addr);
  StackID creation_stack_id;
  bool report_bad_unlock = false;
  {
    SlotLocker locker(thr);
    auto s = ctx->metamap.GetSyncOrCreate(thr, pc, addr, true);
    bool released = false;
    {
      Lock lock(&s->mtx);
      creation_stack_id = s->creation_stack_id;
      if (s->owner_tid != kInvalidTid) {
        if (flags()->report_mutex_bugs && !s->IsFlagSet(MutexFlagBroken)) {
          s->SetFlags(MutexFlagBroken);
          report_bad_unlock = true;
        }
      }
      if (!thr->ignore_sync) {
        thr->clock.Release(&s->read_clock);
        released = true;
      }
      if (common_flags()->detect_deadlocks && s->recursion == 0) {
        Callback cb(thr, pc);
        ctx->dd->MutexBeforeUnlock(&cb, &s->dd, false);
      }
    }
    if (released)
      IncrementEpoch(thr);
  }
  if (report_bad_unlock)
    ReportMutexMisuse(thr, pc, ReportTypeMutexBadReadUnlock, addr,
                      creation_stack_id);
  if (common_flags()->detect_deadlocks) {
    Callback cb(thr, pc);
    ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));
  }
}

void MutexReadOrWriteUnlock(ThreadState *thr, uptr pc, uptr addr) {
  DPrintf("#%d: MutexReadOrWriteUnlock %zx\n", thr->tid, addr);
  if (pc && IsAppMem(addr))
    MemoryAccess(thr, pc, addr, 1, kAccessRead | kAccessAtomic);
  RecordMutexUnlock(thr, addr);
  StackID creation_stack_id;
  bool report_bad_unlock = false;
  bool write = true;
  {
    SlotLocker locker(thr);
    auto s = ctx->metamap.GetSyncOrCreate(thr, pc, addr, true);
    bool released = false;
    {
      Lock lock(&s->mtx);
      creation_stack_id = s->creation_stack_id;
      if (s->owner_tid == kInvalidTid) {
        // Seems to be read unlock.
        write = false;
        if (!thr->ignore_sync) {
          thr->clock.Release(&s->read_clock);
          released = true;
        }
      } else if (s->owner_tid == thr->tid) {
        // Seems to be write unlock.
        CHECK_GT(s->recursion, 0);
        s->recursion--;
        if (s->recursion == 0) {
          s->owner_tid = kInvalidTid;
          if (!thr->ignore_sync) {
            thr->clock.ReleaseStore(&s->clock);
            released = true;
          }
        }
      } else if (!s->IsFlagSet(MutexFlagBroken)) {
        s->SetFlags(MutexFlagBroken);
        report_bad_unlock = true;
      }
      if (common_flags()->detect_deadlocks && s->recursion == 0) {
        Callback cb(thr, pc);
        ctx->dd->MutexBeforeUnlock(&cb, &s->dd, write);
      }
    }
    if (released)
      IncrementEpoch(thr);
  }
  if (report_bad_unlock)
    ReportMutexMisuse(thr, pc, ReportTypeMutexBadUnlock, addr,
                      creation_stack_id);
  if (common_flags()->detect_deadlocks) {
    Callback cb(thr, pc);
    ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));
  }
}

void MutexRepair(ThreadState *thr, uptr pc, uptr addr) {
  DPrintf("#%d: MutexRepair %zx\n", thr->tid, addr);
  SlotLocker locker(thr);
  auto s = ctx->metamap.GetSyncOrCreate(thr, pc, addr, true);
  Lock lock(&s->mtx);
  s->owner_tid = kInvalidTid;
  s->recursion = 0;
}

void MutexInvalidAccess(ThreadState *thr, uptr pc, uptr addr) {
  DPrintf("#%d: MutexInvalidAccess %zx\n", thr->tid, addr);
  StackID creation_stack_id = kInvalidStackID;
  {
    SlotLocker locker(thr);
    auto s = ctx->metamap.GetSyncOrCreate(thr, pc, addr, true);
    if (s)
      creation_stack_id = s->creation_stack_id;
  }
  ReportMutexMisuse(thr, pc, ReportTypeMutexInvalidAccess, addr,
                    creation_stack_id);
}

void Acquire(ThreadState *thr, uptr pc, uptr addr) {
  DPrintf("#%d: Acquire %zx\n", thr->tid, addr);
  if (thr->ignore_sync)
    return;
  auto s = ctx->metamap.GetSyncIfExists(addr);
  if (!s)
    return;
  SlotLocker locker(thr);
  if (!s->clock)
    return;
  ReadLock lock(&s->mtx);
  thr->clock.Acquire(s->clock);
}

void AcquireGlobal(ThreadState *thr) {
  DPrintf("#%d: AcquireGlobal\n", thr->tid);
  if (thr->ignore_sync)
    return;
  SlotLocker locker(thr);
  for (auto &slot : ctx->slots) thr->clock.Set(slot.sid, slot.epoch());
}

void Release(ThreadState *thr, uptr pc, uptr addr) {
  DPrintf("#%d: Release %zx\n", thr->tid, addr);
  if (thr->ignore_sync)
    return;
  SlotLocker locker(thr);
  {
    auto s = ctx->metamap.GetSyncOrCreate(thr, pc, addr, false);
    Lock lock(&s->mtx);
    thr->clock.Release(&s->clock);
  }
  IncrementEpoch(thr);
}

void ReleaseStore(ThreadState *thr, uptr pc, uptr addr) {
  DPrintf("#%d: ReleaseStore %zx\n", thr->tid, addr);
  if (thr->ignore_sync)
    return;
  SlotLocker locker(thr);
  {
    auto s = ctx->metamap.GetSyncOrCreate(thr, pc, addr, false);
    Lock lock(&s->mtx);
    thr->clock.ReleaseStore(&s->clock);
  }
  IncrementEpoch(thr);
}

void ReleaseStoreAcquire(ThreadState *thr, uptr pc, uptr addr) {
  DPrintf("#%d: ReleaseStoreAcquire %zx\n", thr->tid, addr);
  if (thr->ignore_sync)
    return;
  SlotLocker locker(thr);
  {
    auto s = ctx->metamap.GetSyncOrCreate(thr, pc, addr, false);
    Lock lock(&s->mtx);
    thr->clock.ReleaseStoreAcquire(&s->clock);
  }
  IncrementEpoch(thr);
}

void IncrementEpoch(ThreadState *thr) {
  DCHECK(!thr->ignore_sync);
  DCHECK(thr->slot_locked);
  Epoch epoch = EpochInc(thr->fast_state.epoch());
  if (!EpochOverflow(epoch)) {
    Sid sid = thr->fast_state.sid();
    thr->clock.Set(sid, epoch);
    thr->fast_state.SetEpoch(epoch);
    thr->slot->SetEpoch(epoch);
    TraceTime(thr);
  }
}

#if !SANITIZER_GO
void AfterSleep(ThreadState *thr, uptr pc) {
  DPrintf("#%d: AfterSleep\n", thr->tid);
  if (thr->ignore_sync)
    return;
  thr->last_sleep_stack_id = CurrentStackId(thr, pc);
  thr->last_sleep_clock.Reset();
  SlotLocker locker(thr);
  for (auto &slot : ctx->slots)
    thr->last_sleep_clock.Set(slot.sid, slot.epoch());
}
#endif

void ReportDeadlock(ThreadState *thr, uptr pc, DDReport *r) {
  if (r == 0 || !ShouldReport(thr, ReportTypeDeadlock))
    return;
  ThreadRegistryLock l(&ctx->thread_registry);
  ScopedReport rep(ReportTypeDeadlock);
  for (int i = 0; i < r->n; i++) {
    rep.AddMutex(r->loop[i].mtx_ctx0, r->loop[i].stk[0]);
    rep.AddUniqueTid((int)r->loop[i].thr_ctx);
    rep.AddThread((int)r->loop[i].thr_ctx);
  }
  uptr dummy_pc = 0x42;
  for (int i = 0; i < r->n; i++) {
    for (int j = 0; j < (flags()->second_deadlock_stack ? 2 : 1); j++) {
      u32 stk = r->loop[i].stk[j];
      if (stk && stk != kInvalidStackID) {
        rep.AddStack(StackDepotGet(stk), true);
      } else {
        // Sometimes we fail to extract the stack trace (FIXME: investigate),
        // but we should still produce some stack trace in the report.
        rep.AddStack(StackTrace(&dummy_pc, 1), true);
      }
    }
  }
  OutputReport(thr, rep);
}

void ReportDestroyLocked(ThreadState *thr, uptr pc, uptr addr,
                         FastState last_lock, StackID creation_stack_id) {
  SlotPairLocker locker(thr, last_lock.sid());
  ThreadRegistryLock l0(&ctx->thread_registry);
  Lock slots_lock(&ctx->slot_mtx);
  ScopedReport rep(ReportTypeMutexDestroyLocked);
  rep.AddMutex(addr, creation_stack_id);
  VarSizeStackTrace trace;
  ObtainCurrentStack(thr, pc, &trace);
  rep.AddStack(trace, true);

  Tid tid;
  DynamicMutexSet mset;
  uptr tag;
  if (!RestoreStack(EventType::kLock, last_lock.sid(), last_lock.epoch(), addr,
                    0, kAccessWrite, &tid, &trace, mset, &tag))
    return;
  rep.AddStack(trace, true);
  rep.AddLocation(addr, 1);
  OutputReport(thr, rep);
}

}  // namespace __tsan
