112 lines
		
	
	
	
		
			1.8 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			112 lines
		
	
	
	
		
			1.8 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
|   | #ifndef __ASM_SH_FUTEX_IRQ_H
 | ||
|  | #define __ASM_SH_FUTEX_IRQ_H
 | ||
|  | 
 | ||
|  | #include <asm/system.h>
 | ||
|  | 
 | ||
|  | static inline int atomic_futex_op_xchg_set(int oparg, int __user *uaddr, | ||
|  | 					   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; | ||
|  | } | ||
|  | 
 | ||
|  | static inline int atomic_futex_op_xchg_add(int oparg, int __user *uaddr, | ||
|  | 					   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; | ||
|  | } | ||
|  | 
 | ||
|  | static inline int atomic_futex_op_xchg_or(int oparg, int __user *uaddr, | ||
|  | 					  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; | ||
|  | } | ||
|  | 
 | ||
|  | static inline int atomic_futex_op_xchg_and(int oparg, int __user *uaddr, | ||
|  | 					   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; | ||
|  | } | ||
|  | 
 | ||
|  | static inline int atomic_futex_op_xchg_xor(int oparg, int __user *uaddr, | ||
|  | 					   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; | ||
|  | } | ||
|  | 
 | ||
|  | static inline int atomic_futex_op_cmpxchg_inatomic(int __user *uaddr, | ||
|  | 						   int oldval, int newval) | ||
|  | { | ||
|  | 	unsigned long flags; | ||
|  | 	int ret, prev = 0; | ||
|  | 
 | ||
|  | 	local_irq_save(flags); | ||
|  | 
 | ||
|  | 	ret = get_user(prev, uaddr); | ||
|  | 	if (!ret && oldval == prev) | ||
|  | 		ret = put_user(newval, uaddr); | ||
|  | 
 | ||
|  | 	local_irq_restore(flags); | ||
|  | 
 | ||
|  | 	if (ret) | ||
|  | 		return ret; | ||
|  | 
 | ||
|  | 	return prev; | ||
|  | } | ||
|  | 
 | ||
|  | #endif /* __ASM_SH_FUTEX_IRQ_H */
 |