18d59ecb2SHans Petter Selasky /*-
28d59ecb2SHans Petter Selasky * Copyright (c) 2010 Isilon Systems, Inc.
38d59ecb2SHans Petter Selasky * Copyright (c) 2010 iX Systems, Inc.
48d59ecb2SHans Petter Selasky * Copyright (c) 2010 Panasas, Inc.
562bae5d4SHans Petter Selasky * Copyright (c) 2013-2017 Mellanox Technologies, Ltd.
68d59ecb2SHans Petter Selasky * All rights reserved.
78d59ecb2SHans Petter Selasky *
88d59ecb2SHans Petter Selasky * Redistribution and use in source and binary forms, with or without
98d59ecb2SHans Petter Selasky * modification, are permitted provided that the following conditions
108d59ecb2SHans Petter Selasky * are met:
118d59ecb2SHans Petter Selasky * 1. Redistributions of source code must retain the above copyright
128d59ecb2SHans Petter Selasky * notice unmodified, this list of conditions, and the following
138d59ecb2SHans Petter Selasky * disclaimer.
148d59ecb2SHans Petter Selasky * 2. Redistributions in binary form must reproduce the above copyright
158d59ecb2SHans Petter Selasky * notice, this list of conditions and the following disclaimer in the
168d59ecb2SHans Petter Selasky * documentation and/or other materials provided with the distribution.
178d59ecb2SHans Petter Selasky *
188d59ecb2SHans Petter Selasky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
198d59ecb2SHans Petter Selasky * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
208d59ecb2SHans Petter Selasky * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
218d59ecb2SHans Petter Selasky * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
228d59ecb2SHans Petter Selasky * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
238d59ecb2SHans Petter Selasky * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
248d59ecb2SHans Petter Selasky * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
258d59ecb2SHans Petter Selasky * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
268d59ecb2SHans Petter Selasky * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
278d59ecb2SHans Petter Selasky * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
288d59ecb2SHans Petter Selasky */
29307f78f3SVladimir Kondratyev #ifndef _LINUXKPI_ASM_ATOMIC_LONG_H_
30307f78f3SVladimir Kondratyev #define _LINUXKPI_ASM_ATOMIC_LONG_H_
318d59ecb2SHans Petter Selasky
3262bae5d4SHans Petter Selasky #include <linux/compiler.h>
338d59ecb2SHans Petter Selasky #include <sys/types.h>
348d59ecb2SHans Petter Selasky #include <machine/atomic.h>
352bb46d55SHans Petter Selasky #define ATOMIC_LONG_INIT(x) { .counter = (x) }
362bb46d55SHans Petter Selasky
378d59ecb2SHans Petter Selasky typedef struct {
3829cbb3beSHans Petter Selasky volatile long counter;
398d59ecb2SHans Petter Selasky } atomic_long_t;
408d59ecb2SHans Petter Selasky
418d59ecb2SHans Petter Selasky #define atomic_long_add(i, v) atomic_long_add_return((i), (v))
42*9491ea7cSJean-Sébastien Pédron #define atomic_long_sub(i, v) atomic_long_sub_return((i), (v))
438d59ecb2SHans Petter Selasky #define atomic_long_inc_return(v) atomic_long_add_return(1, (v))
4444701cf7SHans Petter Selasky #define atomic_long_inc_not_zero(v) atomic_long_add_unless((v), 1, 0)
458d59ecb2SHans Petter Selasky
468d59ecb2SHans Petter Selasky static inline long
atomic_long_add_return(long i,atomic_long_t * v)478d59ecb2SHans Petter Selasky atomic_long_add_return(long i, atomic_long_t *v)
488d59ecb2SHans Petter Selasky {
498d59ecb2SHans Petter Selasky return i + atomic_fetchadd_long(&v->counter, i);
508d59ecb2SHans Petter Selasky }
518d59ecb2SHans Petter Selasky
52*9491ea7cSJean-Sébastien Pédron static inline long
atomic_long_sub_return(long i,atomic_long_t * v)53*9491ea7cSJean-Sébastien Pédron atomic_long_sub_return(long i, atomic_long_t *v)
54*9491ea7cSJean-Sébastien Pédron {
55*9491ea7cSJean-Sébastien Pédron return atomic_fetchadd_long(&v->counter, -i) - i;
56*9491ea7cSJean-Sébastien Pédron }
57*9491ea7cSJean-Sébastien Pédron
588d59ecb2SHans Petter Selasky static inline void
atomic_long_set(atomic_long_t * v,long i)598d59ecb2SHans Petter Selasky atomic_long_set(atomic_long_t *v, long i)
608d59ecb2SHans Petter Selasky {
6162bae5d4SHans Petter Selasky WRITE_ONCE(v->counter, i);
628d59ecb2SHans Petter Selasky }
638d59ecb2SHans Petter Selasky
648d59ecb2SHans Petter Selasky static inline long
atomic_long_read(atomic_long_t * v)658d59ecb2SHans Petter Selasky atomic_long_read(atomic_long_t *v)
668d59ecb2SHans Petter Selasky {
6762bae5d4SHans Petter Selasky return READ_ONCE(v->counter);
688d59ecb2SHans Petter Selasky }
698d59ecb2SHans Petter Selasky
708d59ecb2SHans Petter Selasky static inline long
atomic_long_inc(atomic_long_t * v)718d59ecb2SHans Petter Selasky atomic_long_inc(atomic_long_t *v)
728d59ecb2SHans Petter Selasky {
738d59ecb2SHans Petter Selasky return atomic_fetchadd_long(&v->counter, 1) + 1;
748d59ecb2SHans Petter Selasky }
758d59ecb2SHans Petter Selasky
768d59ecb2SHans Petter Selasky static inline long
atomic_long_dec(atomic_long_t * v)778d59ecb2SHans Petter Selasky atomic_long_dec(atomic_long_t *v)
788d59ecb2SHans Petter Selasky {
798d59ecb2SHans Petter Selasky return atomic_fetchadd_long(&v->counter, -1) - 1;
808d59ecb2SHans Petter Selasky }
818d59ecb2SHans Petter Selasky
82622f2291SHans Petter Selasky static inline long
atomic_long_xchg(atomic_long_t * v,long val)83622f2291SHans Petter Selasky atomic_long_xchg(atomic_long_t *v, long val)
84622f2291SHans Petter Selasky {
85622f2291SHans Petter Selasky return atomic_swap_long(&v->counter, val);
86622f2291SHans Petter Selasky }
87622f2291SHans Petter Selasky
88db119089SHans Petter Selasky static inline long
atomic_long_cmpxchg(atomic_long_t * v,long old,long new)89db119089SHans Petter Selasky atomic_long_cmpxchg(atomic_long_t *v, long old, long new)
90db119089SHans Petter Selasky {
91db119089SHans Petter Selasky long ret = old;
92db119089SHans Petter Selasky
93db119089SHans Petter Selasky for (;;) {
946402bc3dSHans Petter Selasky if (atomic_fcmpset_long(&v->counter, &ret, new))
95db119089SHans Petter Selasky break;
96db119089SHans Petter Selasky if (ret != old)
97db119089SHans Petter Selasky break;
98db119089SHans Petter Selasky }
99db119089SHans Petter Selasky return (ret);
100db119089SHans Petter Selasky }
101db119089SHans Petter Selasky
10244701cf7SHans Petter Selasky static inline int
atomic_long_add_unless(atomic_long_t * v,long a,long u)10344701cf7SHans Petter Selasky atomic_long_add_unless(atomic_long_t *v, long a, long u)
10444701cf7SHans Petter Selasky {
1056402bc3dSHans Petter Selasky long c = atomic_long_read(v);
10644701cf7SHans Petter Selasky
10744701cf7SHans Petter Selasky for (;;) {
10844701cf7SHans Petter Selasky if (unlikely(c == u))
10944701cf7SHans Petter Selasky break;
1106402bc3dSHans Petter Selasky if (likely(atomic_fcmpset_long(&v->counter, &c, c + a)))
11144701cf7SHans Petter Selasky break;
11244701cf7SHans Petter Selasky }
11344701cf7SHans Petter Selasky return (c != u);
11444701cf7SHans Petter Selasky }
11544701cf7SHans Petter Selasky
1168d59ecb2SHans Petter Selasky static inline long
atomic_long_fetch_add_unless(atomic_long_t * v,long a,long u)117b9bf16adSHans Petter Selasky atomic_long_fetch_add_unless(atomic_long_t *v, long a, long u)
118b9bf16adSHans Petter Selasky {
119b9bf16adSHans Petter Selasky long c = atomic_long_read(v);
120b9bf16adSHans Petter Selasky
121b9bf16adSHans Petter Selasky for (;;) {
122b9bf16adSHans Petter Selasky if (unlikely(c == u))
123b9bf16adSHans Petter Selasky break;
124b9bf16adSHans Petter Selasky if (likely(atomic_fcmpset_long(&v->counter, &c, c + a)))
125b9bf16adSHans Petter Selasky break;
126b9bf16adSHans Petter Selasky }
127b9bf16adSHans Petter Selasky return (c);
128b9bf16adSHans Petter Selasky }
129b9bf16adSHans Petter Selasky
130b9bf16adSHans Petter Selasky static inline long
atomic_long_dec_and_test(atomic_long_t * v)1318d59ecb2SHans Petter Selasky atomic_long_dec_and_test(atomic_long_t *v)
1328d59ecb2SHans Petter Selasky {
1338d59ecb2SHans Petter Selasky long i = atomic_long_add(-1, v);
1348d59ecb2SHans Petter Selasky return i == 0 ;
1358d59ecb2SHans Petter Selasky }
1368d59ecb2SHans Petter Selasky
137307f78f3SVladimir Kondratyev #endif /* _LINUXKPI_ASM_ATOMIC_LONG_H_ */
138