futex-irq.h 1.8 KB
Newer Older
K
Kaz Kojima 已提交
1 2 3 4 5
#ifndef __ASM_SH_FUTEX_IRQ_H
#define __ASM_SH_FUTEX_IRQ_H

#include <asm/system.h>

6
static inline int atomic_futex_op_xchg_set(int oparg, u32 __user *uaddr,
K
Kaz Kojima 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
					   int *oldval)
{
	unsigned long flags;
	int ret;

	local_irq_save(flags);

	ret = get_user(*oldval, uaddr);
	if (!ret)
		ret = put_user(oparg, uaddr);

	local_irq_restore(flags);

	return ret;
}

23
static inline int atomic_futex_op_xchg_add(int oparg, u32 __user *uaddr,
K
Kaz Kojima 已提交
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
					   int *oldval)
{
	unsigned long flags;
	int ret;

	local_irq_save(flags);

	ret = get_user(*oldval, uaddr);
	if (!ret)
		ret = put_user(*oldval + oparg, uaddr);

	local_irq_restore(flags);

	return ret;
}

40
static inline int atomic_futex_op_xchg_or(int oparg, u32 __user *uaddr,
K
Kaz Kojima 已提交
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
					  int *oldval)
{
	unsigned long flags;
	int ret;

	local_irq_save(flags);

	ret = get_user(*oldval, uaddr);
	if (!ret)
		ret = put_user(*oldval | oparg, uaddr);

	local_irq_restore(flags);

	return ret;
}

57
static inline int atomic_futex_op_xchg_and(int oparg, u32 __user *uaddr,
K
Kaz Kojima 已提交
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
					   int *oldval)
{
	unsigned long flags;
	int ret;

	local_irq_save(flags);

	ret = get_user(*oldval, uaddr);
	if (!ret)
		ret = put_user(*oldval & oparg, uaddr);

	local_irq_restore(flags);

	return ret;
}

74
static inline int atomic_futex_op_xchg_xor(int oparg, u32 __user *uaddr,
K
Kaz Kojima 已提交
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
					   int *oldval)
{
	unsigned long flags;
	int ret;

	local_irq_save(flags);

	ret = get_user(*oldval, uaddr);
	if (!ret)
		ret = put_user(*oldval ^ oparg, uaddr);

	local_irq_restore(flags);

	return ret;
}

91 92 93
static inline int atomic_futex_op_cmpxchg_inatomic(u32 *uval,
						   u32 __user *uaddr,
						   u32 oldval, u32 newval)
K
Kaz Kojima 已提交
94 95
{
	unsigned long flags;
96 97
	int ret;
	u32 prev = 0;
K
Kaz Kojima 已提交
98 99 100 101 102 103 104 105 106

	local_irq_save(flags);

	ret = get_user(prev, uaddr);
	if (!ret && oldval == prev)
		ret = put_user(newval, uaddr);

	local_irq_restore(flags);

107 108
	*uval = prev;
	return ret;
K
Kaz Kojima 已提交
109 110 111
}

#endif /* __ASM_SH_FUTEX_IRQ_H */