diff options
author | hselasky <hselasky@FreeBSD.org> | 2016-01-21 17:52:55 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2016-01-21 17:52:55 +0000 |
commit | 6bd95caf293cb5235dc170854e683462f4230ddf (patch) | |
tree | 8daa887201bd2fc889c91c6322e6b28a53fe4155 /sys/compat | |
parent | b0fce449a8e83171ebdc4b8beca48d736d6ea82b (diff) | |
download | FreeBSD-src-6bd95caf293cb5235dc170854e683462f4230ddf.zip FreeBSD-src-6bd95caf293cb5235dc170854e683462f4230ddf.tar.gz |
LinuxKPI atomic fixes:
- Fix implementation of atomic_add_unless(). The atomic_cmpset_int()
function returns a boolean and not the previous value of the atomic
variable.
- The atomic counters should be signed according to Linux.
- Some minor cosmetics and styling while at it.
Reviewed by: alfred @
MFC after: 1 week
Sponsored by: Mellanox Technologies
Diffstat (limited to 'sys/compat')
-rw-r--r-- | sys/compat/linuxkpi/common/include/asm/atomic-long.h | 2 | ||||
-rw-r--r-- | sys/compat/linuxkpi/common/include/asm/atomic.h | 42 |
2 files changed, 22 insertions, 22 deletions
diff --git a/sys/compat/linuxkpi/common/include/asm/atomic-long.h b/sys/compat/linuxkpi/common/include/asm/atomic-long.h index f522af8..0cf91c9 100644 --- a/sys/compat/linuxkpi/common/include/asm/atomic-long.h +++ b/sys/compat/linuxkpi/common/include/asm/atomic-long.h @@ -36,7 +36,7 @@ #include <machine/atomic.h> typedef struct { - volatile u_long counter; + volatile long counter; } atomic_long_t; #define atomic_long_add(i, v) atomic_long_add_return((i), (v)) diff --git a/sys/compat/linuxkpi/common/include/asm/atomic.h b/sys/compat/linuxkpi/common/include/asm/atomic.h index fc22a39..ee85624 100644 --- a/sys/compat/linuxkpi/common/include/asm/atomic.h +++ b/sys/compat/linuxkpi/common/include/asm/atomic.h @@ -2,7 +2,7 @@ * Copyright (c) 2010 Isilon Systems, Inc. * Copyright (c) 2010 iX Systems, Inc. * Copyright (c) 2010 Panasas, Inc. - * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd. + * Copyright (c) 2013-2016 Mellanox Technologies, Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,9 +36,13 @@ #include <machine/atomic.h> typedef struct { - volatile u_int counter; + volatile int counter; } atomic_t; +/*------------------------------------------------------------------------* + * 32-bit atomic operations + *------------------------------------------------------------------------*/ + #define atomic_add(i, v) atomic_add_return((i), (v)) #define atomic_sub(i, v) atomic_sub_return((i), (v)) #define atomic_inc_return(v) atomic_add_return(1, (v)) @@ -46,7 +50,8 @@ typedef struct { #define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0) #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) #define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0) -#define atomic_dec_return(v) atomic_sub_return(1, (v)) +#define atomic_dec_return(v) atomic_sub_return(1, (v)) +#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) static inline int atomic_add_return(int i, atomic_t *v) @@ -84,24 +89,19 @@ atomic_dec(atomic_t *v) return atomic_fetchadd_int(&v->counter, -1) - 1; } -static inline int atomic_add_unless(atomic_t *v, int a, int u) +static inline int +atomic_add_unless(atomic_t *v, int a, int u) { - int c, old; - c = atomic_read(v); - for (;;) { - if (unlikely(c == (u))) - break; - old = atomic_cmpset_int(&v->counter, c, c + (a)); - if (likely(old == c)) - break; - c = old; - } - return c != (u); -} - -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) - - + int c; + for (;;) { + c = atomic_read(v); + if (unlikely(c == u)) + break; + if (likely(atomic_cmpset_int(&v->counter, c, c + a))) + break; + } + return (c != u); +} -#endif /* _ASM_ATOMIC_H_ */ +#endif /* _ASM_ATOMIC_H_ */ |