]>
git.saurik.com Git - apple/libc.git/blob - arm/sys/OSAtomic-v4.c
f3a1b37548d94d86cf25804978c6b90d08ca8155
2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <libkern/OSAtomic.h>
28 #if !defined(_ARM_ARCH_6)
31 * The only atomic operation ARMv4T provides (atomic swap) is not
32 * sufficient for the general 32-bit arithmetic and compare-and-swap
33 * operations OSAtomic is supposed to provide. So we use a global
34 * spin lock around all operations.
36 * Since we have only a single, in-order, CPU, we do not need
37 * memory barriers for data.
40 static OSSpinLock _atomic_lock
= OS_SPINLOCK_INIT
;
42 int32_t OSAtomicAdd32( int32_t theAmount
, int32_t *theValue
)
46 OSSpinLockLock(&_atomic_lock
);
47 result
= (*theValue
+= theAmount
);
48 OSSpinLockUnlock(&_atomic_lock
);
53 int32_t OSAtomicAdd32Barrier( int32_t theAmount
, int32_t *theValue
)
55 return OSAtomicAdd32(theAmount
, theValue
);
58 int32_t OSAtomicOr32( uint32_t theMask
, uint32_t *theValue
)
62 OSSpinLockLock(&_atomic_lock
);
63 result
= (*theValue
|= theMask
);
64 OSSpinLockUnlock(&_atomic_lock
);
69 int32_t OSAtomicOr32Barrier( uint32_t theMask
, uint32_t *theValue
)
71 return OSAtomicOr32(theMask
, theValue
);
74 int32_t OSAtomicAnd32( uint32_t theMask
, uint32_t *theValue
)
78 OSSpinLockLock(&_atomic_lock
);
79 result
= (*theValue
&= theMask
);
80 OSSpinLockUnlock(&_atomic_lock
);
85 int32_t OSAtomicAnd32Barrier( uint32_t theMask
, uint32_t *theValue
)
87 return OSAtomicAnd32(theMask
, theValue
);
90 int32_t OSAtomicXor32( uint32_t theMask
, uint32_t *theValue
)
94 OSSpinLockLock(&_atomic_lock
);
95 result
= (*theValue
^= theMask
);
96 OSSpinLockUnlock(&_atomic_lock
);
101 int32_t OSAtomicXor32Barrier( uint32_t theMask
, uint32_t *theValue
)
103 return OSAtomicXor32(theMask
, theValue
);
106 bool OSAtomicCompareAndSwap32( int32_t oldValue
, int32_t newValue
, int32_t *theValue
)
110 OSSpinLockLock(&_atomic_lock
);
111 result
= (*theValue
== oldValue
);
112 if (result
) *theValue
= newValue
;
113 OSSpinLockUnlock(&_atomic_lock
);
118 bool OSAtomicCompareAndSwap32Barrier( int32_t oldValue
, int32_t newValue
, int32_t *theValue
)
120 return OSAtomicCompareAndSwap32(oldValue
, newValue
, theValue
);
123 bool OSAtomicTestAndSet( uint32_t n
, void *theAddress
)
125 char *byteAddress
= ((char*)theAddress
+ (n
>>3));
126 uint32_t byteBit
= (0x80>>(n
&7));
129 OSSpinLockLock(&_atomic_lock
);
130 result
= *byteAddress
& byteBit
;
131 *byteAddress
|= byteBit
;
132 OSSpinLockUnlock(&_atomic_lock
);
137 bool OSAtomicTestAndSetBarrier( uint32_t n
, void *theAddress
)
139 return OSAtomicTestAndSet(n
, theAddress
);
142 bool OSAtomicTestAndClear( uint32_t n
, void *theAddress
)
144 char *byteAddress
= ((char*)theAddress
+ (n
>>3));
145 uint32_t byteBit
= (0x80>>(n
&7));
148 OSSpinLockLock(&_atomic_lock
);
149 result
= *byteAddress
& byteBit
;
150 *byteAddress
&= (~byteBit
);
151 OSSpinLockUnlock(&_atomic_lock
);
156 bool OSAtomicTestAndClearBarrier( uint32_t n
, void *theAddress
)
158 return OSAtomicTestAndClear(n
, theAddress
);
161 void OSMemoryBarrier( void )
166 #endif /* !defined(_ARM_ARCH_6) */