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");
 | 
						|
}
 | 
						|
 | 
						|
 |