diff options
| author | Alex Rønne Petersen <alex@alexrp.com> | 2025-04-12 18:14:17 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-12 18:14:17 +0200 |
| commit | 9352f379e8a08bcc5a3bfc851bfb6c6a662000af (patch) | |
| tree | 9fee8a3b98ab806c02aab3a6e9646ccea08f40f1 /lib/libtsan/tsan_mutexset.cpp | |
| parent | 4e700fdf8ed01e7fc856e631ceffd6006e6f48df (diff) | |
| parent | 1f896c1bf89aa0e3d2a0dce1f4cf6ba6ce5ae9ed (diff) | |
| download | zig-9352f379e8a08bcc5a3bfc851bfb6c6a662000af.tar.gz zig-9352f379e8a08bcc5a3bfc851bfb6c6a662000af.zip | |
Merge pull request #23529 from alexrp/2879-groundwork
Introduce libzigc for libc function implementations in Zig
Diffstat (limited to 'lib/libtsan/tsan_mutexset.cpp')
| -rw-r--r-- | lib/libtsan/tsan_mutexset.cpp | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/lib/libtsan/tsan_mutexset.cpp b/lib/libtsan/tsan_mutexset.cpp new file mode 100644 index 0000000000..3a75b80ac3 --- /dev/null +++ b/lib/libtsan/tsan_mutexset.cpp @@ -0,0 +1,80 @@ +//===-- tsan_mutexset.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 "tsan_mutexset.h" + +#include "sanitizer_common/sanitizer_placement_new.h" +#include "tsan_rtl.h" + +namespace __tsan { + +MutexSet::MutexSet() { +} + +void MutexSet::Reset() { internal_memset(this, 0, sizeof(*this)); } + +void MutexSet::AddAddr(uptr addr, StackID stack_id, bool write) { + // Look up existing mutex with the same id. + for (uptr i = 0; i < size_; i++) { + if (descs_[i].addr == addr) { + descs_[i].count++; + descs_[i].seq = seq_++; + return; + } + } + // On overflow, find the oldest mutex and drop it. + if (size_ == kMaxSize) { + uptr min = 0; + for (uptr i = 0; i < size_; i++) { + if (descs_[i].seq < descs_[min].seq) + min = i; + } + RemovePos(min); + CHECK_EQ(size_, kMaxSize - 1); + } + // Add new mutex descriptor. + descs_[size_].addr = addr; + descs_[size_].stack_id = stack_id; + descs_[size_].write = write; + descs_[size_].seq = seq_++; + descs_[size_].count = 1; + size_++; +} + +void MutexSet::DelAddr(uptr addr, bool destroy) { + for (uptr i = 0; i < size_; i++) { + if (descs_[i].addr == addr) { + if (destroy || --descs_[i].count == 0) + RemovePos(i); + return; + } + } +} + +void MutexSet::RemovePos(uptr i) { + CHECK_LT(i, size_); + descs_[i] = descs_[size_ - 1]; + size_--; +} + +uptr MutexSet::Size() const { + return size_; +} + +MutexSet::Desc MutexSet::Get(uptr i) const { + CHECK_LT(i, size_); + return descs_[i]; +} + +DynamicMutexSet::DynamicMutexSet() : ptr_(New<MutexSet>()) {} +DynamicMutexSet::~DynamicMutexSet() { DestroyAndFree(ptr_); } + +} // namespace __tsan |
