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 void * add1sub1_thr(void * id);
31 int add1sub1_test(void);
32 void * acqrel_thr(void *id);
33 int acqrel_test(void);
34 void * test_and_set_thr(void * id);
35 int test_and_set_test(void);
37 #if defined(AO_HAVE_fetch_and_add1) && defined(AO_HAVE_fetch_and_sub1)
41 void * add1sub1_thr(void * id)
43 int me = (int)(long)id;
47 for (i = 0; i < NITERS; ++i)
49 AO_fetch_and_sub1(&counter);
51 AO_fetch_and_add1(&counter);
56 int add1sub1_test(void)
61 #endif /* defined(AO_HAVE_fetch_and_add1) && defined(AO_HAVE_fetch_and_sub1) */
63 #if defined(AO_HAVE_store_release_write) && defined(AO_HAVE_load_acquire_read)
65 /* Invariant: counter1 >= counter2 */
69 void * acqrel_thr(void *id)
71 int me = (int)(long)id;
75 for (i = 0; i < NITERS; ++i)
80 fprintf(stderr, "acqrel test: too many threads\n");
81 my_counter1 = AO_load(&counter1);
82 AO_store(&counter1, my_counter1 + 1);
83 AO_store_release_write(&counter2, my_counter1 + 1);
87 AO_t my_counter1a, my_counter2a;
88 AO_t my_counter1b, my_counter2b;
90 my_counter2a = AO_load_acquire_read(&counter2);
91 my_counter1a = AO_load(&counter1);
92 /* Redo this, to make sure that the second load of counter1 */
93 /* is not viewed as a common subexpression. */
94 my_counter2b = AO_load_acquire_read(&counter2);
95 my_counter1b = AO_load(&counter1);
96 if (my_counter1a < my_counter2a)
98 fprintf(stderr, "Saw release store out of order: %lu < %lu\n",
99 (unsigned long)my_counter1a, (unsigned long)my_counter2a);
102 if (my_counter1b < my_counter2b)
105 "Saw release store out of order (bad CSE?): %lu < %lu\n",
106 (unsigned long)my_counter1b, (unsigned long)my_counter2b);
114 int acqrel_test(void)
116 return counter1 == NITERS && counter2 == NITERS;
119 #endif /* AO_HAVE_store_release_write && AO_HAVE_load_acquire_read */
121 #if defined(AO_HAVE_test_and_set_acquire)
123 AO_TS_T lock = AO_TS_INITIALIZER;
125 unsigned long locked_counter;
126 volatile unsigned long junk = 13;
128 void * test_and_set_thr(void * id)
132 for (i = 0; i < NITERS/10; ++i)
134 while (AO_test_and_set_acquire(&lock) != AO_TS_CLEAR);
136 if (locked_counter != 1)
138 fprintf(stderr, "Test and set failure 1, counter = %ld\n",
146 if (locked_counter != 1)
148 fprintf(stderr, "Test and set failure 2, counter = %ld\n",
154 /* Spend a bit of time outside the lock. */
161 int test_and_set_test(void)
163 return locked_counter == 0;
166 #endif /* defined(AO_HAVE_test_and_set_acquire) */
171 test_atomic_acquire();
172 test_atomic_release();
176 test_atomic_release_write();
177 test_atomic_acquire_read();
178 # if defined(AO_HAVE_fetch_and_add1) && defined(AO_HAVE_fetch_and_sub1)
179 run_parallel(4, add1sub1_thr, add1sub1_test, "add1/sub1");
181 # if defined(AO_HAVE_store_release_write) && defined(AO_HAVE_load_acquire_read)
182 run_parallel(3, acqrel_thr, acqrel_test,
183 "store_release_write/load_acquire_read");
185 # if defined(AO_HAVE_test_and_set_acquire)
186 run_parallel(5, test_and_set_thr, test_and_set_test,