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,