atomic-long.h revision 337898
11556Srgrimes/*-
21556Srgrimes * Copyright (c) 2010 Isilon Systems, Inc.
31556Srgrimes * Copyright (c) 2010 iX Systems, Inc.
41556Srgrimes * Copyright (c) 2010 Panasas, Inc.
51556Srgrimes * Copyright (c) 2013-2017 Mellanox Technologies, Ltd.
61556Srgrimes * All rights reserved.
71556Srgrimes *
81556Srgrimes * Redistribution and use in source and binary forms, with or without
91556Srgrimes * modification, are permitted provided that the following conditions
101556Srgrimes * are met:
111556Srgrimes * 1. Redistributions of source code must retain the above copyright
121556Srgrimes *    notice unmodified, this list of conditions, and the following
131556Srgrimes *    disclaimer.
141556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
151556Srgrimes *    notice, this list of conditions and the following disclaimer in the
161556Srgrimes *    documentation and/or other materials provided with the distribution.
171556Srgrimes *
181556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
191556Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
201556Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
211556Srgrimes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
221556Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
231556Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
241556Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
251556Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
261556Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
271556Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
281556Srgrimes *
291556Srgrimes * $FreeBSD: stable/11/sys/compat/linuxkpi/common/include/asm/atomic-long.h 337898 2018-08-16 08:12:36Z hselasky $
301556Srgrimes */
311556Srgrimes#ifndef	_ATOMIC_LONG_H_
321556Srgrimes#define	_ATOMIC_LONG_H_
331556Srgrimes
341556Srgrimes#include <linux/compiler.h>
351556Srgrimes#include <sys/types.h>
3617987Speter#include <machine/atomic.h>
3750471Speter
381556Srgrimes#define	ATOMIC_LONG_INIT(x)	{ .counter = (x) }
391556Srgrimes
401556Srgrimestypedef struct {
411556Srgrimes	volatile long counter;
421556Srgrimes} atomic_long_t;
431556Srgrimes
441556Srgrimes#define	atomic_long_add(i, v)		atomic_long_add_return((i), (v))
4590111Simp#define	atomic_long_inc_return(v)	atomic_long_add_return(1, (v))
4690111Simp#define	atomic_long_inc_not_zero(v)	atomic_long_add_unless((v), 1, 0)
4790111Simp
4890111Simpstatic inline long
4990111Simpatomic_long_add_return(long i, atomic_long_t *v)
5017987Speter{
51	return i + atomic_fetchadd_long(&v->counter, i);
52}
53
54static inline void
55atomic_long_set(atomic_long_t *v, long i)
56{
57	WRITE_ONCE(v->counter, i);
58}
59
60static inline long
61atomic_long_read(atomic_long_t *v)
62{
63	return READ_ONCE(v->counter);
64}
65
66static inline long
67atomic_long_inc(atomic_long_t *v)
68{
69	return atomic_fetchadd_long(&v->counter, 1) + 1;
70}
71
72static inline long
73atomic_long_dec(atomic_long_t *v)
74{
75	return atomic_fetchadd_long(&v->counter, -1) - 1;
76}
77
78static inline long
79atomic_long_xchg(atomic_long_t *v, long val)
80{
81	return atomic_swap_long(&v->counter, val);
82}
83
84static inline long
85atomic_long_cmpxchg(atomic_long_t *v, long old, long new)
86{
87	long ret = old;
88
89	for (;;) {
90		if (atomic_fcmpset_long(&v->counter, &ret, new))
91			break;
92		if (ret != old)
93			break;
94	}
95	return (ret);
96}
97
98static inline int
99atomic_long_add_unless(atomic_long_t *v, long a, long u)
100{
101	long c = atomic_long_read(v);
102
103	for (;;) {
104		if (unlikely(c == u))
105			break;
106		if (likely(atomic_fcmpset_long(&v->counter, &c, c + a)))
107			break;
108	}
109	return (c != u);
110}
111
112static inline long
113atomic_long_dec_and_test(atomic_long_t *v)
114{
115	long i = atomic_long_add(-1, v);
116	return i == 0 ;
117}
118
119#endif	/* _ATOMIC_LONG_H_ */
120