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
116 lines
2.3 KiB
C
116 lines
2.3 KiB
C
/* ------------------------------- **
|
|
** Atomic locking for MIPS **
|
|
** ------------------------------- */
|
|
|
|
static __inline__ int test_and_set_bit(int nr, volatile void *addr)
|
|
{
|
|
int mask, retval, mw;
|
|
|
|
mask = 1;
|
|
do {
|
|
mw = load_linked(addr);
|
|
retval = (mask & mw) != 0;
|
|
} while (!store_conditional(addr, mw|mask));
|
|
|
|
return retval;
|
|
}
|
|
|
|
static inline void _spin_lock(__dummy_lock_t *lock)
|
|
{
|
|
unsigned int tmp;
|
|
|
|
__asm__ __volatile__(
|
|
".set\tnoreorder\t\t\t# spin_lock\n"
|
|
"1:\tll\t%1, %2\n\t"
|
|
"bnez\t%1, 1b\n\t"
|
|
" li\t%1, 1\n\t"
|
|
"sc\t%1, %0\n\t"
|
|
"beqz\t%1, 1b\n\t"
|
|
" sync\n\t"
|
|
".set\treorder"
|
|
: "=o" (__dummy_lock(lock)), "=&r" (tmp)
|
|
: "o" (__dummy_lock(lock))
|
|
: "memory");
|
|
}
|
|
|
|
static inline void spin_unlock(__dummy_lock_t *lock)
|
|
{
|
|
__asm__ __volatile__(
|
|
".set\tnoreorder\t\t\t# spin_unlock\n\t"
|
|
"sync\n\t"
|
|
"sw\t$0, %0\n\t"
|
|
".set\treorder"
|
|
: "=o" (__dummy_lock(lock))
|
|
: "o" (__dummy_lock(lock))
|
|
: "memory");
|
|
}
|
|
|
|
static inline void _read_lock(rwlock_t *rw)
|
|
{
|
|
unsigned int tmp;
|
|
|
|
__asm__ __volatile__(
|
|
".set\tnoreorder\t\t\t# read_lock\n"
|
|
"1:\tll\t%1, %2\n\t"
|
|
"bltz\t%1, 1b\n\t"
|
|
" addu\t%1, 1\n\t"
|
|
"sc\t%1, %0\n\t"
|
|
"beqz\t%1, 1b\n\t"
|
|
" sync\n\t"
|
|
".set\treorder"
|
|
: "=o" (__dummy_lock(rw)), "=&r" (tmp)
|
|
: "o" (__dummy_lock(rw))
|
|
: "memory");
|
|
}
|
|
|
|
/* Note the use of sub, not subu which will make the kernel die with an
|
|
overflow exception if we ever try to unlock an rwlock that is already
|
|
unlocked or is being held by a writer. */
|
|
static inline void _read_unlock(rwlock_t *rw)
|
|
{
|
|
unsigned int tmp;
|
|
|
|
__asm__ __volatile__(
|
|
".set\tnoreorder\t\t\t# read_unlock\n"
|
|
"1:\tll\t%1, %2\n\t"
|
|
"sub\t%1, 1\n\t"
|
|
"sc\t%1, %0\n\t"
|
|
"beqz\t%1, 1b\n\t"
|
|
".set\treorder"
|
|
: "=o" (__dummy_lock(rw)), "=&r" (tmp)
|
|
: "o" (__dummy_lock(rw))
|
|
: "memory");
|
|
}
|
|
|
|
static inline void _write_lock(rwlock_t *rw)
|
|
{
|
|
unsigned int tmp;
|
|
|
|
__asm__ __volatile__(
|
|
".set\tnoreorder\t\t\t# write_lock\n"
|
|
"1:\tll\t%1, %2\n\t"
|
|
"bnez\t%1, 1b\n\t"
|
|
" lui\t%1, 0x8000\n\t"
|
|
"sc\t%1, %0\n\t"
|
|
"beqz\t%1, 1b\n\t"
|
|
" sync\n\t"
|
|
".set\treorder"
|
|
: "=o" (__dummy_lock(rw)), "=&r" (tmp)
|
|
: "o" (__dummy_lock(rw))
|
|
: "memory");
|
|
}
|
|
|
|
static inline void _write_unlock(rwlock_t *rw)
|
|
{
|
|
__asm__ __volatile__(
|
|
".set\tnoreorder\t\t\t# write_unlock\n\t"
|
|
"sync\n\t"
|
|
"sw\t$0, %0\n\t"
|
|
".set\treorder"
|
|
: "=o" (__dummy_lock(rw))
|
|
: "o" (__dummy_lock(rw))
|
|
: "memory");
|
|
}
|
|
|
|
|