1 //===-- tsan_mutexset.cpp -------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file is a part of ThreadSanitizer (TSan), a race detector.
11 //===----------------------------------------------------------------------===//
12 #include "tsan_mutexset.h"
14 #include "sanitizer_common/sanitizer_placement_new.h"
19 MutexSet::MutexSet() {
22 void MutexSet::Reset() { internal_memset(this, 0, sizeof(*this)); }
24 void MutexSet::AddAddr(uptr addr
, StackID stack_id
, bool write
) {
25 // Look up existing mutex with the same id.
26 for (uptr i
= 0; i
< size_
; i
++) {
27 if (descs_
[i
].addr
== addr
) {
29 descs_
[i
].seq
= seq_
++;
33 // On overflow, find the oldest mutex and drop it.
34 if (size_
== kMaxSize
) {
36 for (uptr i
= 0; i
< size_
; i
++) {
37 if (descs_
[i
].seq
< descs_
[min
].seq
)
41 CHECK_EQ(size_
, kMaxSize
- 1);
43 // Add new mutex descriptor.
44 descs_
[size_
].addr
= addr
;
45 descs_
[size_
].stack_id
= stack_id
;
46 descs_
[size_
].write
= write
;
47 descs_
[size_
].seq
= seq_
++;
48 descs_
[size_
].count
= 1;
52 void MutexSet::DelAddr(uptr addr
, bool destroy
) {
53 for (uptr i
= 0; i
< size_
; i
++) {
54 if (descs_
[i
].addr
== addr
) {
55 if (destroy
|| --descs_
[i
].count
== 0)
62 void MutexSet::RemovePos(uptr i
) {
64 descs_
[i
] = descs_
[size_
- 1];
68 uptr
MutexSet::Size() const {
72 MutexSet::Desc
MutexSet::Get(uptr i
) const {
77 DynamicMutexSet::DynamicMutexSet() : ptr_(New
<MutexSet
>()) {}
78 DynamicMutexSet::~DynamicMutexSet() { DestroyAndFree(ptr_
); }