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

📄 debuglocks.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
字号:
/* $Id: debuglocks.c,v 1.5 2000/05/09 17:40:14 davem Exp $ * debuglocks.c: Debugging versions of SMP locking primitives. * * Copyright (C) 1998 David S. Miller (davem@redhat.com) */#include <linux/config.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/spinlock.h>#include <asm/system.h>#ifdef CONFIG_SMP/* To enable this code, just define SPIN_LOCK_DEBUG in asm/spinlock.h */#ifdef SPIN_LOCK_DEBUG#define GET_CALLER(PC) __asm__ __volatile__("mov %%i7, %0" : "=r" (PC))static inline void show (char *str, spinlock_t *lock, unsigned long caller){	int cpu = smp_processor_id();	printk("%s(%p) CPU#%d stuck at %08x, owner PC(%08x):CPU(%x)\n",	       str, lock, cpu, (unsigned int) caller,	       lock->owner_pc, lock->owner_cpu);}static inline void show_read (char *str, rwlock_t *lock, unsigned long caller){	int cpu = smp_processor_id();	printk("%s(%p) CPU#%d stuck at %08x, writer PC(%08x):CPU(%x)\n",	       str, lock, cpu, (unsigned int) caller,	       lock->writer_pc, lock->writer_cpu);}static inline void show_write (char *str, rwlock_t *lock, unsigned long caller){	int cpu = smp_processor_id();	printk("%s(%p) CPU#%d stuck at %08x\n",	       str, lock, cpu, (unsigned int) caller);	printk("Writer: PC(%08x):CPU(%x)\n",	       lock->writer_pc, lock->writer_cpu);	printk("Readers: 0[%08x] 1[%08x] 2[%08x] 4[%08x]\n",	       lock->reader_pc[0], lock->reader_pc[1],	       lock->reader_pc[2], lock->reader_pc[3]);}#undef INIT_STUCK#define INIT_STUCK 100000000void _do_spin_lock(spinlock_t *lock, char *str){	unsigned long caller, val;	int stuck = INIT_STUCK;	int cpu = smp_processor_id();	GET_CALLER(caller);again:	__asm__ __volatile__("ldstub [%1], %0"			     : "=r" (val)			     : "r" (&(lock->lock))			     : "memory");	membar("#StoreLoad | #StoreStore");	if (val) {		while (lock->lock) {			if (!--stuck) {				show(str, lock, caller);				stuck = INIT_STUCK;			}			membar("#LoadLoad");		}		goto again;	}	lock->owner_pc = ((unsigned int)caller);	lock->owner_cpu = cpu;}int _spin_trylock(spinlock_t *lock){	unsigned long val, caller;	int cpu = smp_processor_id();	GET_CALLER(caller);	__asm__ __volatile__("ldstub [%1], %0"			     : "=r" (val)			     : "r" (&(lock->lock))			     : "memory");	membar("#StoreLoad | #StoreStore");	if (!val) {		lock->owner_pc = ((unsigned int)caller);		lock->owner_cpu = cpu;	}	return val == 0;}void _do_spin_unlock(spinlock_t *lock){	lock->owner_pc = 0;	lock->owner_cpu = NO_PROC_ID;	membar("#StoreStore | #LoadStore");	lock->lock = 0;}/* Keep INIT_STUCK the same... */void _do_read_lock (rwlock_t *rw, char *str){	unsigned long caller, val;	int stuck = INIT_STUCK;	int cpu = smp_processor_id();	GET_CALLER(caller);wlock_again:	/* Wait for any writer to go away.  */	while (((long)(rw->lock)) < 0) {		if (!--stuck) {			show_read(str, rw, caller);			stuck = INIT_STUCK;		}		membar("#LoadLoad");	}	/* Try once to increment the counter.  */	__asm__ __volatile__("	ldx		[%0], %%g5	brlz,a,pn	%%g5, 2f	 mov		1, %0	add		%%g5, 1, %%g7	casx		[%0], %%g5, %%g7	sub		%%g5, %%g7, %02:"	: "=r" (val)	: "0" (&(rw->lock))	: "g5", "g7", "memory");	membar("#StoreLoad | #StoreStore");	if (val)		goto wlock_again;	rw->reader_pc[cpu] = ((unsigned int)caller);}void _do_read_unlock (rwlock_t *rw, char *str){	unsigned long caller, val;	int stuck = INIT_STUCK;	int cpu = smp_processor_id();	GET_CALLER(caller);	/* Drop our identity _first_. */	rw->reader_pc[cpu] = 0;runlock_again:	/* Spin trying to decrement the counter using casx.  */	__asm__ __volatile__("	ldx	[%0], %%g5	sub	%%g5, 1, %%g7	casx	[%0], %%g5, %%g7	membar	#StoreLoad | #StoreStore	sub	%%g5, %%g7, %0"	: "=r" (val)	: "0" (&(rw->lock))	: "g5", "g7", "memory");	if (val) {		if (!--stuck) {			show_read(str, rw, caller);			stuck = INIT_STUCK;		}		goto runlock_again;	}}void _do_write_lock (rwlock_t *rw, char *str){	unsigned long caller, val;	int stuck = INIT_STUCK;	int cpu = smp_processor_id();	GET_CALLER(caller);wlock_again:	/* Spin while there is another writer. */	while (((long)rw->lock) < 0) {		if (!--stuck) {			show_write(str, rw, caller);			stuck = INIT_STUCK;		}		membar("#LoadLoad");	}	/* Try to acuire the write bit.  */	__asm__ __volatile__("	mov	1, %%g3	sllx	%%g3, 63, %%g3	ldx	[%0], %%g5	brlz,pn	%%g5, 1f	 or	%%g5, %%g3, %%g7	casx	[%0], %%g5, %%g7	membar	#StoreLoad | #StoreStore	ba,pt	%%xcc, 2f	 sub	%%g5, %%g7, %01:	mov	1, %02:"	: "=r" (val)	: "0" (&(rw->lock))	: "g3", "g5", "g7", "memory");	if (val) {		/* We couldn't get the write bit. */		if (!--stuck) {			show_write(str, rw, caller);			stuck = INIT_STUCK;		}		goto wlock_again;	}	if ((rw->lock & ((1UL<<63)-1UL)) != 0UL) {		/* Readers still around, drop the write		 * lock, spin, and try again.		 */		if (!--stuck) {			show_write(str, rw, caller);			stuck = INIT_STUCK;		}		__asm__ __volatile__("		mov	1, %%g3		sllx	%%g3, 63, %%g31:		ldx	[%0], %%g5		andn	%%g5, %%g3, %%g7		casx	[%0], %%g5, %%g7		cmp	%%g5, %%g7		bne,pn	%%xcc, 1b		 membar	#StoreLoad | #StoreStore"		: /* no outputs */		: "r" (&(rw->lock))		: "g3", "g5", "g7", "cc", "memory");		while(rw->lock != 0) {			if (!--stuck) {				show_write(str, rw, caller);				stuck = INIT_STUCK;			}			membar("#LoadLoad");		}		goto wlock_again;	}	/* We have it, say who we are. */	rw->writer_pc = ((unsigned int)caller);	rw->writer_cpu = cpu;}void _do_write_unlock(rwlock_t *rw){	unsigned long caller, val;	int stuck = INIT_STUCK;	GET_CALLER(caller);	/* Drop our identity _first_ */	rw->writer_pc = 0;	rw->writer_cpu = NO_PROC_ID;wlock_again:	__asm__ __volatile__("	mov	1, %%g3	sllx	%%g3, 63, %%g3	ldx	[%0], %%g5	andn	%%g5, %%g3, %%g7	casx	[%0], %%g5, %%g7	membar	#StoreLoad | #StoreStore	sub	%%g5, %%g7, %0"	: "=r" (val)	: "0" (&(rw->lock))	: "g3", "g5", "g7", "memory");	if (val) {		if (!--stuck) {			show_write("write_unlock", rw, caller);			stuck = INIT_STUCK;		}		goto wlock_again;	}}#endif /* SPIN_LOCK_DEBUG */#endif /* CONFIG_SMP */

⌨️ 快捷键说明

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