Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mutexset.h
35269 views
1
//===-- tsan_mutexset.h -----------------------------------------*- C++ -*-===//
2
//
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
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file is a part of ThreadSanitizer (TSan), a race detector.
10
//
11
// MutexSet holds the set of mutexes currently held by a thread.
12
//===----------------------------------------------------------------------===//
13
#ifndef TSAN_MUTEXSET_H
14
#define TSAN_MUTEXSET_H
15
16
#include "tsan_defs.h"
17
18
namespace __tsan {
19
20
class MutexSet {
21
public:
22
// Holds limited number of mutexes.
23
// The oldest mutexes are discarded on overflow.
24
static constexpr uptr kMaxSize = 16;
25
struct Desc {
26
uptr addr;
27
StackID stack_id;
28
u32 seq;
29
u32 count;
30
bool write;
31
32
Desc() { internal_memset(this, 0, sizeof(*this)); }
33
Desc(const Desc& other) { *this = other; }
34
Desc& operator=(const MutexSet::Desc& other) {
35
internal_memcpy(this, &other, sizeof(*this));
36
return *this;
37
}
38
};
39
40
MutexSet();
41
void Reset();
42
void AddAddr(uptr addr, StackID stack_id, bool write);
43
void DelAddr(uptr addr, bool destroy = false);
44
uptr Size() const;
45
Desc Get(uptr i) const;
46
47
private:
48
#if !SANITIZER_GO
49
u32 seq_ = 0;
50
uptr size_ = 0;
51
Desc descs_[kMaxSize];
52
53
void RemovePos(uptr i);
54
#endif
55
};
56
57
// MutexSet is too large to live on stack.
58
// DynamicMutexSet can be use used to create local MutexSet's.
59
class DynamicMutexSet {
60
public:
61
DynamicMutexSet();
62
~DynamicMutexSet();
63
MutexSet* operator->() { return ptr_; }
64
operator MutexSet*() { return ptr_; }
65
DynamicMutexSet(const DynamicMutexSet&) = delete;
66
DynamicMutexSet& operator=(const DynamicMutexSet&) = delete;
67
68
private:
69
MutexSet* ptr_;
70
#if SANITIZER_GO
71
MutexSet set_;
72
#endif
73
};
74
75
// Go does not have mutexes, so do not spend memory and time.
76
// (Go sync.Mutex is actually a semaphore -- can be unlocked
77
// in different goroutine).
78
#if SANITIZER_GO
79
MutexSet::MutexSet() {}
80
void MutexSet::Reset() {}
81
void MutexSet::AddAddr(uptr addr, StackID stack_id, bool write) {}
82
void MutexSet::DelAddr(uptr addr, bool destroy) {}
83
uptr MutexSet::Size() const { return 0; }
84
MutexSet::Desc MutexSet::Get(uptr i) const { return Desc(); }
85
DynamicMutexSet::DynamicMutexSet() : ptr_(&set_) {}
86
DynamicMutexSet::~DynamicMutexSet() {}
87
#endif
88
89
} // namespace __tsan
90
91
#endif // TSAN_MUTEXSET_H
92
93