Matt Turner wrote:
Hi,

Going on Richard's advice, I've tried to write an alpha futex
implementation based on the powerpc futex.h.

I've gotten this far.. :\


#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
     __asm__ __volatile(             \
     __ASM_MB                        \
     "1: ldl_l   %0,0(%3)\n"         \
         insn                        \
     "2: stl_c   %1,0(%3)\n"         \
     "   beq     %1,4f\n"            \
     "   mov     $31,%1\n"           \
     "3: .subsection 2\n"            \
     "4: br      1b\n"               \
     "   .previous\n"                \
     ".section __ex_table,\"a\"\n"   \
     "   .long   1b-.\n"             \
     "   lda     %0,3b-1b(%2)\n"     \
     "   .long   2b-.\n"             \
     "   lda     %0,3b-2b(%2)\n"     \
     "   .previous\n"                \
     : "=&r" (oldval), "=&r"(ret)    \
     : "r" (uaddr), "r"(oparg)       \
     : "memory")

  switch (op) {
    case FUTEX_OP_SET:
      __futex_atomic_op("mov %0,%1", ret, oldval, uaddr, oparg);
      break;
    case FUTEX_OP_ADD:
      __futex_atomic_op("addl %0,%4,%1\n", ret, oldval, uaddr, oparg);
      break;
    case FUTEX_OP_OR:
      __futex_atomic_op("or %0,%4,%1\n", ret, oldval, uaddr, oparg);
      break;
    case FUTEX_OP_ANDN:
      __futex_atomic_op("andnot %0,%4,%1\n", ret, oldval, uaddr, oparg);
      break;
    case FUTEX_OP_XOR:
      __futex_atomic_op("xor %0,%4,%1\n", ret, oldval, uaddr, oparg);
      break;
    default:
      ret = -ENOSYS;
  }


Also, there's a bug in the powerpc implementation. It appears that oparg is clobbered, and if stwcx fails the operation will be repeated with incorrect inputs.


r~



_______________________________________________
Linuxppc-dev mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to