2 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 #include <sys/appleapiopts.h>
27 #include <ppc/asm.h> // EXT, LEXT
28 #include <machine/cpu_capabilities.h>
29 #include <machine/commpage.h>
33 .globl EXT(spinlock_32_try_mp)
34 .globl EXT(spinlock_32_try_up)
35 .globl EXT(spinlock_32_lock_mp)
36 .globl EXT(spinlock_32_lock_up)
37 .globl EXT(spinlock_32_unlock_mp)
38 .globl EXT(spinlock_32_unlock_up)
40 .globl EXT(spinlock_64_try_mp)
41 .globl EXT(spinlock_64_try_up)
42 .globl EXT(spinlock_64_lock_mp)
43 .globl EXT(spinlock_64_lock_up)
44 .globl EXT(spinlock_64_unlock_mp)
45 .globl EXT(spinlock_64_unlock_up)
47 .globl EXT(spinlock_relinquish)
49 #define MP_SPIN_TRIES 1000
52 // The user mode spinlock library. There are many versions,
53 // in order to take advantage of a few special cases:
54 // - no barrier instructions (SYNC,ISYNC) are needed if UP
55 // - 64-bit processors can use LWSYNC instead of SYNC (if MP)
56 // - branch hints appropriate to the processor (+ vs ++ etc)
57 // - potentially custom relinquish strategies (not used at present)
58 // - fixes for errata as necessary
69 isync // cancel speculative execution
76 COMMPAGE_DESCRIPTOR(spinlock_32_try_mp,_COMM_PAGE_SPINLOCK_TRY,0,k64Bit+kUP,0)
93 COMMPAGE_DESCRIPTOR(spinlock_32_try_up,_COMM_PAGE_SPINLOCK_TRY,kUP,k64Bit,0)
103 isync // cancel speculative execution
104 beqlr+ // we return void
107 subic. r5,r5,1 // try again before relinquish?
109 ba _COMM_PAGE_RELINQUISH
111 COMMPAGE_DESCRIPTOR(spinlock_32_lock_mp,_COMM_PAGE_SPINLOCK_LOCK,0,k64Bit+kUP,0)
118 bnea- _COMM_PAGE_RELINQUISH // always depress on UP (let lock owner run)
120 beqlr+ // we return void
123 COMMPAGE_DESCRIPTOR(spinlock_32_lock_up,_COMM_PAGE_SPINLOCK_LOCK,kUP,k64Bit,0)
126 spinlock_32_unlock_mp:
128 sync // complete prior stores before unlock
132 COMMPAGE_DESCRIPTOR(spinlock_32_unlock_mp,_COMM_PAGE_SPINLOCK_UNLOCK,0,k64Bit+kUP,0)
135 spinlock_32_unlock_up:
140 COMMPAGE_DESCRIPTOR(spinlock_32_unlock_up,_COMM_PAGE_SPINLOCK_UNLOCK,kUP,k64Bit,0)
151 isync // cancel speculative execution
156 stwcx. r5,r6,r1 // clear the pending reservation (using red zone)
157 li r3,0 // Pass failure
160 COMMPAGE_DESCRIPTOR(spinlock_64_try_mp,_COMM_PAGE_SPINLOCK_TRY,k64Bit,kUP,0)
175 stwcx. r5,r6,r1 // clear the pending reservation (using red zone)
179 COMMPAGE_DESCRIPTOR(spinlock_64_try_up,_COMM_PAGE_SPINLOCK_TRY,k64Bit+kUP,0,0)
189 isync // cancel speculative execution
190 beqlr++ // we return void
194 stwcx. r3,r6,r1 // clear the pending reservation (using red zone)
195 subic. r5,r5,1 // try again before relinquish?
196 bne-- 1b // mispredict this one (a cheap back-off)
197 ba _COMM_PAGE_RELINQUISH
199 COMMPAGE_DESCRIPTOR(spinlock_64_lock_mp,_COMM_PAGE_SPINLOCK_LOCK,k64Bit,kUP,0)
208 beqlr++ // we return void
210 2: // always relinquish on UP (let lock owner run)
212 stwcx. r3,r6,r1 // clear the pending reservation (using red zone)
213 ba _COMM_PAGE_RELINQUISH
215 COMMPAGE_DESCRIPTOR(spinlock_64_lock_up,_COMM_PAGE_SPINLOCK_LOCK,k64Bit+kUP,0,0)
218 spinlock_64_unlock_mp:
220 lwsync // complete prior stores before unlock
224 COMMPAGE_DESCRIPTOR(spinlock_64_unlock_mp,_COMM_PAGE_SPINLOCK_UNLOCK,k64Bit,kUP,0)
227 spinlock_64_unlock_up:
232 COMMPAGE_DESCRIPTOR(spinlock_64_unlock_up,_COMM_PAGE_SPINLOCK_UNLOCK,k64Bit+kUP,0,0)
236 mr r12,r3 // preserve lockword ptr across relinquish
237 li r3,0 // THREAD_NULL
238 li r4,1 // SWITCH_OPTION_DEPRESS
239 li r5,1 // timeout (ms)
240 li r0,-61 // SYSCALL_THREAD_SWITCH
243 ba _COMM_PAGE_SPINLOCK_LOCK
245 COMMPAGE_DESCRIPTOR(spinlock_relinquish,_COMM_PAGE_RELINQUISH,0,0,0)