spinlock.h

来自「linux 内核源代码」· C头文件 代码 · 共 195 行

H
195
字号
#ifndef __ASM_SPINLOCK_H#define __ASM_SPINLOCK_H#include <asm/system.h>#include <asm/processor.h>#include <asm/spinlock_types.h>static inline int __raw_spin_is_locked(raw_spinlock_t *x){	volatile unsigned int *a = __ldcw_align(x);	return *a == 0;}#define __raw_spin_lock(lock) __raw_spin_lock_flags(lock, 0)#define __raw_spin_unlock_wait(x) \		do { cpu_relax(); } while (__raw_spin_is_locked(x))static inline void __raw_spin_lock_flags(raw_spinlock_t *x,					 unsigned long flags){	volatile unsigned int *a;	mb();	a = __ldcw_align(x);	while (__ldcw(a) == 0)		while (*a == 0)			if (flags & PSW_SM_I) {				local_irq_enable();				cpu_relax();				local_irq_disable();			} else				cpu_relax();	mb();}static inline void __raw_spin_unlock(raw_spinlock_t *x){	volatile unsigned int *a;	mb();	a = __ldcw_align(x);	*a = 1;	mb();}static inline int __raw_spin_trylock(raw_spinlock_t *x){	volatile unsigned int *a;	int ret;	mb();	a = __ldcw_align(x);        ret = __ldcw(a) != 0;	mb();	return ret;}/* * Read-write spinlocks, allowing multiple readers but only one writer. * Linux rwlocks are unfair to writers; they can be starved for an indefinite * time by readers.  With care, they can also be taken in interrupt context. * * In the PA-RISC implementation, we have a spinlock and a counter. * Readers use the lock to serialise their access to the counter (which * records how many readers currently hold the lock). * Writers hold the spinlock, preventing any readers or other writers from * grabbing the rwlock. *//* Note that we have to ensure interrupts are disabled in case we're * interrupted by some other code that wants to grab the same read lock */static  __inline__ void __raw_read_lock(raw_rwlock_t *rw){	unsigned long flags;	local_irq_save(flags);	__raw_spin_lock_flags(&rw->lock, flags);	rw->counter++;	__raw_spin_unlock(&rw->lock);	local_irq_restore(flags);}/* Note that we have to ensure interrupts are disabled in case we're * interrupted by some other code that wants to grab the same read lock */static  __inline__ void __raw_read_unlock(raw_rwlock_t *rw){	unsigned long flags;	local_irq_save(flags);	__raw_spin_lock_flags(&rw->lock, flags);	rw->counter--;	__raw_spin_unlock(&rw->lock);	local_irq_restore(flags);}/* Note that we have to ensure interrupts are disabled in case we're * interrupted by some other code that wants to grab the same read lock */static __inline__ int __raw_read_trylock(raw_rwlock_t *rw){	unsigned long flags; retry:	local_irq_save(flags);	if (__raw_spin_trylock(&rw->lock)) {		rw->counter++;		__raw_spin_unlock(&rw->lock);		local_irq_restore(flags);		return 1;	}	local_irq_restore(flags);	/* If write-locked, we fail to acquire the lock */	if (rw->counter < 0)		return 0;	/* Wait until we have a realistic chance at the lock */	while (__raw_spin_is_locked(&rw->lock) && rw->counter >= 0)		cpu_relax();	goto retry;}/* Note that we have to ensure interrupts are disabled in case we're * interrupted by some other code that wants to read_trylock() this lock */static __inline__ void __raw_write_lock(raw_rwlock_t *rw){	unsigned long flags;retry:	local_irq_save(flags);	__raw_spin_lock_flags(&rw->lock, flags);	if (rw->counter != 0) {		__raw_spin_unlock(&rw->lock);		local_irq_restore(flags);		while (rw->counter != 0)			cpu_relax();		goto retry;	}	rw->counter = -1; /* mark as write-locked */	mb();	local_irq_restore(flags);}static __inline__ void __raw_write_unlock(raw_rwlock_t *rw){	rw->counter = 0;	__raw_spin_unlock(&rw->lock);}/* Note that we have to ensure interrupts are disabled in case we're * interrupted by some other code that wants to read_trylock() this lock */static __inline__ int __raw_write_trylock(raw_rwlock_t *rw){	unsigned long flags;	int result = 0;	local_irq_save(flags);	if (__raw_spin_trylock(&rw->lock)) {		if (rw->counter == 0) {			rw->counter = -1;			result = 1;		} else {			/* Read-locked.  Oh well. */			__raw_spin_unlock(&rw->lock);		}	}	local_irq_restore(flags);	return result;}/* * read_can_lock - would read_trylock() succeed? * @lock: the rwlock in question. */static __inline__ int __raw_read_can_lock(raw_rwlock_t *rw){	return rw->counter >= 0;}/* * write_can_lock - would write_trylock() succeed? * @lock: the rwlock in question. */static __inline__ int __raw_write_can_lock(raw_rwlock_t *rw){	return !rw->counter;}#define _raw_spin_relax(lock)	cpu_relax()#define _raw_read_relax(lock)	cpu_relax()#define _raw_write_relax(lock)	cpu_relax()#endif /* __ASM_SPINLOCK_H */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?