e5f4633c39
which included commits to RCS files with non-trunk default branches. git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@5 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
119 lines
2.1 KiB
C
119 lines
2.1 KiB
C
/* ------------------------------- **
|
|
** Atomic lock for ALPHA **
|
|
** ------------------------------- */
|
|
|
|
/* This code is stolen from the Linux kernel */
|
|
|
|
static __inline__ int _test_and_set_bit(unsigned long nr,
|
|
volatile void * addr)
|
|
{
|
|
unsigned long oldbit;
|
|
unsigned long temp;
|
|
unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
|
|
|
|
__asm__ __volatile__(
|
|
"1: ldl_l %0,%1\n"
|
|
" and %0,%3,%2\n"
|
|
" bne %2,2f\n"
|
|
" xor %0,%3,%0\n"
|
|
" stl_c %0,%1\n"
|
|
" beq %0,3f\n"
|
|
" mb\n"
|
|
"2:\n"
|
|
".subsection 2\n"
|
|
"3: br 1b\n"
|
|
".previous"
|
|
:"=&r" (temp), "=m" (*m), "=&r" (oldbit)
|
|
:"Ir" (1UL << (nr & 31)), "m" (*m));
|
|
|
|
return oldbit != 0;
|
|
}
|
|
|
|
static __inline__ void _spin_lock(volatile void *lock)
|
|
{
|
|
long tmp;
|
|
|
|
/* Use sub-sections to put the actual loop at the end
|
|
of this object file's text section so as to perfect
|
|
branch prediction. */
|
|
__asm__ __volatile__(
|
|
"1: ldl_l %0,%1\n"
|
|
" blbs %0,2f\n"
|
|
" or %0,1,%0\n"
|
|
" stl_c %0,%1\n"
|
|
" beq %0,2f\n"
|
|
" mb\n"
|
|
".subsection 2\n"
|
|
"2: ldl %0,%1\n"
|
|
" blbs %0,2b\n"
|
|
" br 1b\n"
|
|
".previous"
|
|
: "=r" (tmp), "=m" (__dummy_lock(lock))
|
|
: "m"(__dummy_lock(lock)));
|
|
}
|
|
|
|
static inline void _write_lock(rwlock_t * lock)
|
|
{
|
|
long regx;
|
|
|
|
__asm__ __volatile__(
|
|
"1: ldl_l %1,%0\n"
|
|
" bne %1,6f\n"
|
|
" or $31,1,%1\n"
|
|
" stl_c %1,%0\n"
|
|
" beq %1,6f\n"
|
|
" mb\n"
|
|
".subsection 2\n"
|
|
"6: ldl %1,%0\n"
|
|
" bne %1,6b\n"
|
|
" br 1b\n"
|
|
".previous"
|
|
: "=m" (__dummy_lock(lock)), "=&r" (regx)
|
|
: "0" (__dummy_lock(lock))
|
|
);
|
|
}
|
|
|
|
static inline void _read_lock(rwlock_t * lock)
|
|
{
|
|
long regx;
|
|
|
|
__asm__ __volatile__(
|
|
"1: ldl_l %1,%0\n"
|
|
" blbs %1,6f\n"
|
|
" subl %1,2,%1\n"
|
|
" stl_c %1,%0\n"
|
|
" beq %1,6f\n"
|
|
"4: mb\n"
|
|
".subsection 2\n"
|
|
"6: ldl %1,%0\n"
|
|
" blbs %1,6b\n"
|
|
" br 1b\n"
|
|
".previous"
|
|
: "=m" (__dummy_lock(lock)), "=&r" (regx)
|
|
: "m" (__dummy_lock(lock))
|
|
);
|
|
}
|
|
|
|
|
|
static inline void _write_unlock(rwlock_t * lock)
|
|
{
|
|
mb();
|
|
*(volatile int *)lock = 0;
|
|
}
|
|
|
|
static inline void _read_unlock(rwlock_t * lock)
|
|
{
|
|
long regx;
|
|
__asm__ __volatile__(
|
|
"1: ldl_l %1,%0\n"
|
|
" addl %1,2,%1\n"
|
|
" stl_c %1,%0\n"
|
|
" beq %1,6f\n"
|
|
".subsection 2\n"
|
|
"6: br 1b\n"
|
|
".previous"
|
|
: "=m" (__dummy_lock(lock)), "=&r" (regx)
|
|
: "m" (__dummy_lock(lock)));
|
|
}
|
|
|