aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-sh/futex-irq.h
diff options
context:
space:
mode:
authorKaz Kojima <kkojima@rr.iij4u.or.jp>2007-06-18 00:58:32 -0400
committerPaul Mundt <lethal@linux-sh.org>2007-06-18 00:58:32 -0400
commitfc1d4c9c3761ca8db52b647c6a4ba50771900a12 (patch)
tree205ec8220fac5ee77e3430bb0248426eb92effe8 /include/asm-sh/futex-irq.h
parenteee4c4694fb2936258244bb391e6eec07f3eea8e (diff)
sh: Fix up futex implementation.
SH is able to support a complete futex implementation on UP by way of gUSA. However, IRQ toggling must be done for the old CPUs that don't have movli.l/movco.l (LL/SC) instructions. Provide a default implementation that does this, so it's possible to optimize for newer CPUs. Follows the same scheme as the current asm-sh/atomic-*.h headers. Signed-off-by: Kaz Kojima <kkojima@rr.iij4u.or.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'include/asm-sh/futex-irq.h')
-rw-r--r--include/asm-sh/futex-irq.h111
1 files changed, 111 insertions, 0 deletions
diff --git a/include/asm-sh/futex-irq.h b/include/asm-sh/futex-irq.h
new file mode 100644
index 000000000000..a9f16a7f9aea
--- /dev/null
+++ b/include/asm-sh/futex-irq.h
@@ -0,0 +1,111 @@
1#ifndef __ASM_SH_FUTEX_IRQ_H
2#define __ASM_SH_FUTEX_IRQ_H
3
4#include <asm/system.h>
5
6static inline int atomic_futex_op_xchg_set(int oparg, int __user *uaddr,
7 int *oldval)
8{
9 unsigned long flags;
10 int ret;
11
12 local_irq_save(flags);
13
14 ret = get_user(*oldval, uaddr);
15 if (!ret)
16 ret = put_user(oparg, uaddr);
17
18 local_irq_restore(flags);
19
20 return ret;
21}
22
23static inline int atomic_futex_op_xchg_add(int oparg, int __user *uaddr,
24 int *oldval)
25{
26 unsigned long flags;
27 int ret;
28
29 local_irq_save(flags);
30
31 ret = get_user(*oldval, uaddr);
32 if (!ret)
33 ret = put_user(*oldval + oparg, uaddr);
34
35 local_irq_restore(flags);
36
37 return ret;
38}
39
40static inline int atomic_futex_op_xchg_or(int oparg, int __user *uaddr,
41 int *oldval)
42{
43 unsigned long flags;
44 int ret;
45
46 local_irq_save(flags);
47
48 ret = get_user(*oldval, uaddr);
49 if (!ret)
50 ret = put_user(*oldval | oparg, uaddr);
51
52 local_irq_restore(flags);
53
54 return ret;
55}
56
57static inline int atomic_futex_op_xchg_and(int oparg, int __user *uaddr,
58 int *oldval)
59{
60 unsigned long flags;
61 int ret;
62
63 local_irq_save(flags);
64
65 ret = get_user(*oldval, uaddr);
66 if (!ret)
67 ret = put_user(*oldval & oparg, uaddr);
68
69 local_irq_restore(flags);
70
71 return ret;
72}
73
74static inline int atomic_futex_op_xchg_xor(int oparg, int __user *uaddr,
75 int *oldval)
76{
77 unsigned long flags;
78 int ret;
79
80 local_irq_save(flags);
81
82 ret = get_user(*oldval, uaddr);
83 if (!ret)
84 ret = put_user(*oldval ^ oparg, uaddr);
85
86 local_irq_restore(flags);
87
88 return ret;
89}
90
91static inline int atomic_futex_op_cmpxchg_inatomic(int __user *uaddr,
92 int oldval, int newval)
93{
94 unsigned long flags;
95 int ret, prev = 0;
96
97 local_irq_save(flags);
98
99 ret = get_user(prev, uaddr);
100 if (!ret && oldval == prev)
101 ret = put_user(newval, uaddr);
102
103 local_irq_restore(flags);
104
105 if (ret)
106 return ret;
107
108 return prev;
109}
110
111#endif /* __ASM_SH_FUTEX_IRQ_H */