implemented Setup.hs to build boehm cpp libs and install them;
[hs-boehmgc.git] / gc-7.2 / libatomic_ops / src / atomic_ops / sysdeps / generic_pthread.h
1 /*
2  * Copyright (c) 2003 by Hewlett-Packard Company.  All rights reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22
23 /* The following is useful primarily for debugging and documentation.   */
24 /* We define various atomic operations by acquiring a global pthread    */
25 /* lock.  The resulting implementation will perform poorly, but should  */
26 /* be correct unless it is used from signal handlers.                   */
27 /* We assume that all pthread operations act like full memory barriers. */
28 /* (We believe that is the intent of the specification.)                */
29
30 #include <pthread.h>
31
32 #include "test_and_set_t_is_ao_t.h"
33         /* This is not necessarily compatible with the native           */
34         /* implementation.  But those can't be safely mixed anyway.     */
35
36 /* We define only the full barrier variants, and count on the           */
37 /* generalization section below to fill in the rest.                    */
38 extern pthread_mutex_t AO_pt_lock;
39
40 AO_INLINE void
41 AO_nop_full(void)
42 {
43   pthread_mutex_lock(&AO_pt_lock);
44   pthread_mutex_unlock(&AO_pt_lock);
45 }
46 #define AO_HAVE_nop_full
47
48 AO_INLINE AO_t
49 AO_load_full(const volatile AO_t *addr)
50 {
51   AO_t result;
52   pthread_mutex_lock(&AO_pt_lock);
53   result = *addr;
54   pthread_mutex_unlock(&AO_pt_lock);
55   return result;
56 }
57 #define AO_HAVE_load_full
58
59 AO_INLINE void
60 AO_store_full(volatile AO_t *addr, AO_t val)
61 {
62   pthread_mutex_lock(&AO_pt_lock);
63   *addr = val;
64   pthread_mutex_unlock(&AO_pt_lock);
65 }
66 #define AO_HAVE_store_full
67
68 AO_INLINE unsigned char
69 AO_char_load_full(const volatile unsigned char *addr)
70 {
71   unsigned char result;
72   pthread_mutex_lock(&AO_pt_lock);
73   result = *addr;
74   pthread_mutex_unlock(&AO_pt_lock);
75   return result;
76 }
77 #define AO_HAVE_char_load_full
78
79 AO_INLINE void
80 AO_char_store_full(volatile unsigned char *addr, unsigned char val)
81 {
82   pthread_mutex_lock(&AO_pt_lock);
83   *addr = val;
84   pthread_mutex_unlock(&AO_pt_lock);
85 }
86 #define AO_HAVE_char_store_full
87
88 AO_INLINE unsigned short
89 AO_short_load_full(const volatile unsigned short *addr)
90 {
91   unsigned short result;
92   pthread_mutex_lock(&AO_pt_lock);
93   result = *addr;
94   pthread_mutex_unlock(&AO_pt_lock);
95   return result;
96 }
97 #define AO_HAVE_short_load_full
98
99 AO_INLINE void
100 AO_short_store_full(volatile unsigned short *addr, unsigned short val)
101 {
102   pthread_mutex_lock(&AO_pt_lock);
103   *addr = val;
104   pthread_mutex_unlock(&AO_pt_lock);
105 }
106 #define AO_HAVE_short_store_full
107
108 AO_INLINE unsigned int
109 AO_int_load_full(const volatile unsigned int *addr)
110 {
111   unsigned int result;
112   pthread_mutex_lock(&AO_pt_lock);
113   result = *addr;
114   pthread_mutex_unlock(&AO_pt_lock);
115   return result;
116 }
117 #define AO_HAVE_int_load_full
118
119 AO_INLINE void
120 AO_int_store_full(volatile unsigned int *addr, unsigned int val)
121 {
122   pthread_mutex_lock(&AO_pt_lock);
123   *addr = val;
124   pthread_mutex_unlock(&AO_pt_lock);
125 }
126 #define AO_HAVE_int_store_full
127
128 AO_INLINE AO_TS_VAL_t
129 AO_test_and_set_full(volatile AO_TS_t *addr)
130 {
131   AO_TS_VAL_t result;
132   pthread_mutex_lock(&AO_pt_lock);
133   result = (AO_TS_VAL_t)(*addr);
134   *addr = AO_TS_SET;
135   pthread_mutex_unlock(&AO_pt_lock);
136   assert(result == AO_TS_SET || result == AO_TS_CLEAR);
137   return result;
138 }
139 #define AO_HAVE_test_and_set_full
140
141 AO_INLINE AO_t
142 AO_fetch_and_add_full(volatile AO_t *p, AO_t incr)
143 {
144   AO_t tmp;
145
146   pthread_mutex_lock(&AO_pt_lock);
147   tmp = *p;
148   *p = tmp + incr;
149   pthread_mutex_unlock(&AO_pt_lock);
150   return tmp;
151 }
152 #define AO_HAVE_fetch_and_add_full
153
154 AO_INLINE unsigned char
155 AO_char_fetch_and_add_full(volatile unsigned char *p, unsigned char incr)
156 {
157   unsigned char tmp;
158
159   pthread_mutex_lock(&AO_pt_lock);
160   tmp = *p;
161   *p = tmp + incr;
162   pthread_mutex_unlock(&AO_pt_lock);
163   return tmp;
164 }
165 #define AO_HAVE_char_fetch_and_add_full
166
167 AO_INLINE unsigned short
168 AO_short_fetch_and_add_full(volatile unsigned short *p, unsigned short incr)
169 {
170   unsigned short tmp;
171
172   pthread_mutex_lock(&AO_pt_lock);
173   tmp = *p;
174   *p = tmp + incr;
175   pthread_mutex_unlock(&AO_pt_lock);
176   return tmp;
177 }
178 #define AO_HAVE_short_fetch_and_add_full
179
180 AO_INLINE unsigned int
181 AO_int_fetch_and_add_full(volatile unsigned int *p, unsigned int incr)
182 {
183   unsigned int tmp;
184
185   pthread_mutex_lock(&AO_pt_lock);
186   tmp = *p;
187   *p = tmp + incr;
188   pthread_mutex_unlock(&AO_pt_lock);
189   return tmp;
190 }
191 #define AO_HAVE_int_fetch_and_add_full
192
193 AO_INLINE void
194 AO_or_full(volatile AO_t *p, AO_t incr)
195 {
196   AO_t tmp;
197
198   pthread_mutex_lock(&AO_pt_lock);
199   tmp = *p;
200   *p = (tmp | incr);
201   pthread_mutex_unlock(&AO_pt_lock);
202 }
203 #define AO_HAVE_or_full
204
205 AO_INLINE int
206 AO_compare_and_swap_full(volatile AO_t *addr,
207                              AO_t old, AO_t new_val)
208 {
209   pthread_mutex_lock(&AO_pt_lock);
210   if (*addr == old)
211     {
212       *addr = new_val;
213       pthread_mutex_unlock(&AO_pt_lock);
214       return 1;
215     }
216   else
217     pthread_mutex_unlock(&AO_pt_lock);
218     return 0;
219 }
220 #define AO_HAVE_compare_and_swap_full
221
222 /* Unlike real architectures, we define both double-width CAS variants. */
223
224 typedef struct {
225         AO_t AO_val1;
226         AO_t AO_val2;
227 } AO_double_t;
228 #define AO_HAVE_double_t
229
230 AO_INLINE int
231 AO_compare_double_and_swap_double_full(volatile AO_double_t *addr,
232                                        AO_t old1, AO_t old2,
233                                        AO_t new1, AO_t new2)
234 {
235   pthread_mutex_lock(&AO_pt_lock);
236   if (addr -> AO_val1 == old1 && addr -> AO_val2 == old2)
237     {
238       addr -> AO_val1 = new1;
239       addr -> AO_val2 = new2;
240       pthread_mutex_unlock(&AO_pt_lock);
241       return 1;
242     }
243   else
244     pthread_mutex_unlock(&AO_pt_lock);
245     return 0;
246 }
247 #define AO_HAVE_compare_double_and_swap_double_full
248
249 AO_INLINE int
250 AO_compare_and_swap_double_full(volatile AO_double_t *addr,
251                                 AO_t old1,
252                                 AO_t new1, AO_t new2)
253 {
254   pthread_mutex_lock(&AO_pt_lock);
255   if (addr -> AO_val1 == old1)
256     {
257       addr -> AO_val1 = new1;
258       addr -> AO_val2 = new2;
259       pthread_mutex_unlock(&AO_pt_lock);
260       return 1;
261     }
262   else
263     pthread_mutex_unlock(&AO_pt_lock);
264     return 0;
265 }
266 #define AO_HAVE_compare_and_swap_double_full
267
268 /* We can't use hardware loads and stores, since they don't     */
269 /* interact correctly with atomic updates.                      */