1 #ifndef __ASM_SH_FUTEX_H
2 #define __ASM_SH_FUTEX_H
6 #include <linux/futex.h>
7 #include <linux/uaccess.h>
10 #if !defined(CONFIG_SMP)
11 #include <asm/futex-irq.h>
12 #elif defined(CONFIG_CPU_J2)
13 #include <asm/futex-cas.h>
14 #elif defined(CONFIG_CPU_SH4A)
15 #include <asm/futex-llsc.h>
17 #error SMP not supported on this configuration.
21 futex_atomic_cmpxchg_inatomic(u32
*uval
, u32 __user
*uaddr
,
22 u32 oldval
, u32 newval
)
24 if (!access_ok(VERIFY_WRITE
, uaddr
, sizeof(u32
)))
27 return atomic_futex_op_cmpxchg_inatomic(uval
, uaddr
, oldval
, newval
);
30 static inline int futex_atomic_op_inuser(int encoded_op
, u32 __user
*uaddr
)
32 int op
= (encoded_op
>> 28) & 7;
33 int cmp
= (encoded_op
>> 24) & 15;
34 u32 oparg
= (encoded_op
<< 8) >> 20;
35 u32 cmparg
= (encoded_op
<< 20) >> 20;
36 u32 oldval
, newval
, prev
;
39 if (encoded_op
& (FUTEX_OP_OPARG_SHIFT
<< 28))
42 if (!access_ok(VERIFY_WRITE
, uaddr
, sizeof(u32
)))
48 if (op
== FUTEX_OP_SET
)
51 ret
= get_user(oldval
, uaddr
);
60 newval
= oldval
+ oparg
;
63 newval
= oldval
| oparg
;
66 newval
= oldval
& ~oparg
;
69 newval
= oldval
^ oparg
;
78 ret
= futex_atomic_cmpxchg_inatomic(&prev
, uaddr
, oldval
, newval
);
79 } while (!ret
&& prev
!= oldval
);
85 case FUTEX_OP_CMP_EQ
: ret
= (oldval
== cmparg
); break;
86 case FUTEX_OP_CMP_NE
: ret
= (oldval
!= cmparg
); break;
87 case FUTEX_OP_CMP_LT
: ret
= ((int)oldval
< (int)cmparg
); break;
88 case FUTEX_OP_CMP_GE
: ret
= ((int)oldval
>= (int)cmparg
); break;
89 case FUTEX_OP_CMP_LE
: ret
= ((int)oldval
<= (int)cmparg
); break;
90 case FUTEX_OP_CMP_GT
: ret
= ((int)oldval
> (int)cmparg
); break;
91 default: ret
= -ENOSYS
;
98 #endif /* __KERNEL__ */
99 #endif /* __ASM_SH_FUTEX_H */