@@ -55,15 +55,28 @@ static inline void sanitizer_finish_switch_fiber(void) {}
55
55
#endif
56
56
57
57
#if defined(_COMPILER_TSAN_ENABLED_ )
58
- static inline void tsan_destroy_ctx (jl_ptls_t ptls , void * state ) {
59
- if (state != & ptls -> root_task -> state ) {
60
- __tsan_destroy_fiber (ctx -> state );
58
+ static inline void tsan_destroy_ctx (jl_ptls_t ptls , jl_ucontext_t * ctx ) {
59
+ if (ctx != & ptls -> root_task -> ctx ) {
60
+ __tsan_destroy_fiber (ctx -> tsan_state );
61
61
}
62
- ctx -> state = NULL ;
62
+ ctx -> tsan_state = NULL ;
63
63
}
64
- static inline void tsan_switch_to_ctx (void * state ) {
65
- __tsan_switch_to_fiber (state , 0 );
64
+ static inline void tsan_destroy_copyctx (jl_ptls_t ptls , struct jl_stack_context_t * ctx ) {
65
+ if (ctx != & ptls -> root_task -> copy_stack_ctx ) {
66
+ __tsan_destroy_fiber (ctx -> tsan_state );
67
+ }
68
+ ctx -> tsan_state = NULL ;
69
+ }
70
+ static inline void tsan_switch_to_ctx (jl_ucontext_t * ctx ) {
71
+ __tsan_switch_to_fiber (ctx -> tsan_state , 0 );
72
+ }
73
+ static inline void tsan_switch_to_copyctx (struct jl_stack_context_t * ctx ) {
74
+ __tsan_switch_to_fiber (ctx -> tsan_state , 0 );
66
75
}
76
+ #else
77
+ static inline void tsan_destroy_ctx (jl_ptls_t ptls , jl_ucontext_t * ctx ) {}
78
+ static inline void tsan_switch_to_ctx (jl_ucontext_t * ctx ) {}
79
+ static inline void tsan_switch_to_copyctx (struct jl_stack_context_t * ctx ) {}
67
80
#endif
68
81
69
82
// empirically, jl_finish_task needs about 64k stack space to infer/run
@@ -180,6 +193,7 @@ static void restore_stack2(jl_task_t *t, jl_ptls_t ptls, jl_task_t *lastt)
180
193
#error COPY_STACKS is incompatible with this platform
181
194
#endif
182
195
sanitizer_start_switch_fiber (t -> stkbuf , t -> bufsz );
196
+ tsan_switch_to_copyctx (& t -> copy_stack_ctx );
183
197
#if defined(_OS_WINDOWS_ )
184
198
jl_setcontext (& t -> ctx );
185
199
#else
@@ -357,9 +371,9 @@ static void ctx_switch(jl_task_t *lastt)
357
371
t -> sticky = 1 ;
358
372
t -> bufsz = 0 ;
359
373
if (always_copy_stacks )
360
- memcpy (& t -> copy_stack_ctx , & ptls -> copy_stack_ctx , sizeof (t -> copy_stack_ctx ));
374
+ memcpy (& t -> copy_stack_ctx , & ptls -> copy_stack_ctx , sizeof (t -> copy_stack_ctx ) - sizeof ( t -> copy_stack_ctx . tsan_state ) );
361
375
else
362
- memcpy (& t -> ctx , & ptls -> base_ctx , sizeof (t -> ctx ));
376
+ memcpy (& t -> ctx , & ptls -> base_ctx , sizeof (t -> ctx ) - sizeof ( t -> ctx . tsan_state ) );
363
377
#else
364
378
jl_throw (jl_memory_exception );
365
379
#endif
@@ -401,35 +415,39 @@ static void ctx_switch(jl_task_t *lastt)
401
415
#endif
402
416
jl_set_pgcstack (& t -> gcstack );
403
417
404
- #if defined(_COMPILER_TSAN_ENABLED_ )
405
- tsan_switch_to_ctx (& t -> tsan_state );
406
- if (killed )
407
- tsan_destroy_ctx (ptls , & lastt -> tsan_state );
408
- #endif
409
418
if (t -> started ) {
410
419
#ifdef COPY_STACKS
411
420
if (t -> copy_stack ) {
412
421
if (!killed && !lastt -> copy_stack )
413
422
restore_stack2 (t , ptls , lastt );
414
- else if (lastt -> copy_stack ) {
415
- restore_stack (t , ptls , NULL ); // (doesn't return)
416
- }
417
423
else {
418
- restore_stack (t , ptls , (char * )1 ); // (doesn't return)
424
+ tsan_switch_to_copyctx (& t -> copy_stack_ctx );
425
+ if (killed )
426
+ tsan_destroy_copyctx (ptls , & lastt -> copy_stack_ctx );
427
+
428
+ if (lastt -> copy_stack ) {
429
+ restore_stack (t , ptls , NULL ); // (doesn't return)
430
+ }
431
+ else {
432
+ restore_stack (t , ptls , (char * )1 ); // (doesn't return)
433
+ }
419
434
}
420
435
}
421
436
else
422
437
#endif
423
438
{
424
439
sanitizer_start_switch_fiber (t -> stkbuf , t -> bufsz );
425
440
if (killed ) {
441
+ tsan_switch_to_ctx (& t -> ctx );
442
+ tsan_destroy_ctx (ptls , & lastt -> ctx );
426
443
jl_set_fiber (& t -> ctx ); // (doesn't return)
427
444
abort (); // unreachable
428
445
}
429
446
else {
430
447
if (lastt -> copy_stack ) {
431
448
// Resume at the jl_setjmp earlier in this function,
432
449
// don't do a full task swap
450
+ tsan_switch_to_ctx (& t -> ctx );
433
451
jl_set_fiber (& t -> ctx ); // (doesn't return)
434
452
}
435
453
else {
@@ -441,6 +459,10 @@ static void ctx_switch(jl_task_t *lastt)
441
459
else {
442
460
sanitizer_start_switch_fiber (t -> stkbuf , t -> bufsz );
443
461
if (t -> copy_stack && always_copy_stacks ) {
462
+ tsan_switch_to_ctx (& t -> ctx );
463
+ if (killed ) {
464
+ tsan_destroy_ctx (ptls , & lastt -> ctx );
465
+ }
444
466
#ifdef COPY_STACKS
445
467
#if defined(_OS_WINDOWS_ )
446
468
jl_setcontext (& t -> ctx );
@@ -452,11 +474,14 @@ static void ctx_switch(jl_task_t *lastt)
452
474
}
453
475
else {
454
476
if (killed ) {
477
+ tsan_switch_to_ctx (& t -> ctx );
478
+ tsan_destroy_ctx (ptls , & lastt -> ctx );
455
479
jl_start_fiber_set (& t -> ctx ); // (doesn't return)
456
480
abort ();
457
481
}
458
482
else if (lastt -> copy_stack ) {
459
483
// Resume at the jl_setjmp earlier in this function
484
+ tsan_switch_to_ctx (& t -> ctx );
460
485
jl_start_fiber_set (& t -> ctx ); // (doesn't return)
461
486
abort ();
462
487
}
@@ -764,7 +789,10 @@ JL_DLLEXPORT jl_task_t *jl_new_task(jl_function_t *start, jl_value_t *completion
764
789
}
765
790
#endif
766
791
#ifdef _COMPILER_TSAN_ENABLED_
767
- t -> tsan_state = __tsan_create_fiber (0 );
792
+ if (always_copy_stacks )
793
+ t -> copy_stack_ctx .tsan_state = __tsan_create_fiber (0 );
794
+ else
795
+ t -> ctx .tsan_state = __tsan_create_fiber (0 );
768
796
#endif
769
797
return t ;
770
798
}
@@ -924,10 +952,12 @@ static void jl_start_fiber_set(jl_ucontext_t *t)
924
952
static void jl_start_fiber_swap (jl_ucontext_t * lastt , jl_ucontext_t * t )
925
953
{
926
954
assert (lastt );
955
+ tsan_switch_to_ctx (t );
927
956
swapcontext (lastt , t );
928
957
}
929
958
static void jl_swap_fiber (jl_ucontext_t * lastt , jl_ucontext_t * t )
930
959
{
960
+ tsan_switch_to_ctx (t );
931
961
swapcontext (lastt , t );
932
962
}
933
963
static void jl_set_fiber (jl_ucontext_t * t )
@@ -982,6 +1012,7 @@ static void jl_swap_fiber(jl_ucontext_t *lastt, jl_ucontext_t *t)
982
1012
{
983
1013
if (jl_setjmp (lastt -> uc_mcontext , 0 ))
984
1014
return ;
1015
+ tsan_switch_to_ctx (t );
985
1016
jl_set_fiber (t ); // doesn't return
986
1017
}
987
1018
static void jl_set_fiber (jl_ucontext_t * t )
@@ -1069,6 +1100,7 @@ static void jl_start_fiber_swap(jl_ucontext_t *lastt, jl_ucontext_t *t)
1069
1100
if (jl_setjmp (lastt -> uc_mcontext , 0 ))
1070
1101
return ;
1071
1102
#endif
1103
+ tsan_switch_to_ctx (t );
1072
1104
jl_start_fiber_set (t ); // doesn't return
1073
1105
}
1074
1106
static void jl_start_fiber_set (jl_ucontext_t * t )
@@ -1219,12 +1251,14 @@ static void jl_start_fiber_swap(jl_ucontext_t *lastt, jl_ucontext_t *t)
1219
1251
assert (lastt );
1220
1252
if (lastt && jl_setjmp (lastt -> uc_mcontext , 0 ))
1221
1253
return ;
1254
+ tsan_switch_to_ctx (t );
1222
1255
jl_start_fiber_set (t );
1223
1256
}
1224
1257
static void jl_swap_fiber (jl_ucontext_t * lastt , jl_ucontext_t * t )
1225
1258
{
1226
1259
if (jl_setjmp (lastt -> uc_mcontext , 0 ))
1227
1260
return ;
1261
+ tsan_switch_to_ctx (t );
1228
1262
jl_start_fiber_set (t ); // doesn't return
1229
1263
}
1230
1264
static void jl_set_fiber (jl_ucontext_t * t )
@@ -1311,7 +1345,10 @@ jl_task_t *jl_init_root_task(jl_ptls_t ptls, void *stack_lo, void *stack_hi)
1311
1345
assert (jl_current_task == ct );
1312
1346
1313
1347
#ifdef _COMPILER_TSAN_ENABLED_
1314
- ct -> tsan_state = __tsan_get_current_fiber ();
1348
+ if (always_copy_stacks )
1349
+ ct -> copy_stack_ctx .tsan_state = __tsan_get_current_fiber ();
1350
+ else
1351
+ ct -> ctx .tsan_state = __tsan_get_current_fiber ();
1315
1352
#endif
1316
1353
1317
1354
#ifdef COPY_STACKS
0 commit comments