(root)/
gcc-13.2.0/
gcc/
testsuite/
c-c++-common/
tsan/
simple_stack.c
       1  /* { dg-shouldfail "tsan" } */
       2  /* { dg-additional-options "-ldl" } */
       3  
       4  #include <pthread.h>
       5  #include "tsan_barrier.h"
       6  
       7  static pthread_barrier_t barrier;
       8  int Global;
       9  
      10  void __attribute__((noinline)) foo1() {
      11    Global = 42;
      12  }
      13  
      14  void __attribute__((noinline)) bar1() {
      15    volatile int tmp = 42; (void)tmp;
      16    foo1();
      17  }
      18  
      19  void __attribute__((noinline)) foo2() {
      20    volatile int v = Global; (void)v;
      21  }
      22  
      23  void __attribute__((noinline)) bar2() {
      24    volatile int tmp = 42; (void)tmp;
      25    foo2();
      26  }
      27  
      28  void *Thread1(void *x) {
      29    barrier_wait(&barrier);
      30    bar1();
      31    return NULL;
      32  }
      33  
      34  void *Thread2(void *x) {
      35    bar2();
      36    barrier_wait(&barrier);
      37    return NULL;
      38  }
      39  
      40  void StartThread(pthread_t *t, void *(*f)(void*)) {
      41    pthread_create(t, NULL, f, NULL);
      42  }
      43  
      44  int main() {
      45    barrier_init(&barrier, 2);
      46    pthread_t t[2];
      47    StartThread(&t[0], Thread1);
      48    StartThread(&t[1], Thread2);
      49    pthread_join(t[0], NULL);
      50    pthread_join(t[1], NULL);
      51    return 0;
      52  }
      53  
      54  /* { dg-output "WARNING: ThreadSanitizer: data race.*" } */
      55  /* { dg-output "  Write of size 4 at .* by thread T1:(\n|\r\n|\r)" } */
      56  /* { dg-output "    #0 foo1.* .*(simple_stack.c:11|\\?{2}:0) (.*)" } */
      57  /* { dg-output "    #1 bar1.* .*(simple_stack.c:16|\\?{2}:0) (.*)" } */
      58  /* { dg-output "    #2 Thread1.* .*(simple_stack.c:30|\\?{2}:0) (.*)" } */
      59  /* { dg-output "  Previous read of size 4 at .* by thread T2:(\n|\r\n|\r)" } */
      60  /* { dg-output "    #0 foo2.* .*(simple_stack.c:20|\\?{2}:0) (.*)" } */
      61  /* { dg-output "    #1 bar2.* .*(simple_stack.c:25|\\?{2}:0) (.*)" } */
      62  /* { dg-output "    #2 Thread2.* .*(simple_stack.c:35|\\?{2}:0) (.*)" } */
      63  /* { dg-output "  Thread T1 \\(tid=.*, running\\) created by main thread at:(\n|\r\n|\r)" } */
      64  /* { dg-output "    #0 pthread_create .* (.*)" } */
      65  /* { dg-output "    #1 StartThread.* .*(simple_stack.c:41|\\?{2}:0) (.*)" } */
      66  /* { dg-output "  Thread T2 (.*) created by main thread at:(\n|\r\n|\r)" } */
      67  /* { dg-output "    #0 pthread_create .* (.*)" } */
      68  /* { dg-output "    #1 StartThread.* .*(simple_stack.c:41|\\?{2}:0) (.*)" } */