36
36
#include <sys/mman.h>
37
37
#include <sys/types.h>
38
38
39
+ #if defined(__has_feature )
40
+ #if __has_feature (thread_sanitizer )
41
+ #include <sanitizer/tsan_interface.h>
42
+ #endif
43
+ #endif
44
+
39
45
/******************************************************/
40
46
/* Public Headers */
41
47
/******************************************************/
@@ -225,8 +231,80 @@ static inline void alloc_rdata(qthread_shepherd_t *me, qthread_t *t) { /*{{{*/
225
231
VALGRIND_STACK_REGISTER (stack , qlib -> qthread_stack_size );
226
232
}
227
233
#endif
234
+ #if defined(__has_feature )
235
+ #if __has_feature (thread_sanitizer )
236
+ atomic_store_explicit (
237
+ & rdata -> tsan_fiber , __tsan_create_fiber (0u ), memory_order_relaxed );
238
+ assert (atomic_load_explicit (& rdata -> tsan_fiber , memory_order_relaxed ));
239
+ #endif
240
+ #endif
228
241
} /*}}}*/
229
242
243
+ #if defined(__has_feature )
244
+ #if __has_feature (thread_sanitizer )
245
+ #define qthread_before_swap_to_qthread (t ) \
246
+ do { \
247
+ void *tsan_local_fiber = \
248
+ atomic_load_explicit(&t->rdata->tsan_fiber, memory_order_relaxed); \
249
+ atomic_store_explicit(&t->rdata->tsan_fiber, \
250
+ __tsan_get_current_fiber(), \
251
+ memory_order_relaxed); \
252
+ __tsan_switch_to_fiber(tsan_local_fiber, 0u); \
253
+ } while (0)
254
+
255
+ #define qthread_after_swap_to_qthread (t )
256
+
257
+ #define qthread_before_swap_from_qthread (t ) \
258
+ do { \
259
+ void *tsan_local_fiber = \
260
+ atomic_load_explicit(&t->rdata->tsan_fiber, memory_order_relaxed); \
261
+ atomic_store_explicit(&t->rdata->tsan_fiber, \
262
+ __tsan_get_current_fiber(), \
263
+ memory_order_relaxed); \
264
+ __tsan_switch_to_fiber(tsan_local_fiber, 0u); \
265
+ } while (0)
266
+
267
+ #define qthread_after_swap_from_qthread (t )
268
+
269
+ #define qthread_before_swap_to_main () \
270
+ do { \
271
+ void *tsan_local_fiber_main = qlib->tsan_main_fiber; \
272
+ qlib->tsan_main_fiber = __tsan_get_current_fiber(); \
273
+ __tsan_switch_to_fiber(tsan_local_fiber_main, 0u); \
274
+ } while (0)
275
+
276
+ #define qthread_after_swap_to_main ()
277
+
278
+ #define qthread_before_swap_from_main () \
279
+ do { \
280
+ void *tsan_local_fiber_main = qlib->tsan_main_fiber; \
281
+ qlib->tsan_main_fiber = __tsan_get_current_fiber(); \
282
+ __tsan_switch_to_fiber(tsan_local_fiber_main, 0u); \
283
+ } while (0)
284
+
285
+ #define qthread_after_swap_from_main ()
286
+
287
+ #else
288
+ #define qthread_before_swap_to_qthread (t )
289
+ #define qthread_after_swap_to_qthread (t )
290
+ #define qthread_before_swap_from_qthread (t )
291
+ #define qthread_after_swap_from_qthread (t )
292
+ #define qthread_before_swap_to_main ()
293
+ #define qthread_after_swap_to_main ()
294
+ #define qthread_before_swap_from_main ()
295
+ #define qthread_after_swap_from_main ()
296
+ #endif
297
+ #else
298
+ #define qthread_before_swap_to_qthread (t )
299
+ #define qthread_after_swap_to_qthread (t )
300
+ #define qthread_before_swap_from_qthread (t )
301
+ #define qthread_after_swap_from_qthread (t )
302
+ #define qthread_before_swap_to_main ()
303
+ #define qthread_after_swap_to_main ()
304
+ #define qthread_before_swap_from_main ()
305
+ #define qthread_after_swap_from_main ()
306
+ #endif
307
+
230
308
/* the qthread_master() function is the loop responsible for actually
231
309
* executing the work units
232
310
*
@@ -251,6 +329,7 @@ static void *qthread_master(void *arg) {
251
329
qthread_worker_t * me_worker = (qthread_worker_t * )arg ;
252
330
qthread_shepherd_t * me = (qthread_shepherd_t * )me_worker -> shepherd ;
253
331
qthread_shepherd_id_t my_id = me -> shepherd_id ;
332
+ if (my_id == 0 && me_worker -> worker_id == 0 ) { qthread_after_swap_to_main (); }
254
333
qt_context_t my_context ;
255
334
qt_threadqueue_t * threadqueue ;
256
335
qt_threadqueue_private_t * localqueue = NULL ;
@@ -441,6 +520,10 @@ static void *qthread_master(void *arg) {
441
520
}
442
521
}
443
522
523
+ if (my_id == 0 && me_worker -> worker_id == 0 ) {
524
+ qthread_before_swap_from_main ();
525
+ }
526
+
444
527
pthread_exit (NULL );
445
528
return NULL ;
446
529
} /*}}} */
@@ -714,6 +797,17 @@ int API_FUNC qthread_initialize(void) { /*{{{ */
714
797
qlib -> mccoy_thread -> rdata -> stack = NULL ;
715
798
qlib -> mccoy_thread -> rdata -> tasklocal_size = 0 ;
716
799
800
+ #if defined(__has_feature )
801
+ #if __has_feature (thread_sanitizer )
802
+ atomic_store_explicit (& qlib -> mccoy_thread -> rdata -> tsan_fiber ,
803
+ __tsan_get_current_fiber (),
804
+ memory_order_relaxed );
805
+ qlib -> tsan_main_fiber = __tsan_create_fiber (0u );
806
+ assert (atomic_load_explicit (& qlib -> mccoy_thread -> rdata -> tsan_fiber ,
807
+ memory_order_relaxed ) &&
808
+ qlib -> tsan_main_fiber );
809
+ #endif
810
+ #endif
717
811
TLS_SET (shepherd_structs ,
718
812
(qthread_shepherd_t * )& (qlib -> shepherds [0 ].workers [0 ]));
719
813
qt_threadqueue_enqueue (qlib -> shepherds [0 ].ready , qlib -> mccoy_thread );
@@ -749,6 +843,9 @@ int API_FUNC qthread_initialize(void) { /*{{{ */
749
843
sizeof (qt_context_t ));
750
844
VALGRIND_MAKE_MEM_DEFINED (& (qlib -> master_context ), sizeof (qt_context_t ));
751
845
#endif
846
+
847
+ qthread_before_swap_to_main ();
848
+
752
849
#ifdef HAVE_NATIVE_MAKECONTEXT
753
850
qassert (
754
851
swapcontext (& qlib -> mccoy_thread -> rdata -> context , & (qlib -> master_context )),
@@ -758,6 +855,9 @@ int API_FUNC qthread_initialize(void) { /*{{{ */
758
855
qt_swapctxt (& qlib -> mccoy_thread -> rdata -> context , & (qlib -> master_context )),
759
856
0 );
760
857
#endif
858
+
859
+ qthread_after_swap_from_main ();
860
+
761
861
assert (hw_par > 0 );
762
862
qlib -> nworkers_active = hw_par ;
763
863
@@ -1053,6 +1153,14 @@ void API_FUNC qthread_finalize(void) { /*{{{ */
1053
1153
#ifdef QTHREAD_USE_VALGRIND
1054
1154
VALGRIND_STACK_DEREGISTER (qlib -> mccoy_thread -> rdata -> valgrind_stack_id );
1055
1155
VALGRIND_STACK_DEREGISTER (qlib -> valgrind_masterstack_id );
1156
+ #endif
1157
+ #if defined(__has_feature )
1158
+ #if __has_feature (thread_sanitizer )
1159
+ assert (atomic_load_explicit (& qlib -> mccoy_thread -> rdata -> tsan_fiber ,
1160
+ memory_order_relaxed ) &&
1161
+ qlib -> tsan_main_fiber );
1162
+ //__tsan_destroy_fiber(qlib->tsan_main_fiber);
1163
+ #endif
1056
1164
#endif
1057
1165
assert (qlib -> mccoy_thread -> rdata -> stack == NULL );
1058
1166
if (qlib -> mccoy_thread -> rdata -> tasklocal_size > 0 ) {
@@ -1381,6 +1489,12 @@ void qthread_thread_free(qthread_t *t) { /*{{{ */
1381
1489
}
1382
1490
#ifdef QTHREAD_USE_VALGRIND
1383
1491
VALGRIND_STACK_DEREGISTER (t -> rdata -> valgrind_stack_id );
1492
+ #endif
1493
+ #if defined(__has_feature )
1494
+ #if __has_feature (thread_sanitizer )
1495
+ assert (atomic_load_explicit (& t -> rdata -> tsan_fiber , memory_order_relaxed ));
1496
+ //__tsan_destroy_fiber(t->rdata->tsan_fiber);
1497
+ #endif
1384
1498
#endif
1385
1499
if (atomic_load_explicit (& t -> flags , memory_order_relaxed ) &
1386
1500
QTHREAD_SIMPLE ) {
@@ -1452,6 +1566,7 @@ static void qthread_wrapper(unsigned int high, unsigned int low) { /*{{{ */
1452
1566
static void qthread_wrapper (void * ptr ) {
1453
1567
qthread_t * t = (qthread_t * )ptr ;
1454
1568
#endif
1569
+ if ((t -> flags & QTHREAD_SIMPLE ) == 0 ) { qthread_after_swap_to_qthread (t ); }
1455
1570
#ifdef QTHREAD_ALLOW_HPCTOOLKIT_STACK_UNWINDING
1456
1571
MONITOR_ASM_LABEL (qthread_fence1 ); // add label for HPCToolkit stack unwind
1457
1572
#endif
@@ -1594,7 +1709,10 @@ static void qthread_wrapper(void *ptr) {
1594
1709
#endif
1595
1710
if ((atomic_load_explicit (& t -> flags , memory_order_relaxed ) &
1596
1711
QTHREAD_SIMPLE ) == 0 ) {
1712
+ qthread_before_swap_from_qthread (t );
1597
1713
qthread_back_to_master2 (t );
1714
+ qthread_after_swap_to_qthread (t );
1715
+ qthread_before_swap_from_qthread (t );
1598
1716
}
1599
1717
} /*}}} */
1600
1718
@@ -1643,6 +1761,9 @@ void INTERNAL qthread_exec(qthread_t *t, qt_context_t *c) { /*{{{ */
1643
1761
atomic_load_explicit (& t -> rdata -> return_context , memory_order_relaxed ),
1644
1762
sizeof (qt_context_t ));
1645
1763
#endif
1764
+
1765
+ qthread_before_swap_to_qthread (t );
1766
+
1646
1767
#ifdef HAVE_NATIVE_MAKECONTEXT
1647
1768
qassert (swapcontext (atomic_load_explicit (& t -> rdata -> return_context ,
1648
1769
memory_order_relaxed ),
@@ -1654,6 +1775,9 @@ void INTERNAL qthread_exec(qthread_t *t, qt_context_t *c) { /*{{{ */
1654
1775
& t -> rdata -> context ),
1655
1776
0 );
1656
1777
#endif
1778
+
1779
+ qthread_after_swap_from_qthread (t );
1780
+
1657
1781
} else {
1658
1782
assert (t -> thread_state == QTHREAD_STATE_NEW );
1659
1783
atomic_store_explicit (
@@ -2109,6 +2233,7 @@ void INTERNAL qthread_back_to_master(qthread_t *t) { /*{{{ */
2109
2233
atomic_load_explicit (& t -> rdata -> return_context , memory_order_relaxed ),
2110
2234
sizeof (qt_context_t ));
2111
2235
#endif
2236
+ qthread_before_swap_from_qthread (t );
2112
2237
#ifdef HAVE_NATIVE_MAKECONTEXT
2113
2238
qassert (swapcontext (& t -> rdata -> context ,
2114
2239
atomic_load_explicit (& t -> rdata -> return_context ,
@@ -2120,6 +2245,9 @@ void INTERNAL qthread_back_to_master(qthread_t *t) { /*{{{ */
2120
2245
memory_order_relaxed )),
2121
2246
0 );
2122
2247
#endif
2248
+
2249
+ qthread_after_swap_to_qthread (t );
2250
+
2123
2251
} /*}}} */
2124
2252
2125
2253
void INTERNAL qthread_back_to_master2 (qthread_t * t ) { /*{{{ */
0 commit comments