(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
atomic/
c11-atomic-exec-4.c
       1  /* Test for _Atomic in C11.  Test that compare-and-exchange is
       2     operating properly when operations on the same variable are carried
       3     out in two threads.  */
       4  /* { dg-do run } */
       5  /* { dg-options "-std=c11 -pedantic-errors -pthread -U_POSIX_C_SOURCE -D_POSIX_C_SOURCE=200809L" } */
       6  /* { dg-additional-options "-D_XOPEN_SOURCE=600" { target *-*-solaris2* } } */
       7  /* { dg-additional-options "-D_HPUX_SOURCE" { target *-*-hpux* } } */
       8  /* { dg-require-effective-target pthread } */
       9  
      10  #include <stdint.h>
      11  #include <pthread.h>
      12  #include <stdbool.h>
      13  #include <stdio.h>
      14  #include <stdlib.h>
      15  
      16  #define ITER_COUNT 10000
      17  
      18  static volatile _Atomic bool thread_ready;
      19  
      20  /* Generate test code (with NAME used to name functions and variables)
      21     for atomic compound assignments to a variable of type LHSTYPE.  The
      22     variable is initialized to INIT, then PRE var POST is executed
      23     ITER_COUNT times in each of two threads, and the final result
      24     should be FINAL.  A function test_main_##NAME is generated that
      25     returns nonzero on failure, zero on success.  */
      26  
      27  #define TEST_FUNCS(NAME, LHSTYPE, PRE, POST, INIT, FINAL)		\
      28  									\
      29  static volatile _Atomic LHSTYPE var_##NAME = (INIT);			\
      30  									\
      31  static void *								\
      32  test_thread_##NAME (void *arg)						\
      33  {									\
      34    thread_ready = true;							\
      35    for (int i = 0; i < ITER_COUNT; i++)					\
      36      {									\
      37        sched_yield ();							\
      38        PRE var_##NAME POST;						\
      39      }									\
      40    return NULL;								\
      41  }									\
      42  									\
      43  static int								\
      44  test_main_##NAME (void)							\
      45  {									\
      46    thread_ready = false;							\
      47    pthread_t thread_id;							\
      48    int pret = pthread_create (&thread_id, NULL, test_thread_##NAME,	\
      49  			     NULL);					\
      50    if (pret != 0)							\
      51      {									\
      52        printf ("pthread_create failed: %d\n", pret);			\
      53        return 1;								\
      54      }									\
      55    while (!thread_ready)							\
      56      sched_yield ();							\
      57    for (int i = 0; i < ITER_COUNT; i++)					\
      58      {									\
      59        PRE var_##NAME POST;						\
      60        sched_yield ();							\
      61      }									\
      62    pthread_join (thread_id, NULL);					\
      63    if (var_##NAME != (FINAL))						\
      64      {									\
      65        printf (#NAME " failed\n");					\
      66        return 1;								\
      67      }									\
      68    else									\
      69      {									\
      70        printf (#NAME " passed\n");					\
      71        return 0;								\
      72      }									\
      73  }
      74  
      75  TEST_FUNCS (uint8_add, uint8_t, , += 1, 0, (uint8_t) 20000)
      76  TEST_FUNCS (uint8_add_3, uint8_t, , += 3, 0, (uint8_t) 60000)
      77  TEST_FUNCS (uint16_add, uint16_t, , += 1, 0, (uint16_t) 20000)
      78  TEST_FUNCS (uint16_add_3, uint16_t, , += 3, 0, (uint16_t) 60000)
      79  TEST_FUNCS (uint32_add, uint32_t, , += 1, 0, (uint32_t) 20000)
      80  TEST_FUNCS (uint32_add_3, uint32_t, , += 3, 0, (uint32_t) 60000)
      81  TEST_FUNCS (uint64_add, uint64_t, , += 1, 0, (uint64_t) 20000)
      82  TEST_FUNCS (uint64_add_3, uint64_t, , += 3, 0, (uint64_t) 60000)
      83  TEST_FUNCS (uint64_add_neg, uint64_t, , += 1, -10000, (uint64_t) 10000)
      84  TEST_FUNCS (float_add, float, , += 1, 0, 20000)
      85  TEST_FUNCS (double_add, double, , += 1, 0, 20000)
      86  TEST_FUNCS (long_double_add, long double, , += 1, 0, 20000)
      87  TEST_FUNCS (complex_float_add, _Complex float, , += 1, 0, 20000)
      88  TEST_FUNCS (complex_double_add, _Complex double, , += 1, 0, 20000)
      89  TEST_FUNCS (complex_long_double_add, _Complex long double, , += 1, 0, 20000)
      90  TEST_FUNCS (uint8_postinc, uint8_t, , ++, 0, (uint8_t) 20000)
      91  TEST_FUNCS (uint16_postinc, uint16_t, , ++, 0, (uint16_t) 20000)
      92  TEST_FUNCS (uint32_postinc, uint32_t, , ++, 0, (uint32_t) 20000)
      93  TEST_FUNCS (uint64_postinc, uint64_t, , ++, 0, (uint64_t) 20000)
      94  TEST_FUNCS (uint64_postinc_neg, uint64_t, , ++, -10000, (uint64_t) 10000)
      95  TEST_FUNCS (float_postinc, float, , ++, 0, 20000)
      96  TEST_FUNCS (double_postinc, double, , ++, 0, 20000)
      97  TEST_FUNCS (long_double_postinc, long double, , ++, 0, 20000)
      98  TEST_FUNCS (uint8_preinc, uint8_t, ++, , 0, (uint8_t) 20000)
      99  TEST_FUNCS (uint16_preinc, uint16_t, ++, , 0, (uint16_t) 20000)
     100  TEST_FUNCS (uint32_preinc, uint32_t, ++, , 0, (uint32_t) 20000)
     101  TEST_FUNCS (uint64_preinc, uint64_t, ++, , 0, (uint64_t) 20000)
     102  TEST_FUNCS (uint64_preinc_neg, uint64_t, ++, , -10000, (uint64_t) 10000)
     103  TEST_FUNCS (float_preinc, float, ++, , 0, 20000)
     104  TEST_FUNCS (double_preinc, double, ++, , 0, 20000)
     105  TEST_FUNCS (long_double_preinc, long double, ++, , 0, 20000)
     106  TEST_FUNCS (uint8_sub, uint8_t, , -= 1, 0, (uint8_t) -20000)
     107  TEST_FUNCS (uint8_sub_3, uint8_t, , -= 3, 0, (uint8_t) -60000)
     108  TEST_FUNCS (uint16_sub, uint16_t, , -= 1, 0, (uint16_t) -20000)
     109  TEST_FUNCS (uint16_sub_3, uint16_t, , -= 3, 0, (uint16_t) -60000)
     110  TEST_FUNCS (uint32_sub, uint32_t, , -= 1, 0, (uint32_t) -20000)
     111  TEST_FUNCS (uint32_sub_3, uint32_t, , -= 3, 0, (uint32_t) -60000)
     112  TEST_FUNCS (uint64_sub, uint64_t, , -= 1, 0, (uint64_t) -20000)
     113  TEST_FUNCS (uint64_sub_3, uint64_t, , -= 3, 0, (uint64_t) -60000)
     114  TEST_FUNCS (uint64_sub_neg, uint64_t, , -= 1, 10000, (uint64_t) -10000)
     115  TEST_FUNCS (float_sub, float, , -= 1, 0, -20000)
     116  TEST_FUNCS (double_sub, double, , -= 1, 0, -20000)
     117  TEST_FUNCS (long_double_sub, long double, , -= 1, 0, -20000)
     118  TEST_FUNCS (complex_float_sub, _Complex float, , -= 1, 0, -20000)
     119  TEST_FUNCS (complex_double_sub, _Complex double, , -= 1, 0, -20000)
     120  TEST_FUNCS (complex_long_double_sub, _Complex long double, , -= 1, 0, -20000)
     121  TEST_FUNCS (uint8_postdec, uint8_t, , --, 0, (uint8_t) -20000)
     122  TEST_FUNCS (uint16_postdec, uint16_t, , --, 0, (uint16_t) -20000)
     123  TEST_FUNCS (uint32_postdec, uint32_t, , --, 0, (uint32_t) -20000)
     124  TEST_FUNCS (uint64_postdec, uint64_t, , --, 0, (uint64_t) -20000)
     125  TEST_FUNCS (uint64_postdec_neg, uint64_t, , --, 10000, (uint64_t) -10000)
     126  TEST_FUNCS (float_postdec, float, , --, 0, -20000)
     127  TEST_FUNCS (double_postdec, double, , --, 0, -20000)
     128  TEST_FUNCS (long_double_postdec, long double, , --, 0, -20000)
     129  TEST_FUNCS (uint8_predec, uint8_t, --, , 0, (uint8_t) -20000)
     130  TEST_FUNCS (uint16_predec, uint16_t, --, , 0, (uint16_t) -20000)
     131  TEST_FUNCS (uint32_predec, uint32_t, --, , 0, (uint32_t) -20000)
     132  TEST_FUNCS (uint64_predec, uint64_t, --, , 0, (uint64_t) -20000)
     133  TEST_FUNCS (uint64_predec_neg, uint64_t, --, , 10000, (uint64_t) -10000)
     134  TEST_FUNCS (float_predec, float, --, , 0, -20000)
     135  TEST_FUNCS (double_predec, double, --, , 0, -20000)
     136  TEST_FUNCS (long_double_predec, long double, --, , 0, -20000)
     137  TEST_FUNCS (uint8_mul, uint8_t, , *= 3, 1, (uint8_t) 0x81)
     138  TEST_FUNCS (uint16_mul, uint16_t, , *= 3, 1, (uint16_t) 0x9681)
     139  TEST_FUNCS (uint32_mul, uint32_t, , *= 3, 1, (uint32_t) 0x62b49681U)
     140  TEST_FUNCS (uint64_mul, uint64_t, , *= 3, 1, (uint64_t) 0xcd926beb62b49681ULL)
     141  
     142  int
     143  main (void)
     144  {
     145    int ret = 0;
     146    ret |= test_main_uint8_add ();
     147    ret |= test_main_uint8_add_3 ();
     148    ret |= test_main_uint16_add ();
     149    ret |= test_main_uint16_add_3 ();
     150    ret |= test_main_uint32_add ();
     151    ret |= test_main_uint32_add_3 ();
     152    ret |= test_main_uint64_add ();
     153    ret |= test_main_uint64_add_3 ();
     154    ret |= test_main_uint64_add_neg ();
     155    ret |= test_main_float_add ();
     156    ret |= test_main_double_add ();
     157    ret |= test_main_long_double_add ();
     158    ret |= test_main_complex_float_add ();
     159    ret |= test_main_complex_double_add ();
     160    ret |= test_main_complex_long_double_add ();
     161    ret |= test_main_uint8_postinc ();
     162    ret |= test_main_uint16_postinc ();
     163    ret |= test_main_uint32_postinc ();
     164    ret |= test_main_uint64_postinc ();
     165    ret |= test_main_uint64_postinc_neg ();
     166    ret |= test_main_float_postinc ();
     167    ret |= test_main_double_postinc ();
     168    ret |= test_main_long_double_postinc ();
     169    ret |= test_main_uint8_preinc ();
     170    ret |= test_main_uint16_preinc ();
     171    ret |= test_main_uint32_preinc ();
     172    ret |= test_main_uint64_preinc ();
     173    ret |= test_main_uint64_preinc_neg ();
     174    ret |= test_main_float_preinc ();
     175    ret |= test_main_double_preinc ();
     176    ret |= test_main_long_double_preinc ();
     177    ret |= test_main_uint8_sub ();
     178    ret |= test_main_uint8_sub_3 ();
     179    ret |= test_main_uint16_sub ();
     180    ret |= test_main_uint16_sub_3 ();
     181    ret |= test_main_uint32_sub ();
     182    ret |= test_main_uint32_sub_3 ();
     183    ret |= test_main_uint64_sub ();
     184    ret |= test_main_uint64_sub_3 ();
     185    ret |= test_main_uint64_sub_neg ();
     186    ret |= test_main_float_sub ();
     187    ret |= test_main_double_sub ();
     188    ret |= test_main_long_double_sub ();
     189    ret |= test_main_complex_float_sub ();
     190    ret |= test_main_complex_double_sub ();
     191    ret |= test_main_complex_long_double_sub ();
     192    ret |= test_main_uint8_postdec ();
     193    ret |= test_main_uint16_postdec ();
     194    ret |= test_main_uint32_postdec ();
     195    ret |= test_main_uint64_postdec ();
     196    ret |= test_main_uint64_postdec_neg ();
     197    ret |= test_main_float_postdec ();
     198    ret |= test_main_double_postdec ();
     199    ret |= test_main_long_double_postdec ();
     200    ret |= test_main_uint8_predec ();
     201    ret |= test_main_uint16_predec ();
     202    ret |= test_main_uint32_predec ();
     203    ret |= test_main_uint64_predec ();
     204    ret |= test_main_uint64_predec_neg ();
     205    ret |= test_main_float_predec ();
     206    ret |= test_main_double_predec ();
     207    ret |= test_main_long_double_predec ();
     208    ret |= test_main_uint8_mul ();
     209    ret |= test_main_uint16_mul ();
     210    ret |= test_main_uint32_mul ();
     211    ret |= test_main_uint64_mul ();
     212    if (ret)
     213      abort ();
     214    else
     215      exit (0);
     216  }