]> git.saurik.com Git - apple/libc.git/blame - arm/sys/OSAtomic-v4.c
Libc-498.1.7.tar.gz
[apple/libc.git] / arm / sys / OSAtomic-v4.c
CommitLineData
b5d655f7
A
1/*
2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#include <libkern/OSAtomic.h>
25#include <arm/arch.h>
26
27
28#if !defined(_ARM_ARCH_6)
29
30/*
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.
35 *
36 * Since we have only a single, in-order, CPU, we do not need
37 * memory barriers for data.
38 */
39
40static OSSpinLock _atomic_lock = OS_SPINLOCK_INIT;
41
42int32_t OSAtomicAdd32( int32_t theAmount, int32_t *theValue )
43{
44 int32_t result;
45
46 OSSpinLockLock(&_atomic_lock);
47 result = (*theValue += theAmount);
48 OSSpinLockUnlock(&_atomic_lock);
49
50 return result;
51}
52
53int32_t OSAtomicAdd32Barrier( int32_t theAmount, int32_t *theValue )
54{
55 return OSAtomicAdd32(theAmount, theValue);
56}
57
58int32_t OSAtomicOr32( uint32_t theMask, uint32_t *theValue )
59{
60 int32_t result;
61
62 OSSpinLockLock(&_atomic_lock);
63 result = (*theValue |= theMask);
64 OSSpinLockUnlock(&_atomic_lock);
65
66 return result;
67}
68
69int32_t OSAtomicOr32Barrier( uint32_t theMask, uint32_t *theValue )
70{
71 return OSAtomicOr32(theMask, theValue);
72}
73
74int32_t OSAtomicAnd32( uint32_t theMask, uint32_t *theValue )
75{
76 int32_t result;
77
78 OSSpinLockLock(&_atomic_lock);
79 result = (*theValue &= theMask);
80 OSSpinLockUnlock(&_atomic_lock);
81
82 return result;
83}
84
85int32_t OSAtomicAnd32Barrier( uint32_t theMask, uint32_t *theValue )
86{
87 return OSAtomicAnd32(theMask, theValue);
88}
89
90int32_t OSAtomicXor32( uint32_t theMask, uint32_t *theValue )
91{
92 int32_t result;
93
94 OSSpinLockLock(&_atomic_lock);
95 result = (*theValue ^= theMask);
96 OSSpinLockUnlock(&_atomic_lock);
97
98 return result;
99}
100
101int32_t OSAtomicXor32Barrier( uint32_t theMask, uint32_t *theValue )
102{
103 return OSAtomicXor32(theMask, theValue);
104}
105
106bool OSAtomicCompareAndSwap32( int32_t oldValue, int32_t newValue, int32_t *theValue )
107{
108 bool result;
109
110 OSSpinLockLock(&_atomic_lock);
111 result = (*theValue == oldValue);
112 if (result) *theValue = newValue;
113 OSSpinLockUnlock(&_atomic_lock);
114
115 return result;
116}
117
118bool OSAtomicCompareAndSwap32Barrier( int32_t oldValue, int32_t newValue, int32_t *theValue )
119{
120 return OSAtomicCompareAndSwap32(oldValue, newValue, theValue);
121}
122
123bool OSAtomicTestAndSet( uint32_t n, void *theAddress )
124{
125 char *byteAddress = ((char*)theAddress + (n>>3));
126 uint32_t byteBit = (0x80>>(n&7));
127 bool result;
128
129 OSSpinLockLock(&_atomic_lock);
130 result = *byteAddress & byteBit;
131 *byteAddress |= byteBit;
132 OSSpinLockUnlock(&_atomic_lock);
133
134 return result;
135}
136
137bool OSAtomicTestAndSetBarrier( uint32_t n, void *theAddress )
138{
139 return OSAtomicTestAndSet(n, theAddress);
140}
141
142bool OSAtomicTestAndClear( uint32_t n, void *theAddress )
143{
144 char *byteAddress = ((char*)theAddress + (n>>3));
145 uint32_t byteBit = (0x80>>(n&7));
146 bool result;
147
148 OSSpinLockLock(&_atomic_lock);
149 result = *byteAddress & byteBit;
150 *byteAddress &= (~byteBit);
151 OSSpinLockUnlock(&_atomic_lock);
152
153 return result;
154}
155
156bool OSAtomicTestAndClearBarrier( uint32_t n, void *theAddress )
157{
158 return OSAtomicTestAndClear(n, theAddress);
159}
160
161void OSMemoryBarrier( void )
162{
163 return;
164}
165
166#endif /* !defined(_ARM_ARCH_6) */