/* * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 1.1 (the * "License"). You may not use this file except in compliance with the * License. Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ #include #include #include /* * We need a relative branch within the comm page, and don't want the linker * to relocate it, so we have to hand-code the instructions. LEN is to account * for the length of a .long, since the jmp is relative to the next instruction. */ #define JNZ .byte 0x0f, 0x85; .long #define JMP .byte 0xe9; .long #define LEN 4 /* * Branch prediction prefixes */ #define LIKELY .byte 0x3e #define UNLIKELY .byte 0x2e #define MP_SPIN_TRIES 1024 .text .align 4, 0x90 Lspin_lock_try_up: movl 4(%esp), %ecx xorl %eax, %eax cmpxchgl %ecx, (%ecx) setz %dl movzbl %dl, %eax ret COMMPAGE_DESCRIPTOR(spin_lock_try_up,_COMM_PAGE_SPINLOCK_TRY,kUP,0) .align 4, 0x90 Lspin_lock_try_mp: movl 4(%esp), %ecx xorl %eax, %eax lock cmpxchgl %ecx, (%ecx) setz %dl movzbl %dl, %eax ret COMMPAGE_DESCRIPTOR(spin_lock_try_mp,_COMM_PAGE_SPINLOCK_TRY,0,kUP) .set Lrelinquish_off, _COMM_PAGE_RELINQUISH - _COMM_PAGE_SPINLOCK_LOCK .align 4, 0x90 Lspin_lock_up: movl 4(%esp), %ecx xorl %eax, %eax .set Lretry, . - Lspin_lock_up cmpxchgl %ecx, (%ecx) UNLIKELY JNZ Lrelinquish_off - . + Lspin_lock_up - LEN ret COMMPAGE_DESCRIPTOR(spin_lock_up,_COMM_PAGE_SPINLOCK_LOCK,kUP,0) .align 4, 0x90 Lspin_lock_mp: movl 4(%esp), %ecx xorl %eax, %eax 0: lock cmpxchgl %ecx, (%ecx) UNLIKELY jnz 1f ret 1: xorl %eax, %eax movl $(MP_SPIN_TRIES), %edx 2: pause cmpl %eax, (%ecx) LIKELY jz 0b decl %edx LIKELY jnz 2b JMP Lrelinquish_off - . + Lspin_lock_mp - LEN COMMPAGE_DESCRIPTOR(spin_lock_mp,_COMM_PAGE_SPINLOCK_LOCK,0,kUP) .align 4, 0x90 Lspin_unlock: movl 4(%esp), %ecx movl $0, (%ecx) ret COMMPAGE_DESCRIPTOR(spin_unlock,_COMM_PAGE_SPINLOCK_UNLOCK,0,0) .align 4, 0x90 Lrelinquish: /* relinquish the processor */ pushl $1 /* 1 ms */ pushl $1 /* SWITCH_OPTION_DEPRESS */ pushl $0 /* THREAD_NULL */ movl $-61, %eax /* syscall_thread_switch */ lcall $7, $0 popl %eax /* set %eax to 0 again */ popl %edx /* use %edx as scratch */ popl %edx /* reg to fixup stack */ JMP Lretry - Lrelinquish_off - . + Lrelinquish - LEN COMMPAGE_DESCRIPTOR(relinquish,_COMM_PAGE_RELINQUISH,0,0)