cygwin needs to link another library now
[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 #ifndef WAPI_ATOMIC_ASM
18 #warning "Atomic functions are not atomic!"
19
20 static pthread_mutex_t spin;
21 static mono_once_t spin_once=MONO_ONCE_INIT;
22
23 static void spin_init(void)
24 {
25         pthread_mutex_init(&spin, 0);
26         g_warning("Using non-atomic functions!");
27 }
28
29 gint32 InterlockedCompareExchange(volatile gint32 *dest, gint32 exch,
30                                   gint32 comp)
31 {
32         gint32 old;
33         
34         mono_once(&spin_once, spin_init);
35         pthread_mutex_lock(&spin);
36         
37         old= *dest;
38         if(old==comp) {
39                 *dest=exch;
40         }
41         
42         pthread_mutex_unlock(&spin);
43
44         return(old);
45 }
46
47 gpointer InterlockedCompareExchangePointer(volatile gpointer *dest,
48                                            gpointer exch, gpointer comp)
49 {
50         gpointer old;
51         
52         mono_once(&spin_once, spin_init);
53         pthread_mutex_lock(&spin);
54         
55         old= *dest;
56         if(old==comp) {
57                 *dest=exch;
58         }
59         
60         pthread_mutex_unlock(&spin);
61
62         return(old);
63 }
64
65 gint32 InterlockedIncrement(volatile gint32 *dest)
66 {
67         gint32 ret;
68         
69         mono_once(&spin_once, spin_init);
70         pthread_mutex_lock(&spin);
71         
72         *dest++;
73         ret= *dest;
74         
75         pthread_mutex_unlock(&spin);
76         
77         return(ret);
78 }
79
80 gint32 InterlockedDecrement(volatile gint32 *dest)
81 {
82         gint32 ret;
83         
84         mono_once(&spin_once, spin_init);
85         pthread_mutex_lock(&spin);
86         
87         *dest--;
88         ret= *dest;
89         
90         pthread_mutex_unlock(&spin);
91         
92         return(ret);
93 }
94
95 gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch)
96 {
97         gint32 ret;
98         
99         mono_once(&spin_once, spin_init);
100         pthread_mutex_lock(&spin);
101
102         ret=*dest;
103         *dest=exch;
104         
105         pthread_mutex_unlock(&spin);
106         
107         return(ret);
108 }
109
110 gpointer InterlockedExchangePointer(volatile gpointer *dest, gpointer exch)
111 {
112         gpointer ret;
113         
114         mono_once(&spin_once, spin_init);
115         pthread_mutex_lock(&spin);
116         
117         ret=*dest;
118         *dest=exch;
119         
120         pthread_mutex_unlock(&spin);
121         
122         return(ret);
123 }
124
125 gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
126 {
127         gint32 ret;
128         
129         mono_once(&spin_once, spin_init);
130         pthread_mutex_lock(&spin);
131
132         ret= *dest;
133         *dest+=add;
134         
135         pthread_mutex_unlock(&spin);
136         
137         return(ret);
138 }
139
140 #endif