grammar updates
[mono.git] / mono / io-layer / atomic.c
1 /*
2  * atomic.c:  Workarounds for atomic operations for platforms that dont have
3  *            really atomic asm functions in atomic.h
4  *
5  * Author:
6  *      Dick Porter (dick@ximian.com)
7  *
8  * (C) 2002 Ximian, Inc.
9  */
10
11 #include <config.h>
12 #include <glib.h>
13 #include <pthread.h>
14
15 #include "mono/io-layer/wapi.h"
16
17 #ifdef WAPI_ATOMIC_ASM
18 #if defined(sparc) || defined (__sparc__)
19 volatile unsigned char _wapi_sparc_lock;
20 #endif
21 #else
22
23 static pthread_mutex_t spin;
24 static mono_once_t spin_once=MONO_ONCE_INIT;
25
26 static void spin_init(void)
27 {
28         pthread_mutex_init(&spin, 0);
29         g_warning("Using non-atomic functions!");
30 }
31
32 gint32 InterlockedCompareExchange(volatile gint32 *dest, gint32 exch,
33                                   gint32 comp)
34 {
35         gint32 old;
36         
37         mono_once(&spin_once, spin_init);
38         pthread_mutex_lock(&spin);
39         
40         old= *dest;
41         if(old==comp) {
42                 *dest=exch;
43         }
44         
45         pthread_mutex_unlock(&spin);
46
47         return(old);
48 }
49
50 gpointer InterlockedCompareExchangePointer(volatile gpointer *dest,
51                                            gpointer exch, gpointer comp)
52 {
53         gpointer old;
54         
55         mono_once(&spin_once, spin_init);
56         pthread_mutex_lock(&spin);
57         
58         old= *dest;
59         if(old==comp) {
60                 *dest=exch;
61         }
62         
63         pthread_mutex_unlock(&spin);
64
65         return(old);
66 }
67
68 gint32 InterlockedIncrement(volatile gint32 *dest)
69 {
70         gint32 ret;
71         
72         mono_once(&spin_once, spin_init);
73         pthread_mutex_lock(&spin);
74         
75         *dest++;
76         ret= *dest;
77         
78         pthread_mutex_unlock(&spin);
79         
80         return(ret);
81 }
82
83 gint32 InterlockedDecrement(volatile gint32 *dest)
84 {
85         gint32 ret;
86         
87         mono_once(&spin_once, spin_init);
88         pthread_mutex_lock(&spin);
89         
90         *dest--;
91         ret= *dest;
92         
93         pthread_mutex_unlock(&spin);
94         
95         return(ret);
96 }
97
98 gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch)
99 {
100         gint32 ret;
101         
102         mono_once(&spin_once, spin_init);
103         pthread_mutex_lock(&spin);
104
105         ret=*dest;
106         *dest=exch;
107         
108         pthread_mutex_unlock(&spin);
109         
110         return(ret);
111 }
112
113 gpointer InterlockedExchangePointer(volatile gpointer *dest, gpointer exch)
114 {
115         gpointer ret;
116         
117         mono_once(&spin_once, spin_init);
118         pthread_mutex_lock(&spin);
119         
120         ret=*dest;
121         *dest=exch;
122         
123         pthread_mutex_unlock(&spin);
124         
125         return(ret);
126 }
127
128 gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
129 {
130         gint32 ret;
131         
132         mono_once(&spin_once, spin_init);
133         pthread_mutex_lock(&spin);
134
135         ret= *dest;
136         *dest+=add;
137         
138         pthread_mutex_unlock(&spin);
139         
140         return(ret);
141 }
142
143 #endif