(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
simulate-thread/
atomic-other-int.c
       1  /* { dg-do link } */
       2  /* { dg-require-effective-target sync_int_long } */
       3  /* { dg-final { simulate-thread } } */
       4  
       5  
       6  #include <stdio.h>
       7  #include "simulate-thread.h"
       8  
       9  /* Test all the __sync routines for proper atomicity on 4 byte values.  */
      10  
      11  unsigned int zero = 0;
      12  unsigned int max = ~0;
      13  
      14  unsigned int changing_value = 0;
      15  unsigned int value = 0;
      16  unsigned int ret;
      17  
      18  void test_abort()
      19  {
      20    static int reported = 0;
      21    if (!reported)
      22      {
      23        printf ("FAIL: improper execution of __sync builtin.\n");
      24        reported = 1;
      25      }
      26  }
      27  
      28  void simulate_thread_other_threads ()
      29  {
      30  }
      31  
      32  int simulate_thread_step_verify ()
      33  {
      34    if (value != zero && value != max)
      35      {
      36        printf ("FAIL: invalid intermediate result for value.\n");
      37        return 1;
      38      }
      39    return 0;
      40  }
      41  
      42  int simulate_thread_final_verify ()
      43  {
      44    if (value != 0)
      45      {
      46        printf ("FAIL: invalid final result for value.\n");
      47        return 1;
      48      }
      49    return 0;
      50  }
      51  
      52  /* All values written to 'value' alternate between 'zero' and
      53     'max'. Any other value detected by simulate_thread_step_verify()
      54     between instructions would indicate that the value was only
      55     partially written, and would thus fail this atomicity test.
      56  
      57     This function tests each different __atomic routine once, with
      58     the exception of the load instruction which requires special
      59     testing.  */
      60  __attribute__((noinline))
      61  void simulate_thread_main()
      62  {
      63    
      64    ret = __atomic_exchange_n (&value, max, __ATOMIC_SEQ_CST);
      65    if (ret != zero || value != max)
      66      test_abort();
      67  
      68    __atomic_store_n (&value, zero, __ATOMIC_SEQ_CST);
      69    if (value != zero)
      70      test_abort();
      71  
      72    ret = __atomic_fetch_add (&value, max, __ATOMIC_SEQ_CST);
      73    if (value != max || ret != zero)
      74      test_abort ();
      75  
      76    ret = __atomic_fetch_sub (&value, max, __ATOMIC_SEQ_CST);
      77    if (value != zero || ret != max)
      78      test_abort ();
      79  
      80    ret = __atomic_fetch_or (&value, max, __ATOMIC_SEQ_CST);
      81    if (value != max || ret != zero)
      82      test_abort ();
      83  
      84    ret = __atomic_fetch_and (&value, max, __ATOMIC_SEQ_CST);
      85    if (value != max || ret != max)
      86      test_abort ();
      87  
      88    ret = __atomic_fetch_xor (&value, max, __ATOMIC_SEQ_CST);
      89    if (value != zero || ret != max)
      90      test_abort ();
      91  
      92    ret = __atomic_add_fetch (&value, max, __ATOMIC_SEQ_CST);
      93    if (value != max || ret != max)
      94      test_abort ();
      95  
      96    ret = __atomic_sub_fetch (&value, max, __ATOMIC_SEQ_CST);
      97    if (value != zero || ret != zero)
      98      test_abort ();
      99  
     100    ret = __atomic_or_fetch (&value, max, __ATOMIC_SEQ_CST);
     101    if (value != max || ret != max)
     102      test_abort ();
     103  
     104    ret = __atomic_and_fetch (&value, max, __ATOMIC_SEQ_CST);
     105    if (value != max || ret != max)
     106      test_abort ();
     107  
     108    ret = __atomic_xor_fetch (&value, max, __ATOMIC_SEQ_CST);
     109    if (value != zero || ret != zero)
     110      test_abort ();
     111  }
     112  
     113  int
     114  main ()
     115  {
     116    simulate_thread_main ();
     117    simulate_thread_done ();
     118    return 0;
     119  }