Messages in this thread Patch in this message | | | Date | Fri, 27 Jul 2007 17:37:34 +0200 | From | "Remy Bohmer" <> | Subject | [PATCH (updated)]: PTHREAD_PRIO_INHERIT support for ARM. |
| |
Hello All,
Attached I have put a (very simple) patch to make PTHREAD_PRIO_INHERIT work for ARM.
This patch implements the futex_atomic_cmpxchg_inatomic() for the ARM architecture. Without this patch the userland PI mutex will not work on ARM.
I have tested it with pi_stress, classic_pi and our production environment, on the following Cores: * Atmel at91rm9200 (ARM-v4) * Atmel at91sam9261 (ARM-v5)
But it should also work on other ARM cores (like ARM-v6), because it makes use of a cmpxchg() routine that was already there in the kernel and that was optimised for pre- and post- ARM-v6 cores. But even if it doesn't work, it could not make it worse than the current implementation, that one is completely broken, it allows multiple threads in the same protected section. So, with this patch it can only get better ;-)
Coding style checked with checkpatch.pl 0.6 on 2.6.22.1-rt6
So, Please apply.
Kind Regards,
Remy Böhmer PTHREAD_PRIO_INHERIT support for ARM.
This patch implements the futex_atomic_cmpxchg_inatomic() for the ARM architecture. Without this patch the userland PI mutex will not work.
Signed-off-by: Remy Bohmer <linux@bohmer.net> --- # include/asm-arm/futex.h | 64 +++++++++++++++++++++++++++++++++++++++++++++--- # 1 file changed, 61 insertions(+), 3 deletions(-) # Index: linux-2.6.22/include/asm-arm/futex.h =================================================================== --- linux-2.6.22.orig/include/asm-arm/futex.h 2007-07-09 01:32:17.000000000 +0200 +++ linux-2.6.22/include/asm-arm/futex.h 2007-07-24 17:05:26.000000000 +0200 @@ -1,6 +1,64 @@ -#ifndef _ASM_FUTEX_H -#define _ASM_FUTEX_H +#ifndef _ASM_ARM_FUTEX_H +#define _ASM_ARM_FUTEX_H -#include <asm-generic/futex.h> +#ifdef __KERNEL__ +#include <linux/futex.h> +#include <linux/errno.h> +#include <linux/uaccess.h> +#include <asm/atomic.h> + +static inline int +futex_atomic_op_inuser(int encoded_op, int __user *uaddr) +{ + int op = (encoded_op >> 28) & 7; + int cmp = (encoded_op >> 24) & 15; + int oparg = (encoded_op << 8) >> 20; + int cmparg = (encoded_op << 20) >> 20; + int oldval = 0; + int ret; + if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) + oparg = 1 << oparg; + + if (!access_ok (VERIFY_WRITE, uaddr, sizeof(int))) + return -EFAULT; + + pagefault_disable(); + + switch (op) { + case FUTEX_OP_SET: + case FUTEX_OP_ADD: + case FUTEX_OP_OR: + case FUTEX_OP_ANDN: + case FUTEX_OP_XOR: + default: + ret = -ENOSYS; + } + + pagefault_enable(); + + if (!ret) { + switch (cmp) { + case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; + case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; + case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; + case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; + case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; + case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; + default: ret = -ENOSYS; + } + } + return ret; +} + +static inline int +futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) +{ + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) + return -EFAULT; + + return cmpxchg(uaddr, oldval, newval); +} + +#endif #endif | |