2 * Copyright 2007, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
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>
15 #include <user_atomic.h>
18 * Emulation of 64 bit atomic functions.
19 * Slow, using spinlocks...
22 #warning M68K: detect 060 here
25 static spinlock atomic_lock
= 0;
28 atomic_set64(vint64
*value
, int64 newValue
)
32 status
= disable_interrupts();
33 acquire_spinlock(&atomic_lock
);
36 release_spinlock(&atomic_lock
);
37 restore_interrupts(status
);
42 atomic_test_and_set64(vint64
*value
, int64 newValue
, int64 testAgainst
)
46 status
= disable_interrupts();
47 acquire_spinlock(&atomic_lock
);
49 if (oldValue
== testAgainst
)
51 release_spinlock(&atomic_lock
);
52 restore_interrupts(status
);
57 atomic_add64(vint64
*value
, int64 addValue
)
61 status
= disable_interrupts();
62 acquire_spinlock(&atomic_lock
);
65 release_spinlock(&atomic_lock
);
66 restore_interrupts(status
);
71 atomic_and64(vint64
*value
, int64 andValue
)
75 status
= disable_interrupts();
76 acquire_spinlock(&atomic_lock
);
79 release_spinlock(&atomic_lock
);
80 restore_interrupts(status
);
85 atomic_or64(vint64
*value
, int64 orValue
)
89 status
= disable_interrupts();
90 acquire_spinlock(&atomic_lock
);
93 release_spinlock(&atomic_lock
);
94 restore_interrupts(status
);
99 atomic_get64(vint64
*value
)
103 status
= disable_interrupts();
104 acquire_spinlock(&atomic_lock
);
106 release_spinlock(&atomic_lock
);
107 restore_interrupts(status
);
112 _user_atomic_set64(vint64
*value
, int64 newValue
)
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
);
124 release_spinlock(&atomic_lock
);
125 restore_interrupts(status
);
126 unlock_memory((void *)value
, 8, B_READ_DEVICE
);
130 // XXX kill application
135 _user_atomic_test_and_set64(vint64
*value
, int64 newValue
, int64 testAgainst
)
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
);
146 if (oldValue
== testAgainst
)
148 release_spinlock(&atomic_lock
);
149 restore_interrupts(status
);
150 unlock_memory((void *)value
, 8, B_READ_DEVICE
);
154 // XXX kill application
159 _user_atomic_add64(vint64
*value
, int64 addValue
)
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
);
171 release_spinlock(&atomic_lock
);
172 restore_interrupts(status
);
173 unlock_memory((void *)value
, 8, B_READ_DEVICE
);
177 // XXX kill application
182 _user_atomic_and64(vint64
*value
, int64 andValue
)
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
);
194 release_spinlock(&atomic_lock
);
195 restore_interrupts(status
);
196 unlock_memory((void *)value
, 8, B_READ_DEVICE
);
200 // XXX kill application
205 _user_atomic_or64(vint64
*value
, int64 orValue
)
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
);
217 release_spinlock(&atomic_lock
);
218 restore_interrupts(status
);
219 unlock_memory((void *)value
, 8, B_READ_DEVICE
);
222 // XXX kill application
227 _user_atomic_get64(vint64
*value
)
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
);
238 release_spinlock(&atomic_lock
);
239 restore_interrupts(status
);
240 unlock_memory((void *)value
, 8, B_READ_DEVICE
);
244 // XXX kill application