Skip to content

Commit 8c89798

Browse files
committed
Merge branch 'feature/reverseTsanAnnotations' into develop
Thread sanitizer annotations for reverse mutex synchronization. New postEvaluate() method in the logic interface.
2 parents 2cc84e7 + 59034de commit 8c89798

8 files changed

Lines changed: 145 additions & 15 deletions

include/opdi/logic/logicInterface.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ namespace opdi {
7575
virtual void init() = 0;
7676
virtual void finalize() = 0;
7777
virtual void prepareEvaluate() = 0;
78+
virtual void postEvaluate() = 0;
7879
virtual void reset() = 0;
7980

8081
virtual void* exportState() = 0;

include/opdi/logic/omp/mutexOmpLogic.cpp

Lines changed: 115 additions & 13 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,6 +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;
412+
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+
}
434+
435+
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+
};
446+
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
351453
}
352454

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

include/opdi/logic/omp/mutexOmpLogic.hpp

Lines changed: 14 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);
@@ -123,6 +134,7 @@ namespace opdi {
123134
virtual void registerInactiveMutex(MutexKind kind, std::size_t waitId);
124135

125136
void prepareEvaluate();
137+
void postEvaluate();
126138
void reset();
127139

128140
void* exportState();

tests/drivers/DriverFirstOrderReverse.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ struct DriverFirstOrderReverse : public DriverBase<DriverFirstOrderReverse<_Case
111111
opdi::logic->prepareEvaluate();
112112
#endif
113113
tape.evaluate();
114+
#ifndef BUILD_REFERENCE
115+
opdi::logic->postEvaluate();
116+
#endif
114117

115118
for (int i = 0; i < Case::nIn; ++i)
116119
{

tests/drivers/DriverFirstOrderReverseNestedParallel.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ struct DriverFirstOrderReverseNestedParallel : public DriverBase<DriverFirstOrde
115115
opdi::logic->prepareEvaluate();
116116
#endif
117117
tape.evaluate();
118+
#ifndef BUILD_REFERENCE
119+
opdi::logic->postEvaluate();
120+
#endif
118121

119122
for (int i = 0; i < Case::nIn; ++i)
120123
{

tests/drivers/DriverFirstOrderReverseNoOpenMP.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ struct DriverFirstOrderReverseNoOpenMP : public DriverBase<DriverFirstOrderRever
112112
opdi::logic->prepareEvaluate();
113113
#endif
114114
tape.evaluate();
115+
#ifndef BUILD_REFERENCE
116+
opdi::logic->postEvaluate();
117+
#endif
115118

116119
for (int i = 0; i < Case::nIn; ++i)
117120
{

tests/drivers/DriverFirstOrderReversePassive.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ struct DriverFirstOrderReversePassive : public DriverBase<DriverFirstOrderRevers
110110
opdi::logic->prepareEvaluate();
111111
#endif
112112
tape.evaluate();
113+
#ifndef BUILD_REFERENCE
114+
opdi::logic->postEvaluate();
115+
#endif
113116

114117
for (int i = 0; i < Case::nIn; ++i)
115118
{

tests/drivers/DriverSecondOrderReverseForward.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ struct DriverSecondOrderReverseForward : public DriverBase<DriverSecondOrderReve
117117
opdi::logic->prepareEvaluate();
118118
#endif
119119
tape.evaluate();
120+
#ifndef BUILD_REFERENCE
121+
opdi::logic->postEvaluate();
122+
#endif
120123

121124
for (int i = 0; i < Case::nIn; ++i)
122125
{

0 commit comments

Comments
 (0)