cmpxchg.h

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

H
108
字号
/* * This file is subject to the terms and conditions of the GNU General Public * License.  See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 2003, 06, 07 by Ralf Baechle (ralf@linux-mips.org) */#ifndef __ASM_CMPXCHG_H#define __ASM_CMPXCHG_H#include <linux/irqflags.h>#define __HAVE_ARCH_CMPXCHG 1#define __cmpxchg_asm(ld, st, m, old, new)				\({									\	__typeof(*(m)) __ret;						\									\	if (cpu_has_llsc && R10000_LLSC_WAR) {				\		__asm__ __volatile__(					\		"	.set	push				\n"	\		"	.set	noat				\n"	\		"	.set	mips3				\n"	\		"1:	" ld "	%0, %2		# __cmpxchg_asm	\n"	\		"	bne	%0, %z3, 2f			\n"	\		"	.set	mips0				\n"	\		"	move	$1, %z4				\n"	\		"	.set	mips3				\n"	\		"	" st "	$1, %1				\n"	\		"	beqzl	$1, 1b				\n"	\		"2:						\n"	\		"	.set	pop				\n"	\		: "=&r" (__ret), "=R" (*m)				\		: "R" (*m), "Jr" (old), "Jr" (new)			\		: "memory");						\	} else if (cpu_has_llsc) {					\		__asm__ __volatile__(					\		"	.set	push				\n"	\		"	.set	noat				\n"	\		"	.set	mips3				\n"	\		"1:	" ld "	%0, %2		# __cmpxchg_asm	\n"	\		"	bne	%0, %z3, 2f			\n"	\		"	.set	mips0				\n"	\		"	move	$1, %z4				\n"	\		"	.set	mips3				\n"	\		"	" st "	$1, %1				\n"	\		"	beqz	$1, 3f				\n"	\		"2:						\n"	\		"	.subsection 2				\n"	\		"3:	b	1b				\n"	\		"	.previous				\n"	\		"	.set	pop				\n"	\		: "=&r" (__ret), "=R" (*m)				\		: "R" (*m), "Jr" (old), "Jr" (new)			\		: "memory");						\	} else {							\		unsigned long __flags;					\									\		raw_local_irq_save(__flags);				\		__ret = *m;						\		if (__ret == old)					\			*m = new;					\		raw_local_irq_restore(__flags);				\	}								\									\	__ret;								\})/* * This function doesn't exist, so you'll get a linker error * if something tries to do an invalid cmpxchg(). */extern void __cmpxchg_called_with_bad_pointer(void);#define __cmpxchg(ptr, old, new, barrier)				\({									\	__typeof__(ptr) __ptr = (ptr);					\	__typeof__(*(ptr)) __old = (old);				\	__typeof__(*(ptr)) __new = (new);				\	__typeof__(*(ptr)) __res = 0;					\									\	barrier;							\									\	switch (sizeof(*(__ptr))) {					\	case 4:								\		__res = __cmpxchg_asm("ll", "sc", __ptr, __old, __new);	\		break;							\	case 8:								\		if (sizeof(long) == 8) {				\			__res = __cmpxchg_asm("lld", "scd", __ptr,	\					   __old, __new);		\			break;						\		}							\	default:							\		__cmpxchg_called_with_bad_pointer();			\		break;							\	}								\									\	barrier;							\									\	__res;								\})#define cmpxchg(ptr, old, new)		__cmpxchg(ptr, old, new, smp_llsc_mb())#define cmpxchg_local(ptr, old, new)	__cmpxchg(ptr, old, new, )#endif /* __ASM_CMPXCHG_H */

⌨️ 快捷键说明

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