2323 *
2424 */
2525
26+ #include < cassert>
27+
2628#include " ../../helpers/macros.hpp"
2729#include " ../../helpers/exceptions.hpp"
2830#include " ../../config.hpp"
3436
3537opdi::MutexOmpLogic::State opdi::MutexOmpLogic::localState;
3638opdi::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
6073void 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
6481void 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
6889void 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
7297void 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
76105void 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
80113void 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
99140void 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
103148void 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
107156void 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
111164void 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
115172void 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
119180void 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
354435void 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
358455void opdi::MutexOmpLogic::reset () {
0 commit comments