home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-sparc64 / futex.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  2.7 KB  |  111 lines

  1. #ifndef _SPARC64_FUTEX_H
  2. #define _SPARC64_FUTEX_H
  3.  
  4. #include <linux/futex.h>
  5. #include <asm/errno.h>
  6. #include <asm/system.h>
  7. #include <asm/uaccess.h>
  8.  
  9. #define __futex_cas_op(insn, ret, oldval, uaddr, oparg)    \
  10.     __asm__ __volatile__(                \
  11.     "\n1:    lduwa    [%3] %%asi, %2\n"        \
  12.     "    " insn "\n"                \
  13.     "2:    casa    [%3] %%asi, %2, %1\n"        \
  14.     "    cmp    %2, %1\n"            \
  15.     "    bne,pn    %%icc, 1b\n"            \
  16.     "     mov    0, %0\n"            \
  17.     "3:\n"                        \
  18.     "    .section .fixup,#alloc,#execinstr\n"    \
  19.     "    .align    4\n"                \
  20.     "4:    ba    3b\n"                \
  21.     "     mov    %5, %0\n"            \
  22.     "    .previous\n"                \
  23.     "    .section __ex_table,\"a\"\n"        \
  24.     "    .align    4\n"                \
  25.     "    .word    1b, 4b\n"            \
  26.     "    .word    2b, 4b\n"            \
  27.     "    .previous\n"                \
  28.     : "=&r" (ret), "=&r" (oldval), "=&r" (tem)    \
  29.     : "r" (uaddr), "r" (oparg), "i" (-EFAULT)    \
  30.     : "memory")
  31.  
  32. static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
  33. {
  34.     int op = (encoded_op >> 28) & 7;
  35.     int cmp = (encoded_op >> 24) & 15;
  36.     int oparg = (encoded_op << 8) >> 20;
  37.     int cmparg = (encoded_op << 20) >> 20;
  38.     int oldval = 0, ret, tem;
  39.  
  40.     if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(int))))
  41.         return -EFAULT;
  42.     if (unlikely((((unsigned long) uaddr) & 0x3UL)))
  43.         return -EINVAL;
  44.  
  45.     if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
  46.         oparg = 1 << oparg;
  47.  
  48.     inc_preempt_count();
  49.  
  50.     switch (op) {
  51.     case FUTEX_OP_SET:
  52.         __futex_cas_op("mov\t%4, %1", ret, oldval, uaddr, oparg);
  53.         break;
  54.     case FUTEX_OP_ADD:
  55.         __futex_cas_op("add\t%2, %4, %1", ret, oldval, uaddr, oparg);
  56.         break;
  57.     case FUTEX_OP_OR:
  58.         __futex_cas_op("or\t%2, %4, %1", ret, oldval, uaddr, oparg);
  59.         break;
  60.     case FUTEX_OP_ANDN:
  61.         __futex_cas_op("and\t%2, %4, %1", ret, oldval, uaddr, oparg);
  62.         break;
  63.     case FUTEX_OP_XOR:
  64.         __futex_cas_op("xor\t%2, %4, %1", ret, oldval, uaddr, oparg);
  65.         break;
  66.     default:
  67.         ret = -ENOSYS;
  68.     }
  69.  
  70.     dec_preempt_count();
  71.  
  72.     if (!ret) {
  73.         switch (cmp) {
  74.         case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
  75.         case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
  76.         case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
  77.         case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
  78.         case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
  79.         case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
  80.         default: ret = -ENOSYS;
  81.         }
  82.     }
  83.     return ret;
  84. }
  85.  
  86. static inline int
  87. futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
  88. {
  89.     __asm__ __volatile__(
  90.     "\n1:    lduwa    [%2] %%asi, %0\n"
  91.     "2:    casa    [%2] %%asi, %0, %1\n"
  92.     "3:\n"
  93.     "    .section .fixup,#alloc,#execinstr\n"
  94.     "    .align    4\n"
  95.     "4:    ba    3b\n"
  96.     "     mov    %3, %0\n"
  97.     "    .previous\n"
  98.     "    .section __ex_table,\"a\"\n"
  99.     "    .align    4\n"
  100.     "    .word    1b, 4b\n"
  101.     "    .word    2b, 4b\n"
  102.     "    .previous\n"
  103.     : "=&r" (oldval)
  104.     : "r" (newval), "r" (uaddr), "i" (-EFAULT)
  105.     : "memory");
  106.  
  107.     return oldval;
  108. }
  109.  
  110. #endif /* !(_SPARC64_FUTEX_H) */
  111.