headers/bsd: Add sys/queue.h.
[haiku.git] / src / system / kernel / arch / m68k / arch_atomic.cpp
blobd10ffa4069449ef0ad4f2cefe82432bcbdf4e19f
1 /*
2 * Copyright 2007, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * François Revol <revol@free.fr>
8 * Copyright 2003, Marcus Overhagen. All rights reserved.
9 * Distributed under the terms of the MIT License.
12 #include <KernelExport.h>
14 #include <kernel.h>
15 #include <user_atomic.h>
18 * Emulation of 64 bit atomic functions.
19 * Slow, using spinlocks...
22 #warning M68K: detect 060 here
23 #if 0
25 static spinlock atomic_lock = 0;
27 int64
28 atomic_set64(vint64 *value, int64 newValue)
30 cpu_status status;
31 int64 oldValue;
32 status = disable_interrupts();
33 acquire_spinlock(&atomic_lock);
34 oldValue = *value;
35 *value = newValue;
36 release_spinlock(&atomic_lock);
37 restore_interrupts(status);
38 return oldValue;
41 int64
42 atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst)
44 cpu_status status;
45 int64 oldValue;
46 status = disable_interrupts();
47 acquire_spinlock(&atomic_lock);
48 oldValue = *value;
49 if (oldValue == testAgainst)
50 *value = newValue;
51 release_spinlock(&atomic_lock);
52 restore_interrupts(status);
53 return oldValue;
56 int64
57 atomic_add64(vint64 *value, int64 addValue)
59 cpu_status status;
60 int64 oldValue;
61 status = disable_interrupts();
62 acquire_spinlock(&atomic_lock);
63 oldValue = *value;
64 *value += addValue;
65 release_spinlock(&atomic_lock);
66 restore_interrupts(status);
67 return oldValue;
70 int64
71 atomic_and64(vint64 *value, int64 andValue)
73 cpu_status status;
74 int64 oldValue;
75 status = disable_interrupts();
76 acquire_spinlock(&atomic_lock);
77 oldValue = *value;
78 *value &= andValue;
79 release_spinlock(&atomic_lock);
80 restore_interrupts(status);
81 return oldValue;
84 int64
85 atomic_or64(vint64 *value, int64 orValue)
87 cpu_status status;
88 int64 oldValue;
89 status = disable_interrupts();
90 acquire_spinlock(&atomic_lock);
91 oldValue = *value;
92 *value |= orValue;
93 release_spinlock(&atomic_lock);
94 restore_interrupts(status);
95 return oldValue;
98 int64
99 atomic_get64(vint64 *value)
101 cpu_status status;
102 int64 oldValue;
103 status = disable_interrupts();
104 acquire_spinlock(&atomic_lock);
105 oldValue = *value;
106 release_spinlock(&atomic_lock);
107 restore_interrupts(status);
108 return oldValue;
111 int64
112 _user_atomic_set64(vint64 *value, int64 newValue)
114 cpu_status status;
115 int64 oldValue;
116 if (!IS_USER_ADDRESS(value)
117 || lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
118 goto access_violation;
120 status = disable_interrupts();
121 acquire_spinlock(&atomic_lock);
122 oldValue = *value;
123 *value = newValue;
124 release_spinlock(&atomic_lock);
125 restore_interrupts(status);
126 unlock_memory((void *)value, 8, B_READ_DEVICE);
127 return oldValue;
129 access_violation:
130 // XXX kill application
131 return -1;
134 int64
135 _user_atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst)
137 cpu_status status;
138 int64 oldValue;
139 if (!IS_USER_ADDRESS(value)
140 || lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
141 goto access_violation;
143 status = disable_interrupts();
144 acquire_spinlock(&atomic_lock);
145 oldValue = *value;
146 if (oldValue == testAgainst)
147 *value = newValue;
148 release_spinlock(&atomic_lock);
149 restore_interrupts(status);
150 unlock_memory((void *)value, 8, B_READ_DEVICE);
151 return oldValue;
153 access_violation:
154 // XXX kill application
155 return -1;
158 int64
159 _user_atomic_add64(vint64 *value, int64 addValue)
161 cpu_status status;
162 int64 oldValue;
163 if (!IS_USER_ADDRESS(value)
164 || lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
165 goto access_violation;
167 status = disable_interrupts();
168 acquire_spinlock(&atomic_lock);
169 oldValue = *value;
170 *value += addValue;
171 release_spinlock(&atomic_lock);
172 restore_interrupts(status);
173 unlock_memory((void *)value, 8, B_READ_DEVICE);
174 return oldValue;
176 access_violation:
177 // XXX kill application
178 return -1;
181 int64
182 _user_atomic_and64(vint64 *value, int64 andValue)
184 cpu_status status;
185 int64 oldValue;
186 if (!IS_USER_ADDRESS(value)
187 || lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
188 goto access_violation;
190 status = disable_interrupts();
191 acquire_spinlock(&atomic_lock);
192 oldValue = *value;
193 *value &= andValue;
194 release_spinlock(&atomic_lock);
195 restore_interrupts(status);
196 unlock_memory((void *)value, 8, B_READ_DEVICE);
197 return oldValue;
199 access_violation:
200 // XXX kill application
201 return -1;
204 int64
205 _user_atomic_or64(vint64 *value, int64 orValue)
207 cpu_status status;
208 int64 oldValue;
209 if (!IS_USER_ADDRESS(value)
210 || lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
211 goto access_violation;
213 status = disable_interrupts();
214 acquire_spinlock(&atomic_lock);
215 oldValue = *value;
216 *value |= orValue;
217 release_spinlock(&atomic_lock);
218 restore_interrupts(status);
219 unlock_memory((void *)value, 8, B_READ_DEVICE);
220 return oldValue;
221 access_violation:
222 // XXX kill application
223 return -1;
226 int64
227 _user_atomic_get64(vint64 *value)
229 cpu_status status;
230 int64 oldValue;
231 if (!IS_USER_ADDRESS(value)
232 || lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
233 goto access_violation;
235 status = disable_interrupts();
236 acquire_spinlock(&atomic_lock);
237 oldValue = *value;
238 release_spinlock(&atomic_lock);
239 restore_interrupts(status);
240 unlock_memory((void *)value, 8, B_READ_DEVICE);
241 return oldValue;
243 access_violation:
244 // XXX kill application
245 return -1;
247 #endif