94a0d7bb6f3c533298041ffceed0ab935edbe190
[linux-2.6-microblaze.git] / tools / lib / bpf / libbpf_util.h
1 /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
2 /* Copyright (c) 2019 Facebook */
3
4 #ifndef __LIBBPF_LIBBPF_UTIL_H
5 #define __LIBBPF_LIBBPF_UTIL_H
6
7 #include <stdbool.h>
8 #include <linux/compiler.h>
9
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13
14 /* Use these barrier functions instead of smp_[rw]mb() when they are
15  * used in a libbpf header file. That way they can be built into the
16  * application that uses libbpf.
17  */
18 #if defined(__i386__) || defined(__x86_64__)
19 # define libbpf_smp_store_release(p, v)                                 \
20         do {                                                            \
21                 asm volatile("" : : : "memory");                        \
22                 WRITE_ONCE(*p, v);                                      \
23         } while (0)
24 # define libbpf_smp_load_acquire(p)                                     \
25         ({                                                              \
26                 typeof(*p) ___p1 = READ_ONCE(*p);                       \
27                 asm volatile("" : : : "memory");                        \
28                 ___p1;                                                  \
29         })
30 #elif defined(__aarch64__)
31 # define libbpf_smp_store_release(p, v)                                 \
32                 asm volatile ("stlr %w1, %0" : "=Q" (*p) : "r" (v) : "memory")
33 # define libbpf_smp_load_acquire(p)                                     \
34         ({                                                              \
35                 typeof(*p) ___p1;                                       \
36                 asm volatile ("ldar %w0, %1"                            \
37                               : "=r" (___p1) : "Q" (*p) : "memory");    \
38                 __p1;                                                   \
39         })
40 #elif defined(__riscv)
41 # define libbpf_smp_store_release(p, v)                                 \
42         do {                                                            \
43                 asm volatile ("fence rw,w" : : : "memory");             \
44                 WRITE_ONCE(*p, v);                                      \
45         } while (0)
46 # define libbpf_smp_load_acquire(p)                                     \
47         ({                                                              \
48                 typeof(*p) ___p1 = READ_ONCE(*p);                       \
49                 asm volatile ("fence r,rw" : : : "memory");             \
50                 ___p1;                                                  \
51         })
52 #endif
53
54 #ifndef libbpf_smp_store_release
55 #define libbpf_smp_store_release(p, v)                                  \
56         do {                                                            \
57                 __sync_synchronize();                                   \
58                 WRITE_ONCE(*p, v);                                      \
59         } while (0)
60 #endif
61
62 #ifndef libbpf_smp_load_acquire
63 #define libbpf_smp_load_acquire(p)                                      \
64         ({                                                              \
65                 typeof(*p) ___p1 = READ_ONCE(*p);                       \
66                 __sync_synchronize();                                   \
67                 ___p1;                                                  \
68         })
69 #endif
70
71 #ifdef __cplusplus
72 } /* extern "C" */
73 #endif
74
75 #endif