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

📄 semaphore-helper.h

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 H
字号:
/* $Id: semaphore-helper.h,v 1.6 1999/10/20 21:10:58 ralf Exp $ * * SMP- and interrupt-safe semaphores helper functions. * * (C) Copyright 1996 Linus Torvalds * (C) Copyright 1999 Andrea Arcangeli * (C) Copyright 1999 Ralf Baechle * (C) Copyright 1999 Silicon Graphics, Inc. */#ifndef _ASM_SEMAPHORE_HELPER_H#define _ASM_SEMAPHORE_HELPER_H#include <linux/config.h>/* * These two _must_ execute atomically wrt each other. */static inline void wake_one_more(struct semaphore * sem){	atomic_inc(&sem->waking);}#if !defined(CONFIG_CPU_HAS_LLSC)/* * It doesn't make sense, IMHO, to endlessly turn interrupts off and on again. * Do it once and that's it. ll/sc *has* it's advantages. HK */#define read(a) ((a)->counter)#define inc(a) (((a)->counter)++)#define dec(a) (((a)->counter)--)static inline int waking_non_zero(struct semaphore *sem){	unsigned long flags;	int ret = 0;	save_and_cli(flags);	if (read(&sem->waking) > 0) {		dec(&sem->waking);		ret = 1;	}	restore_flags(flags);	return ret;}static inline int waking_non_zero_interruptible(struct semaphore *sem,						struct task_struct *tsk){	int ret = 0;	unsigned long flags;	save_and_cli(flags);	if (read(&sem->waking) > 0) {		dec(&sem->waking);		ret = 1;	} else if (signal_pending(tsk)) {		inc(&sem->count);		ret = -EINTR;	}	restore_flags(flags);	return ret;}static inline int waking_non_zero_trylock(struct semaphore *sem){        int ret = 1;	unsigned long flags;	save_and_cli(flags);	if (read(&sem->waking) <= 0)		inc(&sem->count);	else {		dec(&sem->waking);		ret = 0;	}	restore_flags(flags);	return ret;}#else /* CONFIG_CPU_HAS_LLSC */static inline intwaking_non_zero(struct semaphore *sem){	int ret, tmp;	__asm__ __volatile__(	"1:\tll\t%1, %2\n\t"	"blez\t%1, 2f\n\t"	"subu\t%0, %1, 1\n\t"	"sc\t%0, %2\n\t"	"beqz\t%0, 1b\n\t"	"2:"	: "=r"(ret), "=r"(tmp), "=m"(__atomic_fool_gcc(&sem->waking))	: "0"(0));	return ret;}/* * waking_non_zero_interruptible: *	1	got the lock *	0	go to sleep *	-EINTR	interrupted * * We must undo the sem->count down_interruptible decrement * simultaneously and atomicly with the sem->waking adjustment, * otherwise we can race with wake_one_more. * * This is accomplished by doing a 64-bit ll/sc on the 2 32-bit words. * * This is crazy.  Normally it stricly forbidden to use 64-bit operations * in the 32-bit MIPS kernel.  In this case it's however ok because if an * interrupt has destroyed the upper half of registers sc will fail. * Note also that this will not work for MIPS32 CPUS! * * Pseudocode: * * If(sem->waking > 0) { *	Decrement(sem->waking) *	Return(SUCCESS) * } else If(segnal_pending(tsk)) { *	Increment(sem->count) *	Return(-EINTR) * } else { *	Return(SLEEP) * } */static inline intwaking_non_zero_interruptible(struct semaphore *sem, struct task_struct *tsk){	long ret, tmp;        __asm__ __volatile__("	.set	push	.set	mips3	.set	noat0:	lld	%1, %2	li	%0, 0	sll	$1, %1, 0	blez	$1, 1f	daddiu	%1, %1, -1	li	%0, 1	b 	2f1:	beqz	%3, 2f	li	%0, %4	dli	$1, 0x0000000100000000	daddu	%1, %1, $12:	scd	%1, %2	beqz	%1, 0b	.set	pop"	: "=&r"(ret), "=&r"(tmp), "=m"(*sem)	: "r"(signal_pending(tsk)), "i"(-EINTR));	return ret;}/* * waking_non_zero_trylock is unused.  we do everything in  * down_trylock and let non-ll/sc hosts bounce around. */static inline intwaking_non_zero_trylock(struct semaphore *sem){#if WAITQUEUE_DEBUG	CHECK_MAGIC(sem->__magic);#endif	return 0;}#endif /* CONFIG_CPU_HAS_LLSC */#endif /* _ASM_SEMAPHORE_HELPER_H */

⌨️ 快捷键说明

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