xref: /linux/arch/sh/include/asm/futex-irq.h (revision ca55b2fef3a9373fcfc30f82fd26bc7fccbda732)
1 #ifndef __ASM_SH_FUTEX_IRQ_H
2 #define __ASM_SH_FUTEX_IRQ_H
3 
4 
5 static inline int atomic_futex_op_xchg_set(int oparg, u32 __user *uaddr,
6 					   int *oldval)
7 {
8 	unsigned long flags;
9 	int ret;
10 
11 	local_irq_save(flags);
12 
13 	ret = get_user(*oldval, uaddr);
14 	if (!ret)
15 		ret = put_user(oparg, uaddr);
16 
17 	local_irq_restore(flags);
18 
19 	return ret;
20 }
21 
22 static inline int atomic_futex_op_xchg_add(int oparg, u32 __user *uaddr,
23 					   int *oldval)
24 {
25 	unsigned long flags;
26 	int ret;
27 
28 	local_irq_save(flags);
29 
30 	ret = get_user(*oldval, uaddr);
31 	if (!ret)
32 		ret = put_user(*oldval + oparg, uaddr);
33 
34 	local_irq_restore(flags);
35 
36 	return ret;
37 }
38 
39 static inline int atomic_futex_op_xchg_or(int oparg, u32 __user *uaddr,
40 					  int *oldval)
41 {
42 	unsigned long flags;
43 	int ret;
44 
45 	local_irq_save(flags);
46 
47 	ret = get_user(*oldval, uaddr);
48 	if (!ret)
49 		ret = put_user(*oldval | oparg, uaddr);
50 
51 	local_irq_restore(flags);
52 
53 	return ret;
54 }
55 
56 static inline int atomic_futex_op_xchg_and(int oparg, u32 __user *uaddr,
57 					   int *oldval)
58 {
59 	unsigned long flags;
60 	int ret;
61 
62 	local_irq_save(flags);
63 
64 	ret = get_user(*oldval, uaddr);
65 	if (!ret)
66 		ret = put_user(*oldval & oparg, uaddr);
67 
68 	local_irq_restore(flags);
69 
70 	return ret;
71 }
72 
73 static inline int atomic_futex_op_xchg_xor(int oparg, u32 __user *uaddr,
74 					   int *oldval)
75 {
76 	unsigned long flags;
77 	int ret;
78 
79 	local_irq_save(flags);
80 
81 	ret = get_user(*oldval, uaddr);
82 	if (!ret)
83 		ret = put_user(*oldval ^ oparg, uaddr);
84 
85 	local_irq_restore(flags);
86 
87 	return ret;
88 }
89 
90 static inline int atomic_futex_op_cmpxchg_inatomic(u32 *uval,
91 						   u32 __user *uaddr,
92 						   u32 oldval, u32 newval)
93 {
94 	unsigned long flags;
95 	int ret;
96 	u32 prev = 0;
97 
98 	local_irq_save(flags);
99 
100 	ret = get_user(prev, uaddr);
101 	if (!ret && oldval == prev)
102 		ret = put_user(newval, uaddr);
103 
104 	local_irq_restore(flags);
105 
106 	*uval = prev;
107 	return ret;
108 }
109 
110 #endif /* __ASM_SH_FUTEX_IRQ_H */
111