88212deec3daf40efa9de7dbdbd689ffc0ad88b8
[mono.git] / mono / io-layer / atomic.c
1 #include <config.h>
2 #include <glib.h>
3 #include <pthread.h>
4
5 #include "mono/io-layer/wapi.h"
6
7 #ifndef WAPI_ATOMIC_ASM
8 #warning "Atomic functions are not atomic!"
9
10 static pthread_spinlock_t spin;
11 static pthread_once_t spin_once=PTHREAD_ONCE_INIT;
12
13 static void spin_init(void)
14 {
15         pthread_spin_init(&spin, 0);
16         g_warning("Using non-atomic functions!");
17 }
18
19 gint32 InterlockedCompareExchange(volatile gint32 *dest, gint32 exch,
20                                   gint32 comp)
21 {
22         gint32 old;
23         
24         pthread_once(&spin_once, spin_init);
25         pthread_spin_lock(&spin);
26         
27         old= *dest;
28         if(old==comp) {
29                 *dest=exch;
30         }
31         
32         pthread_spin_unlock(&spin);
33
34         return(old);
35 }
36
37 gpointer InterlockedCompareExchangePointer(volatile gpointer *dest,
38                                            gpointer exch, gpointer comp)
39 {
40         gpointer old;
41         
42         pthread_once(&spin_once, spin_init);
43         pthread_spin_lock(&spin);
44         
45         old= *dest;
46         if(old==comp) {
47                 *dest=exch;
48         }
49         
50         pthread_spin_unlock(&spin);
51
52         return(old);
53 }
54
55 gint32 InterlockedIncrement(volatile gint32 *dest)
56 {
57         gint32 ret;
58         
59         pthread_once(&spin_once, spin_init);
60         pthread_spin_lock(&spin);
61         
62         *dest++;
63         ret= *dest;
64         
65         pthread_spin_unlock(&spin);
66         
67         return(ret);
68 }
69
70 gint32 InterlockedDecrement(volatile gint32 *dest)
71 {
72         gint32 ret;
73         
74         pthread_once(&spin_once, spin_init);
75         pthread_spin_lock(&spin);
76         
77         *dest--;
78         ret= *dest;
79         
80         pthread_spin_unlock(&spin);
81         
82         return(ret);
83 }
84
85 gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch)
86 {
87         gint32 ret;
88         
89         pthread_once(&spin_once, spin_init);
90         pthread_spin_lock(&spin);
91
92         ret=*dest;
93         *dest=exch;
94         
95         pthread_spin_unlock(&spin);
96         
97         return(ret);
98 }
99
100 gpointer InterlockedExchangePointer(volatile gpointer *dest, gpointer exch)
101 {
102         gpointer ret;
103         
104         pthread_once(&spin_once, spin_init);
105         pthread_spin_lock(&spin);
106         
107         ret=*dest;
108         *dest=exch;
109         
110         pthread_spin_unlock(&spin);
111         
112         return(ret);
113 }
114
115 gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
116 {
117         gint32 ret;
118         
119         pthread_once(&spin_once, spin_init);
120         pthread_spin_lock(&spin);
121
122         ret= *dest;
123         *dest+=add;
124         
125         pthread_spin_unlock(&spin);
126         
127         return(ret);
128 }
129
130 #endif