linux/arch/m68k/include/asm/futex.h
<<
>>
Prefs
   1#ifndef _ASM_M68K_FUTEX_H
   2#define _ASM_M68K_FUTEX_H
   3
   4#ifdef __KERNEL__
   5#if !defined(CONFIG_MMU)
   6#include <asm-generic/futex.h>
   7#else   /* CONFIG_MMU */
   8
   9#include <linux/futex.h>
  10#include <linux/uaccess.h>
  11#include <asm/errno.h>
  12
  13static inline int
  14futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
  15                              u32 oldval, u32 newval)
  16{
  17        u32 val;
  18
  19        if (unlikely(get_user(val, uaddr) != 0))
  20                return -EFAULT;
  21
  22        if (val == oldval && unlikely(put_user(newval, uaddr) != 0))
  23                return -EFAULT;
  24
  25        *uval = val;
  26
  27        return 0;
  28}
  29
  30static inline int
  31futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
  32{
  33        int op = (encoded_op >> 28) & 7;
  34        int cmp = (encoded_op >> 24) & 15;
  35        int oparg = (encoded_op << 8) >> 20;
  36        int cmparg = (encoded_op << 20) >> 20;
  37        int oldval, ret;
  38        u32 tmp;
  39
  40        if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
  41                oparg = 1 << oparg;
  42
  43        pagefault_disable();    /* implies preempt_disable() */
  44
  45        ret = -EFAULT;
  46        if (unlikely(get_user(oldval, uaddr) != 0))
  47                goto out_pagefault_enable;
  48
  49        ret = 0;
  50        tmp = oldval;
  51
  52        switch (op) {
  53        case FUTEX_OP_SET:
  54                tmp = oparg;
  55                break;
  56        case FUTEX_OP_ADD:
  57                tmp += oparg;
  58                break;
  59        case FUTEX_OP_OR:
  60                tmp |= oparg;
  61                break;
  62        case FUTEX_OP_ANDN:
  63                tmp &= ~oparg;
  64                break;
  65        case FUTEX_OP_XOR:
  66                tmp ^= oparg;
  67                break;
  68        default:
  69                ret = -ENOSYS;
  70        }
  71
  72        if (ret == 0 && unlikely(put_user(tmp, uaddr) != 0))
  73                ret = -EFAULT;
  74
  75out_pagefault_enable:
  76        pagefault_enable();     /* subsumes preempt_enable() */
  77
  78        if (ret == 0) {
  79                switch (cmp) {
  80                case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
  81                case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
  82                case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
  83                case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
  84                case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
  85                case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
  86                default: ret = -ENOSYS;
  87                }
  88        }
  89        return ret;
  90}
  91
  92#endif /* CONFIG_MMU */
  93#endif /* __KERNEL__ */
  94#endif /* _ASM_M68K_FUTEX_H */
  95