2 * Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P.
3 * Original Author: Hans Boehm
5 * This file may be redistributed and/or modified under the
6 * terms of the GNU General Public License as published by the Free Software
7 * Foundation; either version 2, or (at your option) any later version.
9 * It is distributed in the hope that it will be useful, but WITHOUT ANY
10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License in the
12 * file doc/COPYING for more details.
15 #if defined(HAVE_CONFIG_H)
20 #include "run_parallel.inc"
22 #include "test_atomic_include.h"
24 #ifdef AO_USE_PTHREAD_DEFS
25 # define NITERS 100000
27 # define NITERS 10000000
30 #if defined(AO_HAVE_fetch_and_add1) && defined(AO_HAVE_fetch_and_sub1)
34 void * add1sub1_thr(void * id)
36 int me = (int)(long)id;
40 for (i = 0; i < NITERS; ++i)
42 AO_fetch_and_sub1(&counter);
44 AO_fetch_and_add1(&counter);
49 int add1sub1_test(void)
54 #endif /* defined(AO_HAVE_fetch_and_add1) && defined(AO_HAVE_fetch_and_sub1) */
56 #if defined(AO_HAVE_store_release_write) && defined(AO_HAVE_load_acquire_read)
58 /* Invariant: counter1 >= counter2 */
62 void * acqrel_thr(void *id)
64 int me = (int)(long)id;
68 for (i = 0; i < NITERS; ++i)
73 fprintf(stderr, "acqrel test: too many threads\n");
74 my_counter1 = AO_load(&counter1);
75 AO_store(&counter1, my_counter1 + 1);
76 AO_store_release_write(&counter2, my_counter1 + 1);
80 AO_t my_counter1a, my_counter2a;
81 AO_t my_counter1b, my_counter2b;
83 my_counter2a = AO_load_acquire_read(&counter2);
84 my_counter1a = AO_load(&counter1);
85 /* Redo this, to make sure that the second load of counter1 */
86 /* is not viewed as a common subexpression. */
87 my_counter2b = AO_load_acquire_read(&counter2);
88 my_counter1b = AO_load(&counter1);
89 if (my_counter1a < my_counter2a)
91 fprintf(stderr, "Saw release store out of order: %lu < %lu\n",
92 (unsigned long)my_counter1a, (unsigned long)my_counter2a);
95 if (my_counter1b < my_counter2b)
98 "Saw release store out of order (bad CSE?): %lu < %lu\n",
99 (unsigned long)my_counter1b, (unsigned long)my_counter2b);
107 int acqrel_test(void)
109 return counter1 == NITERS && counter2 == NITERS;
112 #endif /* AO_HAVE_store_release_write && AO_HAVE_load_acquire_read */
114 #if defined(AO_HAVE_test_and_set_acquire)
116 AO_TS_T lock = AO_TS_INITIALIZER;
118 unsigned long locked_counter;
119 volatile unsigned long junk = 13;
121 void * test_and_set_thr(void * id)
125 for (i = 0; i < NITERS/10; ++i)
127 while (AO_test_and_set_acquire(&lock) != AO_TS_CLEAR);
129 if (locked_counter != 1)
131 fprintf(stderr, "Test and set failure 1, counter = %ld\n",
139 if (locked_counter != 1)
141 fprintf(stderr, "Test and set failure 2, counter = %ld\n",
147 /* Spend a bit of time outside the lock. */
154 int test_and_set_test(void)
156 return locked_counter == 0;
159 #endif /* defined(AO_HAVE_test_and_set_acquire) */
164 test_atomic_acquire();
165 test_atomic_release();
169 test_atomic_release_write();
170 test_atomic_acquire_read();
171 # if defined(AO_HAVE_fetch_and_add1) && defined(AO_HAVE_fetch_and_sub1)
172 run_parallel(4, add1sub1_thr, add1sub1_test, "add1/sub1");
174 # if defined(AO_HAVE_store_release_write) && defined(AO_HAVE_load_acquire_read)
175 run_parallel(3, acqrel_thr, acqrel_test,
176 "store_release_write/load_acquire_read");
178 # if defined(AO_HAVE_test_and_set_acquire)
179 run_parallel(5, test_and_set_thr, test_and_set_test,