Skip to content

Commit 59034de

Browse files
committed
Add thread sanitizer annotations for reverse mutex synchronization.
1 parent 6cc8782 commit 59034de

2 files changed

Lines changed: 124 additions & 16 deletions

File tree

include/opdi/logic/omp/mutexOmpLogic.cpp

Lines changed: 111 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
*
2424
*/
2525

26+
#include <cassert>
27+
2628
#include "../../helpers/macros.hpp"
2729
#include "../../helpers/exceptions.hpp"
2830
#include "../../config.hpp"
@@ -34,8 +36,15 @@
3436

3537
opdi::MutexOmpLogic::State opdi::MutexOmpLogic::localState;
3638
opdi::MutexOmpLogic::State opdi::MutexOmpLogic::evalState;
37-
38-
void opdi::MutexOmpLogic::internalWaitReverseFunc(std::map<std::size_t, std::size_t>& evalTrace, void* dataPtr) {
39+
#ifdef __SANITIZE_THREAD__
40+
opdi::MutexOmpLogic::State opdi::MutexOmpLogic::tsanDummies;
41+
#endif
42+
43+
void opdi::MutexOmpLogic::internalWaitReverseFunc(std::map<std::size_t, std::size_t>& evalTrace,
44+
#ifdef __SANITIZE_THREAD__
45+
std::map<std::size_t, std::size_t>& tsanDummies,
46+
#endif
47+
void* dataPtr) {
3948
Data* data = (Data*) dataPtr;
4049

4150
#if OPDI_OMP_LOGIC_INSTRUMENT
@@ -55,36 +64,68 @@ void opdi::MutexOmpLogic::internalWaitReverseFunc(std::map<std::size_t, std::siz
5564
break;
5665
}
5766
}
67+
68+
#ifdef __SANITIZE_THREAD__
69+
ANNOTATE_RWLOCK_ACQUIRED(&tsanDummies[data->waitId], true);
70+
#endif
5871
}
5972

6073
void opdi::MutexOmpLogic::waitCriticalReverseFunc(void* dataPtr) {
61-
internalWaitReverseFunc(MutexOmpLogic::evalState.criticalTrace, dataPtr);
74+
internalWaitReverseFunc(MutexOmpLogic::evalState.criticalTrace,
75+
#ifdef __SANITIZE_THREAD__
76+
MutexOmpLogic::tsanDummies.criticalTrace,
77+
#endif
78+
dataPtr);
6279
}
6380

6481
void opdi::MutexOmpLogic::waitLockReverseFunc(void* dataPtr) {
65-
internalWaitReverseFunc(MutexOmpLogic::evalState.lockTrace, dataPtr);
82+
internalWaitReverseFunc(MutexOmpLogic::evalState.lockTrace,
83+
#ifdef __SANITIZE_THREAD__
84+
MutexOmpLogic::tsanDummies.lockTrace,
85+
#endif
86+
dataPtr);
6687
}
6788

6889
void opdi::MutexOmpLogic::waitNestedLockReverseFunc(void* dataPtr) {
69-
internalWaitReverseFunc(MutexOmpLogic::evalState.nestedLockTrace, dataPtr);
90+
internalWaitReverseFunc(MutexOmpLogic::evalState.nestedLockTrace,
91+
#ifdef __SANITIZE_THREAD__
92+
MutexOmpLogic::tsanDummies.nestedLockTrace,
93+
#endif
94+
dataPtr);
7095
}
7196

7297
void opdi::MutexOmpLogic::waitOrderedReverseFunc(void* dataPtr) {
73-
internalWaitReverseFunc(MutexOmpLogic::evalState.orderedTrace, dataPtr);
98+
internalWaitReverseFunc(MutexOmpLogic::evalState.orderedTrace,
99+
#ifdef __SANITIZE_THREAD__
100+
MutexOmpLogic::tsanDummies.orderedTrace,
101+
#endif
102+
dataPtr);
74103
}
75104

76105
void opdi::MutexOmpLogic::waitReductionReverseFunc(void* dataPtr) {
77-
internalWaitReverseFunc(MutexOmpLogic::evalState.reductionTrace, dataPtr);
106+
internalWaitReverseFunc(MutexOmpLogic::evalState.reductionTrace,
107+
#ifdef __SANITIZE_THREAD__
108+
MutexOmpLogic::tsanDummies.reductionTrace,
109+
#endif
110+
dataPtr);
78111
}
79112

