⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 brlock.h

📁 linux得一些常用命令,以及linux环境下的c编程
💻 H
字号:
#ifndef __LINUX_BRLOCK_H#define __LINUX_BRLOCK_H/* * 'Big Reader' read-write spinlocks. * * super-fast read/write locks, with write-side penalty. The point * is to have a per-CPU read/write lock. Readers lock their CPU-local * readlock, writers must lock all locks to get write access. These * CPU-read-write locks are semantically identical to normal rwlocks. * Memory usage is higher as well. (NR_CPUS*L1_CACHE_BYTES bytes) * * The most important feature is that these spinlocks do not cause * cacheline ping-pong in the 'most readonly data' case. * * Copyright 2000, Ingo Molnar <mingo@redhat.com> * * Registry idea and naming [ crutial! :-) ] by: * *                 David S. Miller <davem@redhat.com> * * David has an implementation that doesn't use atomic operations in * the read branch via memory ordering tricks - i guess we need to * split this up into a per-arch thing? The atomicity issue is a * secondary item in profiles, at least on x86 platforms. * * The atomic op version overhead is indeed a big deal on * load-locked/store-conditional cpus (ALPHA/MIPS/PPC) and * compare-and-swap cpus (Sparc64).  So we control which * implementation to use with a __BRLOCK_USE_ATOMICS define. -DaveM *//* Register bigreader lock indices here. */enum brlock_indices {	BR_GLOBALIRQ_LOCK,	BR_NETPROTO_LOCK,	__BR_END};#include <linux/config.h>#ifdef CONFIG_SMP#include <linux/cache.h>#include <linux/spinlock.h>#if defined(__i386__) || defined(__ia64__) || defined(__x86_64__)#define __BRLOCK_USE_ATOMICS#else#undef __BRLOCK_USE_ATOMICS#endif#ifdef __BRLOCK_USE_ATOMICStypedef rwlock_t	brlock_read_lock_t;#elsetypedef unsigned int	brlock_read_lock_t;#endif/* * align last allocated index to the next cacheline: */#define __BR_IDX_MAX \	(((sizeof(brlock_read_lock_t)*__BR_END + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) / sizeof(brlock_read_lock_t))extern brlock_read_lock_t __brlock_array[NR_CPUS][__BR_IDX_MAX];#ifndef __BRLOCK_USE_ATOMICSstruct br_wrlock {	spinlock_t lock;} __attribute__ ((__aligned__(SMP_CACHE_BYTES)));extern struct br_wrlock __br_write_locks[__BR_IDX_MAX];#endifextern void __br_lock_usage_bug (void);#ifdef __BRLOCK_USE_ATOMICSstatic inline void br_read_lock (enum brlock_indices idx){	/*	 * This causes a link-time bug message if an	 * invalid index is used:	 */	if (idx >= __BR_END)		__br_lock_usage_bug();	read_lock(&__brlock_array[smp_processor_id()][idx]);}static inline void br_read_unlock (enum brlock_indices idx){	if (idx >= __BR_END)		__br_lock_usage_bug();	read_unlock(&__brlock_array[smp_processor_id()][idx]);}#else /* ! __BRLOCK_USE_ATOMICS */static inline void br_read_lock (enum brlock_indices idx){	unsigned int *ctr;	spinlock_t *lock;	/*	 * This causes a link-time bug message if an	 * invalid index is used:	 */	if (idx >= __BR_END)		__br_lock_usage_bug();	ctr = &__brlock_array[smp_processor_id()][idx];	lock = &__br_write_locks[idx].lock;again:	(*ctr)++;	mb();	if (spin_is_locked(lock)) {		(*ctr)--;		wmb(); /*			* The release of the ctr must become visible			* to the other cpus eventually thus wmb(),			* we don't care if spin_is_locked is reordered			* before the releasing of the ctr.			* However IMHO this wmb() is superflous even in theory.			* It would not be superflous only if on the			* other CPUs doing a ldl_l instead of an ldl			* would make a difference and I don't think this is			* the case.			* I'd like to clarify this issue further			* but for now this is a slow path so adding the			* wmb() will keep us on the safe side.			*/		while (spin_is_locked(lock))			barrier();		goto again;	}}static inline void br_read_unlock (enum brlock_indices idx){	unsigned int *ctr;	if (idx >= __BR_END)		__br_lock_usage_bug();	ctr = &__brlock_array[smp_processor_id()][idx];	wmb();	(*ctr)--;}#endif /* __BRLOCK_USE_ATOMICS *//* write path not inlined - it's rare and larger */extern void FASTCALL(__br_write_lock (enum brlock_indices idx));extern void FASTCALL(__br_write_unlock (enum brlock_indices idx));static inline void br_write_lock (enum brlock_indices idx){	if (idx >= __BR_END)		__br_lock_usage_bug();	__br_write_lock(idx);}static inline void br_write_unlock (enum brlock_indices idx){	if (idx >= __BR_END)		__br_lock_usage_bug();	__br_write_unlock(idx);}#else# define br_read_lock(idx)	({ (void)(idx); preempt_disable(); })# define br_read_unlock(idx)	({ (void)(idx); preempt_enable(); })# define br_write_lock(idx)	({ (void)(idx); preempt_disable(); })# define br_write_unlock(idx)	({ (void)(idx); preempt_enable(); })#endif	/* CONFIG_SMP *//* * Now enumerate all of the possible sw/hw IRQ protected * versions of the interfaces. */#define br_read_lock_irqsave(idx, flags) \	do { local_irq_save(flags); br_read_lock(idx); } while (0)#define br_read_lock_irq(idx) \	do { local_irq_disable(); br_read_lock(idx); } while (0)#define br_read_lock_bh(idx) \	do { local_bh_disable(); br_read_lock(idx); } while (0)#define br_write_lock_irqsave(idx, flags) \	do { local_irq_save(flags); br_write_lock(idx); } while (0)#define br_write_lock_irq(idx) \	do { local_irq_disable(); br_write_lock(idx); } while (0)#define br_write_lock_bh(idx) \	do { local_bh_disable(); br_write_lock(idx); } while (0)#define br_read_unlock_irqrestore(idx, flags) \	do { br_read_unlock(irx); local_irq_restore(flags); } while (0)#define br_read_unlock_irq(idx) \	do { br_read_unlock(idx); local_irq_enable(); } while (0)#define br_read_unlock_bh(idx) \	do { br_read_unlock(idx); local_bh_enable(); } while (0)#define br_write_unlock_irqrestore(idx, flags) \	do { br_write_unlock(irx); local_irq_restore(flags); } while (0)#define br_write_unlock_irq(idx) \	do { br_write_unlock(idx); local_irq_enable(); } while (0)#define br_write_unlock_bh(idx) \	do { br_write_unlock(idx); local_bh_enable(); } while (0)#endif /* __LINUX_BRLOCK_H */

⌨️ 快捷键说明

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