From c16423ec4e678e5cb01dc99f4115065f8ef6caf7 Mon Sep 17 00:00:00 2001 From: Marcio Barbosa Date: Mon, 14 May 2018 16:46:26 -0300 Subject: [PATCH] rx: fix atomics on darwin As described by commit b2a21422129ca1eeeb5ea1a1f7b08b537fd2a9f7, the API used for atomic operations in kernel space is not the same as the one used in user space. To fix this problem, the commit mentioned above introduced macros to correct the name of these functions in kernel space. Unfortunately, the return value of the functions used in kernel space is not the same as the ones used in user space. Generally speaking, the kernel space atomic functions return the original value of the variable received as an argument before the operation in question. On the other hand, the user space atomic functions return the new value, after the operation has been performed. To fix this problem, this commit provides a new set of inline functions (only used in kernel space) with the expected return values. Also, in order to get the inline implementations of the OSAtomic interfaces in terms of the primitives, commit 74f837fd943ddfa20d349a83d6286a0183cb4663 defines OSATOMIC_USE_INLINED on OS X 10.12. However, the definition of this macro only affects the user space legacy interfaces for atomic operations. The kernel space interfaces for atomics are not deprecated and OSATOMIC_USE_INLINED does not affect these functions. To fix this problem, only define OSATOMIC_USE_INLINED in user space (OS X 10.12+). Change-Id: Ia6cbc76daa7068625dc9f6dff385d0568d6503bd Reviewed-on: https://gerrit.openafs.org/13063 Tested-by: BuildBot Reviewed-by: Benjamin Kaduk --- src/rx/rx_atomic.h | 46 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/src/rx/rx_atomic.h b/src/rx/rx_atomic.h index 5bf35fe..df050e2 100644 --- a/src/rx/rx_atomic.h +++ b/src/rx/rx_atomic.h @@ -184,21 +184,45 @@ rx_atomic_test_and_clear_bit(rx_atomic_t *atomic, int bit) { #elif defined(AFS_DARWIN80_ENV) || defined(AFS_USR_DARWIN80_ENV) -# if defined (AFS_DARWIN160_ENV) || defined(AFS_USR_DARWIN160_ENV) +# if (defined(AFS_DARWIN160_ENV) || defined(AFS_USR_DARWIN160_ENV)) && !defined(KERNEL) # define OSATOMIC_USE_INLINED 1 -# else +# endif -# if defined(KERNEL) && !defined(UKERNEL) -# define OSAtomicIncrement32 OSIncrementAtomic -# define OSAtomicAdd32 OSAddAtomic -# define OSAtomicDecrement32 OSDecrementAtomic -# define OSAtomicOr32 OSBitOrAtomic -# define OSAtomicAnd32 OSBitAndAtomic -# endif +# include -# endif /* end defined DARWIN160 */ +# if defined(KERNEL) && !defined(UKERNEL) +static_inline int +OSAtomicIncrement32(volatile int *value) +{ + return OSIncrementAtomic(value) + 1; +} -# include +static_inline int +OSAtomicAdd32(int amount, volatile int *value) +{ + return OSAddAtomic(amount, value) + amount; +} + +static_inline int +OSAtomicDecrement32(volatile int *value) +{ + return OSDecrementAtomic(value) - 1; +} + +static_inline unsigned int +OSAtomicOr32(unsigned int mask, volatile unsigned int *value) +{ + return OSBitOrAtomic(mask, value) | mask; +} + +static_inline unsigned int +OSAtomicAnd32(unsigned int mask, volatile unsigned int *value) +{ + return OSBitAndAtomic(mask, value) & mask; +} +#define OSAtomicOr32Orig OSBitOrAtomic +#define OSAtomicAnd32Orig OSBitAndAtomic +# endif typedef struct { volatile int var; -- 1.9.4