2 * Copyright 2013 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Ithamar R. Adema, ithamar@upgrade-android.com
9 #include <KernelExport.h>
12 #include <user_atomic.h>
14 #include <util/AutoLock.h>
16 #ifdef ATOMIC_FUNCS_ARE_SYSCALLS
19 * NOTE: These functions are _intentionally_ not using spinlocks, unlike
20 * the 64 bit versions. The reason for this is that they are used by the
21 * spinlock code itself, and therefore would deadlock.
23 * Since these are only really needed for ARMv5, which is not SMP anyway,
24 * this is an acceptable compromise.
28 atomic_set(int32
*value
, int32 newValue
)
30 InterruptsLocker locker
;
35 atomic_get_and_set(int32
*value
, int32 newValue
)
37 InterruptsLocker locker
;
38 int32 oldValue
= *value
;
39 atomic_set(value
, newValue
);
44 atomic_test_and_set(int32
*value
, int32 newValue
, int32 testAgainst
)
46 InterruptsLocker locker
;
48 int32 oldValue
= *value
;
49 if (oldValue
== testAgainst
)
55 atomic_add(int32
*value
, int32 addValue
)
57 InterruptsLocker locker
;
59 int32 oldValue
= *value
;
65 atomic_and(int32
*value
, int32 andValue
)
67 InterruptsLocker locker
;
69 int32 oldValue
= *value
;
75 atomic_or(int32
*value
, int32 orValue
)
77 InterruptsLocker locker
;
79 int32 oldValue
= *value
;
85 atomic_get(int32
*value
)
87 InterruptsLocker locker
;
89 int32 oldValue
= *value
;
94 _user_atomic_set(int32
*value
, int32 newValue
)
96 if (IS_USER_ADDRESS(value
)
97 && lock_memory((void *)value
, sizeof(int32
), B_READ_DEVICE
) == B_OK
) {
98 atomic_set(value
, newValue
);
99 unlock_memory((void *)value
, sizeof(int32
), B_READ_DEVICE
);
104 // XXX kill application
109 _user_atomic_get_and_set(int32
*value
, int32 newValue
)
111 if (IS_USER_ADDRESS(value
)
112 && lock_memory((void *)value
, sizeof(int32
), B_READ_DEVICE
) == B_OK
) {
113 int32 oldValue
= atomic_get_and_set(value
, newValue
);
114 unlock_memory((void *)value
, sizeof(int32
), B_READ_DEVICE
);
119 // XXX kill application
124 _user_atomic_test_and_set(int32
*value
, int32 newValue
, int32 testAgainst
)
126 if (IS_USER_ADDRESS(value
)
127 && lock_memory((void *)value
, sizeof(int32
), B_READ_DEVICE
) == B_OK
) {
128 int32 oldValue
= atomic_test_and_set((int32
*)value
, newValue
, testAgainst
);
129 unlock_memory((void *)value
, sizeof(int32
), B_READ_DEVICE
);
134 // XXX kill application
139 _user_atomic_add(int32
*value
, int32 addValue
)
141 if (IS_USER_ADDRESS(value
)
142 && lock_memory((void *)value
, sizeof(int32
), B_READ_DEVICE
) == B_OK
) {
143 int32 oldValue
= atomic_add(value
, addValue
);
144 unlock_memory((void *)value
, sizeof(int32
), B_READ_DEVICE
);
149 // XXX kill application
154 _user_atomic_and(int32
*value
, int32 andValue
)
156 if (IS_USER_ADDRESS(value
)
157 && lock_memory((void *)value
, sizeof(int32
), B_READ_DEVICE
) == B_OK
) {
158 int32 oldValue
= atomic_and(value
, andValue
);
159 unlock_memory((void *)value
, sizeof(int32
), B_READ_DEVICE
);
164 // XXX kill application
169 _user_atomic_or(int32
*value
, int32 orValue
)
171 if (IS_USER_ADDRESS(value
)
172 && lock_memory((void *)value
, sizeof(int32
), B_READ_DEVICE
) == B_OK
) {
173 int32 oldValue
= atomic_or(value
, orValue
);
174 unlock_memory((void *)value
, sizeof(int32
), B_READ_DEVICE
);
179 // XXX kill application
184 _user_atomic_get(int32
*value
)
186 if (IS_USER_ADDRESS(value
)
187 && lock_memory((void *)value
, sizeof(int32
), B_READ_DEVICE
) == B_OK
) {
188 int32 oldValue
= atomic_get(value
);
189 unlock_memory((void *)value
, sizeof(int32
), B_READ_DEVICE
);
194 // XXX kill application
198 #endif /* ATOMIC_FUNCS_ARE_SYSCALLS */