/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ /* Copyright (c) 2019 Facebook */ #ifndef __LIBBPF_LIBBPF_UTIL_H #define __LIBBPF_LIBBPF_UTIL_H #include #ifdef __cplusplus extern "C" { #endif /* Load-Acquire Store-Release barriers used by the XDP socket * library. The following macros should *NOT* be considered part of * the xsk.h API, and is subject to change anytime. * * LIBRARY INTERNAL */ #define __XSK_READ_ONCE(x) (*(volatile typeof(x) *)&x) #define __XSK_WRITE_ONCE(x, v) (*(volatile typeof(x) *)&x) = (v) #if defined(__i386__) || defined(__x86_64__) # define libbpf_smp_store_release(p, v) \ do { \ asm volatile("" : : : "memory"); \ __XSK_WRITE_ONCE(*p, v); \ } while (0) # define libbpf_smp_load_acquire(p) \ ({ \ typeof(*p) ___p1 = __XSK_READ_ONCE(*p); \ asm volatile("" : : : "memory"); \ ___p1; \ }) #elif defined(__aarch64__) # define libbpf_smp_store_release(p, v) \ asm volatile ("stlr %w1, %0" : "=Q" (*p) : "r" (v) : "memory") # define libbpf_smp_load_acquire(p) \ ({ \ typeof(*p) ___p1; \ asm volatile ("ldar %w0, %1" \ : "=r" (___p1) : "Q" (*p) : "memory"); \ ___p1; \ }) #elif defined(__riscv) # define libbpf_smp_store_release(p, v) \ do { \ asm volatile ("fence rw,w" : : : "memory"); \ __XSK_WRITE_ONCE(*p, v); \ } while (0) # define libbpf_smp_load_acquire(p) \ ({ \ typeof(*p) ___p1 = __XSK_READ_ONCE(*p); \ asm volatile ("fence r,rw" : : : "memory"); \ ___p1; \ }) #endif #ifndef libbpf_smp_store_release #define libbpf_smp_store_release(p, v) \ do { \ __sync_synchronize(); \ __XSK_WRITE_ONCE(*p, v); \ } while (0) #endif #ifndef libbpf_smp_load_acquire #define libbpf_smp_load_acquire(p) \ ({ \ typeof(*p) ___p1 = __XSK_READ_ONCE(*p); \ __sync_synchronize(); \ ___p1; \ }) #endif /* LIBRARY INTERNAL -- END */ #ifdef __cplusplus } /* extern "C" */ #endif #endif