/* * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appears in all copies and * that both the copyright notice and this permission notice appear in * supporting documentation. * * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ /* * MkLinux */ #if defined(__ppc__) #import #import /* void spin_lock(int *p); * * Lock the lock pointed to by `p'. Spin (possibly forever) until * the lock is available. Test and test and set logic used. */ .text LEAF(__spin_lock_try) 1: lwarx r5,0,r3 // Read the lock addi r4,0,0x1 // Lock value cmpwi r5,0x0 // Is it busy? bne- 2f // Yes, return 0 stwcx. r4,0,r3 // Try to lock the lock bne- 1b // Lost reservation, try again addi r3,0,1 // Got the lock isync // Sync instruction stream blr // Return 1 2: addi r3,0,0 // Could not get the lock blr // Return 0 END(__spin_lock_try) .globl _spin_lock LEAF(__spin_lock) _spin_lock: 1: lwarx r5,0,r3 // Read the lock addi r4,0,0x1 // Lock value cmpwi r5,0x0 // Is it busy? bne- 2f // Yes, goto retry logic stwcx. r4,0,r3 // Try to lock the lock bne- 1b // Lost reservation, try again isync // Sync instruction stream blr // Return 2: CALL_EXTERN(__spin_lock_retry) blr // Return END(__spin_lock) /* void spin_unlock(int *p); * * Unlock the lock pointed to by p. */ .globl _spin_unlock LEAF(__spin_unlock) _spin_unlock: sync li32 r4,0 stw r4,0(r3) blr END(__spin_unlock) #elif defined(__i386__) #include /* * void * _spin_lock(p) * int *p; * * Lock the lock pointed to by p. Spin (possibly forever) until the next * lock is available. */ TEXT .globl _spin_lock_try LEAF(__spin_lock_try, 0) _spin_lock_try: movl 4(%esp),%ecx movl $1,%eax xchgl (%ecx),%eax xorl $1,%eax END(__spin_lock_try) .globl _spin_lock LEAF(__spin_lock, 0) _spin_lock: movl 4(%esp), %ecx movl (%ecx), %eax orl %eax, %eax jnz 1f movl $0xFFFFFFFF, %eax xchgl %eax, (%ecx) orl %eax, %eax jz 2f 1: pushl %ecx CALL_EXTERN(__spin_lock_retry) addl $4, %esp 2: END(__spin_lock) /* * void * _spin_unlock(p) * int *p; * * Unlock the lock pointed to by p. */ .globl _spin_unlock LEAF(__spin_unlock, 0) _spin_unlock: movl $0, %eax movl 4(%esp), %ecx xchgl %eax, (%ecx) END(__spin_unlock) #else #error spin_locks not defined for this architecture #endif