/*1* i386 semaphore implementation.2*3* (C) Copyright 1999 Linus Torvalds4*5* Portions Copyright 1999 Red Hat, Inc.6*7* This program is free software; you can redistribute it and/or8* modify it under the terms of the GNU General Public License9* as published by the Free Software Foundation; either version10* 2 of the License, or (at your option) any later version.11*12* rw semaphores implemented November 1999 by Benjamin LaHaise <[email protected]>13*/1415#include <linux/linkage.h>16#include <asm/rwlock.h>17#include <asm/alternative-asm.h>18#include <asm/frame.h>19#include <asm/dwarf2.h>2021/*22* The semaphore operations have a special calling sequence that23* allow us to do a simpler in-line version of them. These routines24* need to convert that sequence back into the C sequence when25* there is contention on the semaphore.26*27* %eax contains the semaphore pointer on entry. Save the C-clobbered28* registers (%eax, %edx and %ecx) except %eax whish is either a return29* value or just clobbered..30*/31.section .sched.text, "ax"3233/*34* rw spinlock fallbacks35*/36#ifdef CONFIG_SMP37ENTRY(__write_lock_failed)38CFI_STARTPROC39FRAME402: LOCK_PREFIX41addl $ RW_LOCK_BIAS,(%eax)421: rep; nop43cmpl $ RW_LOCK_BIAS,(%eax)44jne 1b45LOCK_PREFIX46subl $ RW_LOCK_BIAS,(%eax)47jnz 2b48ENDFRAME49ret50CFI_ENDPROC51ENDPROC(__write_lock_failed)5253ENTRY(__read_lock_failed)54CFI_STARTPROC55FRAME562: LOCK_PREFIX57incl (%eax)581: rep; nop59cmpl $1,(%eax)60js 1b61LOCK_PREFIX62decl (%eax)63js 2b64ENDFRAME65ret66CFI_ENDPROC67ENDPROC(__read_lock_failed)6869#endif7071#ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM7273/* Fix up special calling conventions */74ENTRY(call_rwsem_down_read_failed)75CFI_STARTPROC76pushl_cfi %ecx77CFI_REL_OFFSET ecx,078pushl_cfi %edx79CFI_REL_OFFSET edx,080call rwsem_down_read_failed81popl_cfi %edx82popl_cfi %ecx83ret84CFI_ENDPROC85ENDPROC(call_rwsem_down_read_failed)8687ENTRY(call_rwsem_down_write_failed)88CFI_STARTPROC89pushl_cfi %ecx90CFI_REL_OFFSET ecx,091calll rwsem_down_write_failed92popl_cfi %ecx93ret94CFI_ENDPROC95ENDPROC(call_rwsem_down_write_failed)9697ENTRY(call_rwsem_wake)98CFI_STARTPROC99decw %dx /* do nothing if still outstanding active readers */100jnz 1f101pushl_cfi %ecx102CFI_REL_OFFSET ecx,0103call rwsem_wake104popl_cfi %ecx1051: ret106CFI_ENDPROC107ENDPROC(call_rwsem_wake)108109/* Fix up special calling conventions */110ENTRY(call_rwsem_downgrade_wake)111CFI_STARTPROC112pushl_cfi %ecx113CFI_REL_OFFSET ecx,0114pushl_cfi %edx115CFI_REL_OFFSET edx,0116call rwsem_downgrade_wake117popl_cfi %edx118popl_cfi %ecx119ret120CFI_ENDPROC121ENDPROC(call_rwsem_downgrade_wake)122123#endif124125126