80113
void opdi::MutexOmpLogic::waitDeleteFunc(void* dataPtr) {
81114
Data* data = (Data*) dataPtr;
82115
delete data;
83116
}
84117

85-
void opdi::MutexOmpLogic::internalDecrementReverseFunc(std::map<std::size_t, std::size_t>& evalTrace, void* dataPtr) {
118+
void opdi::MutexOmpLogic::internalDecrementReverseFunc(std::map<std::size_t, std::size_t>& evalTrace,
119+
#ifdef __SANITIZE_THREAD__
120+
std::map<std::size_t, std::size_t>& tsanDummies,
121+
#endif
122+
void* dataPtr) {
86123
Data* data = (Data*) dataPtr;
87124

125+
#ifdef __SANITIZE_THREAD__
126+
ANNOTATE_RWLOCK_RELEASED(&tsanDummies[data->waitId], true);
127+
#endif
128+
88129
// decrement trace value
89130
#pragma omp atomic update
90131
evalTrace[data->waitId] -= 1;
@@ -97,23 +138,43 @@ void opdi::MutexOmpLogic::internalDecrementReverseFunc(std::map<std::size_t, std
97138
}
98139

99140
void opdi::MutexOmpLogic::decrementCriticalReverseFunc(void* dataPtr) {
100-
internalDecrementReverseFunc(MutexOmpLogic::evalState.criticalTrace, dataPtr);
141+
internalDecrementReverseFunc(MutexOmpLogic::evalState.criticalTrace,
142+
#ifdef __SANITIZE_THREAD__
143+
MutexOmpLogic::tsanDummies.criticalTrace,
144+
#endif
145+
dataPtr);
101146
}
102147

103148
void opdi::MutexOmpLogic::decrementLockReverseFunc(void* dataPtr) {
104-
internalDecrementReverseFunc(MutexOmpLogic::evalState.lockTrace, dataPtr);
149+
internalDecrementReverseFunc(MutexOmpLogic::evalState.lockTrace,
150+
#ifdef __SANITIZE_THREAD__
151+
MutexOmpLogic::tsanDummies.lockTrace,
152+
#endif
153+
dataPtr);
105154
}
106155

107156
void opdi::MutexOmpLogic::decrementNestedLockReverseFunc(void* dataPtr) {
108-
internalDecrementReverseFunc(MutexOmpLogic::evalState.nestedLockTrace, dataPtr);
157+
internalDecrementReverseFunc(MutexOmpLogic::evalState.nestedLockTrace,
158+
#ifdef __SANITIZE_THREAD__
159+
MutexOmpLogic::tsanDummies.nestedLockTrace,
160+
#endif
161+
dataPtr);
109162
}
110163

111164
void opdi::MutexOmpLogic::decrementOrderedReverseFunc(void* dataPtr) {
112-
internalDecrementReverseFunc(MutexOmpLogic::evalState.orderedTrace, dataPtr);
165+
internalDecrementReverseFunc(MutexOmpLogic::evalState.orderedTrace,
166+
#ifdef __SANITIZE_THREAD__
167+
MutexOmpLogic::tsanDummies.orderedTrace,
168+
#endif
169+
dataPtr);
113170
}
114171

115172
void opdi::MutexOmpLogic::decrementReductionReverseFunc(void* dataPtr) {
116-
internalDecrementReverseFunc(MutexOmpLogic::evalState.reductionTrace, dataPtr);
173+
internalDecrementReverseFunc(MutexOmpLogic::evalState.reductionTrace,
174+
#ifdef __SANITIZE_THREAD__
175+
MutexOmpLogic::tsanDummies.reductionTrace,
176+
#endif
177+
dataPtr);
117178
}
118179

119180
void opdi::MutexOmpLogic::decrementDeleteFunc(void* dataPtr) {
@@ -348,11 +409,47 @@ void opdi::MutexOmpLogic::prepareEvaluate() {
348409
MutexOmpLogic::evalState.nestedLockTrace = this->nestedLockTrace.trace;
349410
MutexOmpLogic::evalState.orderedTrace = this->orderedTrace.trace;
350411
MutexOmpLogic::evalState.reductionTrace = this->reductionTrace.trace;
351-
}
352412

413+
#ifdef __SANITIZE_THREAD__
414+
/* create lock annotations for the reverse pass */
415+
416+
auto createReverseLocks=[](MutexOmpLogic::Trace const& evalState, MutexOmpLogic::Trace& tsanDummies) {
417+
assert(tsanDummies.empty());
418+
for (auto const& pair : evalState) {
419+
tsanDummies[pair.first] = 0;
420+
}
421+
422+
for (auto& pair : tsanDummies) {
423+
ANNOTATE_RWLOCK_CREATE(&pair.second);
424+
}
425+
};
426+
427+
createReverseLocks(MutexOmpLogic::evalState.criticalTrace, MutexOmpLogic::tsanDummies.criticalTrace);
428+
createReverseLocks(MutexOmpLogic::evalState.lockTrace, MutexOmpLogic::tsanDummies.lockTrace);
429+
createReverseLocks(MutexOmpLogic::evalState.nestedLockTrace, MutexOmpLogic::tsanDummies.nestedLockTrace);
430+
createReverseLocks(MutexOmpLogic::evalState.orderedTrace, MutexOmpLogic::tsanDummies.orderedTrace);
431+
createReverseLocks(MutexOmpLogic::evalState.reductionTrace, MutexOmpLogic::tsanDummies.reductionTrace);
432+
#endif
433+
}
353434

354435
void opdi::MutexOmpLogic::postEvaluate() {
436+
#ifdef __SANITIZE_THREAD__
437+
/* destroy lock annotations */
438+
439+
auto destroyReverseLocks=[](MutexOmpLogic::Trace& tsanDummies) {
440+
for (auto& pair : tsanDummies) {
441+
ANNOTATE_RWLOCK_DESTROY(&pair.second);
442+
}
443+
444+
tsanDummies.clear();
445+
};
355446

447+
destroyReverseLocks(MutexOmpLogic::tsanDummies.criticalTrace);
448+
destroyReverseLocks(MutexOmpLogic::tsanDummies.lockTrace);
449+
destroyReverseLocks(MutexOmpLogic::tsanDummies.nestedLockTrace);
450+
destroyReverseLocks(MutexOmpLogic::tsanDummies.orderedTrace);
451+
destroyReverseLocks(MutexOmpLogic::tsanDummies.reductionTrace);
452+
#endif
356453
}
357454

358455
void opdi::MutexOmpLogic::reset() {

include/opdi/logic/omp/mutexOmpLogic.hpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ namespace opdi {
6565
#pragma omp threadprivate(localState)
6666

6767
static State evalState;
68+
#ifdef __SANITIZE_THREAD__
69+
static State tsanDummies;
70+
#endif
6871

6972
public:
7073

@@ -77,7 +80,11 @@ namespace opdi {
7780

7881
private:
7982

80-
static void internalWaitReverseFunc(std::map<std::size_t, std::size_t>& evalTrace, void* dataPtr);
83+
static void internalWaitReverseFunc(std::map<std::size_t, std::size_t>& evalTrace,
84+
#ifdef __SANITIZE_THREAD__
85+
std::map<std::size_t, std::size_t>& tsanDummies,
86+
#endif
87+
void* dataPtr);
8188

8289
static void waitCriticalReverseFunc(void* dataPtr);
8390
static void waitLockReverseFunc(void* dataPtr);
@@ -87,7 +94,11 @@ namespace opdi {
8794

8895
static void waitDeleteFunc(void* dataPtr);
8996

90-
static void internalDecrementReverseFunc(std::map<std::size_t, std::size_t>& evalTrace, void* dataPtr);
97+
static void internalDecrementReverseFunc(std::map<std::size_t, std::size_t>& evalTrace,
98+
#ifdef __SANITIZE_THREAD__
99+
std::map<std::size_t, std::size_t>& tsanDummies,
100+
#endif
101+
void* dataPtr);
91102

92103
static void decrementCriticalReverseFunc(void* dataPtr);
93104
static void decrementLockReverseFunc(void* dataPtr);

0 commit comments

Comments
 (0)