Path: blob/main/sys/compat/linuxkpi/common/include/asm/atomic64.h
39604 views
/*-1* Copyright (c) 2016-2017 Mellanox Technologies, Ltd.2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice unmodified, this list of conditions, and the following9* disclaimer.10* 2. Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13*14* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR15* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES16* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.17* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,18* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT19* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,20* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY21* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT22* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF23* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.24*/25#ifndef _LINUXKPI_ASM_ATOMIC64_H_26#define _LINUXKPI_ASM_ATOMIC64_H_2728#include <linux/compiler.h>29#include <sys/types.h>30#include <machine/atomic.h>3132typedef struct {33volatile int64_t counter;34} atomic64_t;35#define ATOMIC64_INIT(x) { .counter = (x) }3637/*------------------------------------------------------------------------*38* 64-bit atomic operations39*------------------------------------------------------------------------*/4041#define atomic64_add(i, v) atomic64_add_return((i), (v))42#define atomic64_sub(i, v) atomic64_sub_return((i), (v))43#define atomic64_inc_return(v) atomic64_add_return(1, (v))44#define atomic64_add_negative(i, v) (atomic64_add_return((i), (v)) < 0)45#define atomic64_add_and_test(i, v) (atomic64_add_return((i), (v)) == 0)46#define atomic64_sub_and_test(i, v) (atomic64_sub_return((i), (v)) == 0)47#define atomic64_dec_and_test(v) (atomic64_sub_return(1, (v)) == 0)48#define atomic64_inc_and_test(v) (atomic64_add_return(1, (v)) == 0)49#define atomic64_dec_return(v) atomic64_sub_return(1, (v))50#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)5152static inline int64_t53atomic64_fetch_add(int64_t i, atomic64_t *v)54{55return (atomic_fetchadd_64(&v->counter, i));56}5758static inline int64_t59atomic64_add_return(int64_t i, atomic64_t *v)60{61return i + atomic_fetchadd_64(&v->counter, i);62}6364static inline int64_t65atomic64_sub_return(int64_t i, atomic64_t *v)66{67return atomic_fetchadd_64(&v->counter, -i) - i;68}6970static inline void71atomic64_set(atomic64_t *v, int64_t i)72{73atomic_store_rel_64(&v->counter, i);74}7576static inline int64_t77atomic64_read(atomic64_t *v)78{79return READ_ONCE(v->counter);80}8182static inline int64_t83atomic64_inc(atomic64_t *v)84{85return atomic_fetchadd_64(&v->counter, 1) + 1;86}8788static inline int64_t89atomic64_dec(atomic64_t *v)90{91return atomic_fetchadd_64(&v->counter, -1) - 1;92}9394static inline int64_t95atomic64_add_unless(atomic64_t *v, int64_t a, int64_t u)96{97int64_t c = atomic64_read(v);9899for (;;) {100if (unlikely(c == u))101break;102if (likely(atomic_fcmpset_64(&v->counter, &c, c + a)))103break;104}105return (c != u);106}107108static inline int64_t109atomic64_fetch_add_unless(atomic64_t *v, int64_t a, int64_t u)110{111int64_t c = atomic64_read(v);112113for (;;) {114if (unlikely(c == u))115break;116if (likely(atomic_fcmpset_64(&v->counter, &c, c + a)))117break;118}119return (c);120}121122static inline int64_t123atomic64_xchg(atomic64_t *v, int64_t i)124{125#if !(defined(__powerpc__) && !defined(__powerpc64__))126return (atomic_swap_64(&v->counter, i));127#else128int64_t ret = atomic64_read(v);129130while (!atomic_fcmpset_64(&v->counter, &ret, i))131;132return (ret);133#endif134}135136static inline int64_t137atomic64_cmpxchg(atomic64_t *v, int64_t old, int64_t new)138{139int64_t ret = old;140141for (;;) {142if (atomic_fcmpset_64(&v->counter, &ret, new))143break;144if (ret != old)145break;146}147return (ret);148}149150#endif /* _LINUXKPI_ASM_ATOMIC64_H_ */151152153