~ubuntu-branches/ubuntu/quantal/libgc/quantal

« back to all changes in this revision

Viewing changes to libatomic_ops-1.2/tests/test_atomic.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Egger
  • Date: 2011-03-02 13:43:18 UTC
  • mfrom: (1.2.5 upstream) (3.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20110302134318-82ful0us5ce82qe8
Tags: 1:7.1-7
* Add ppc64 symbol file (Closes: #615469)
* Add sh4 symbol file (Closes: #614744)
* Add armhf symbol file
* Add powerpcspe symbol file
* Handle sparc64 the same as sparc
* Clear non-arch symbol file to support building on not yet captured
  architectures
* add -pthread to fix build with --no-add-needed

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  
 
2
 * Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P.
 
3
 * Original Author: Hans Boehm
 
4
 *
 
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.
 
8
 * 
 
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.
 
13
 */
 
14
 
 
15
#if defined(HAVE_CONFIG_H)
 
16
# include "config.h"
 
17
#endif
 
18
 
 
19
 
 
20
#include "run_parallel.inc"
 
21
 
 
22
#include "test_atomic_include.h"
 
23
 
 
24
#ifdef AO_USE_PTHREAD_DEFS
 
25
# define NITERS 100000
 
26
#else
 
27
# define NITERS 10000000
 
28
#endif
 
29
 
 
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);
 
36
 
 
37
#if defined(AO_HAVE_fetch_and_add1) && defined(AO_HAVE_fetch_and_sub1)
 
38
 
 
39
AO_t counter = 0;
 
40
 
 
41
void * add1sub1_thr(void * id)
 
42
{
 
43
  int me = (int)(long)id;
 
44
 
 
45
  int i;
 
46
 
 
47
  for (i = 0; i < NITERS; ++i)
 
48
    if (me & 1)
 
49
      AO_fetch_and_sub1(&counter);
 
50
    else
 
51
      AO_fetch_and_add1(&counter);
 
52
 
 
53
  return 0;
 
54
}
 
55
 
 
56
int add1sub1_test(void)
 
57
{
 
58
  return counter == 0;
 
59
}
 
60
 
 
61
#endif /* defined(AO_HAVE_fetch_and_add1) && defined(AO_HAVE_fetch_and_sub1) */
 
62
 
 
63
#if defined(AO_HAVE_store_release_write) && defined(AO_HAVE_load_acquire_read)
 
64
 
 
65
/* Invariant: counter1 >= counter2 */
 
66
AO_t counter1 = 0;
 
67
AO_t counter2 = 0;
 
68
 
 
69
void * acqrel_thr(void *id)
 
70
{
 
71
  int me = (int)(long)id;
 
72
 
 
73
  int i;
 
74
 
 
75
  for (i = 0; i < NITERS; ++i)
 
76
    if (me & 1)
 
77
      {
 
78
        AO_t my_counter1;
 
79
        if (me != 1)
 
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);
 
84
      }
 
85
    else
 
86
      {
 
87
        AO_t my_counter1a, my_counter2a;
 
88
        AO_t my_counter1b, my_counter2b;
 
89
 
 
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)
 
97
          {
 
98
            fprintf(stderr, "Saw release store out of order: %lu < %lu\n",
 
99
                    (unsigned long)my_counter1a, (unsigned long)my_counter2a);
 
100
            abort();
 
101
          }
 
102
        if (my_counter1b < my_counter2b)
 
103
          {
 
104
            fprintf(stderr,
 
105
                    "Saw release store out of order (bad CSE?): %lu < %lu\n",
 
106
                    (unsigned long)my_counter1b, (unsigned long)my_counter2b);
 
107
            abort();
 
108
          }
 
109
      }
 
110
 
 
111
  return 0;
 
112
}
 
113
 
 
114
int acqrel_test(void)
 
115
{
 
116
  return counter1 == NITERS && counter2 == NITERS;
 
117
}
 
118
 
 
119
#endif /* AO_HAVE_store_release_write && AO_HAVE_load_acquire_read */
 
120
 
 
121
#if defined(AO_HAVE_test_and_set_acquire)
 
122
 
 
123
AO_TS_T lock = AO_TS_INITIALIZER;
 
124
 
 
125
unsigned long locked_counter;
 
126
volatile unsigned long junk = 13;
 
127
 
 
128
void * test_and_set_thr(void * id)
 
129
{
 
130
  unsigned long i;
 
131
 
 
132
  for (i = 0; i < NITERS/10; ++i)
 
133
    {
 
134
      while (AO_test_and_set_acquire(&lock) != AO_TS_CLEAR);
 
135
      ++locked_counter;
 
136
      if (locked_counter != 1)
 
137
        {
 
138
          fprintf(stderr, "Test and set failure 1, counter = %ld\n",
 
139
                      locked_counter);
 
140
          abort();
 
141
        }
 
142
      locked_counter *= 2;
 
143
      locked_counter -= 1;
 
144
      locked_counter *= 5;
 
145
      locked_counter -= 4;
 
146
      if (locked_counter != 1)
 
147
        {
 
148
          fprintf(stderr, "Test and set failure 2, counter = %ld\n",
 
149
                      locked_counter);
 
150
          abort();
 
151
        }
 
152
      --locked_counter;
 
153
      AO_CLEAR(&lock);
 
154
      /* Spend a bit of time outside the lock. */
 
155
        junk *= 17;
 
156
        junk *= 17;
 
157
    }
 
158
  return 0;
 
159
}
 
160
 
 
161
int test_and_set_test(void)
 
162
{
 
163
  return locked_counter == 0;
 
164
}
 
165
 
 
166
#endif /* defined(AO_HAVE_test_and_set_acquire) */
 
167
 
 
168
int main()
 
169
{
 
170
  test_atomic();
 
171
  test_atomic_acquire();
 
172
  test_atomic_release();
 
173
  test_atomic_read();
 
174
  test_atomic_write();
 
175
  test_atomic_full();
 
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");
 
180
# endif
 
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");
 
184
# endif
 
185
# if defined(AO_HAVE_test_and_set_acquire)
 
186
    run_parallel(5, test_and_set_thr, test_and_set_test,
 
187
                 "test_and_set");
 
188
# endif
 
189
  return 0;
 
190
}