// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */
#ifndef BPF_ATOMIC_H
#define BPF_ATOMIC_H
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include "bpf_experimental.h"
extern bool CONFIG_X86_64 __kconfig __weak;
/*
* _ _ unqual_typeof ( x ) - Declare an unqualified scalar type , leaving
* non - scalar types unchanged ,
*
* Prefer C11 _ Generic for better compile - times and simpler code . Note : ' char '
* is not type - compatible with ' signed char ' , and we define a separate case .
*
* This is copied verbatim from kernel ' s include / linux / compiler_types . h , but
* with default expression ( for pointers ) changed from ( x ) to ( typeof ( x ) 0 ) .
*
* This is because LLVM has a bug where for lvalue ( x ) , it does not get rid of
* an extra address_space qualifier , but does in case of rvalue ( typeof ( x ) 0 ) .
* Hence , for pointers , we need to create an rvalue expression to get the
* desired type . See https : //github.com/llvm/llvm-project/issues/53400.
*/
#define __scalar_type_to_expr_cases(type) \
unsigned type : (unsigned type)0 , signed type : (signed type)0
#define __unqual_typeof(x) \
typeof(_Generic((x), \
char : (char )0 , \
__scalar_type_to_expr_cases(char ), \
__scalar_type_to_expr_cases(short ), \
__scalar_type_to_expr_cases(int ), \
__scalar_type_to_expr_cases(long ), \
__scalar_type_to_expr_cases(long long ), \
default : (typeof(x))0 ))
/* No-op for BPF */
#define cpu_relax() ({})
#define READ_ONCE(x) (*(volatile typeof(x) *)&(x))
#define WRITE_ONCE(x, val) ((*(volatile typeof(x) *)&(x)) = (val))
#define cmpxchg(p, old, new ) __sync_val_compare_and_swap((p), old, new )
#define try_cmpxchg(p, pold, new ) \
({ \
__unqual_typeof(*(pold)) __o = *(pold); \
__unqual_typeof(*(p)) __r = cmpxchg(p, __o, new ); \
if (__r != __o) \
*(pold) = __r; \
__r == __o; \
})
#define try_cmpxchg_relaxed(p, pold, new ) try_cmpxchg(p, pold, new )
#define try_cmpxchg_acquire(p, pold, new ) try_cmpxchg(p, pold, new )
#define smp_mb() \
({ \
volatile unsigned long __val; \
__sync_fetch_and_add(&__val, 0 ); \
})
#define smp_rmb() \
({ \
if (!CONFIG_X86_64) \
smp_mb(); \
else \
barrier(); \
})
#define smp_wmb() \
({ \
if (!CONFIG_X86_64) \
smp_mb(); \
else \
barrier(); \
})
/* Control dependency provides LOAD->STORE, provide LOAD->LOAD */
#define smp_acquire__after_ctrl_dep() ({ smp_rmb(); })
#define smp_load_acquire(p) \
({ \
__unqual_typeof(*(p)) __v = READ_ONCE(*(p)); \
if (!CONFIG_X86_64) \
smp_mb(); \
barrier(); \
__v; \
})
#define smp_store_release(p, val) \
({ \
if (!CONFIG_X86_64) \
smp_mb(); \
barrier(); \
WRITE_ONCE(*(p), val); \
})
#define smp_cond_load_relaxed_label(p, cond_expr, label) \
({ \
typeof(p) __ptr = (p); \
__unqual_typeof(*(p)) VAL; \
for (;;) { \
VAL = (__unqual_typeof(*(p)))READ_ONCE(*__ptr); \
if (cond_expr) \
break ; \
cond_break_label(label); \
cpu_relax(); \
} \
(typeof(*(p)))VAL; \
})
#define smp_cond_load_acquire_label(p, cond_expr, label) \
({ \
__unqual_typeof(*p) __val = \
smp_cond_load_relaxed_label(p, cond_expr, label); \
smp_acquire__after_ctrl_dep(); \
(typeof(*(p)))__val; \
})
#define atomic_read(p) READ_ONCE((p)->counter)
#define atomic_cond_read_relaxed_label(p, cond_expr, label) \
smp_cond_load_relaxed_label(&(p)->counter, cond_expr, label)
#define atomic_cond_read_acquire_label(p, cond_expr, label) \
smp_cond_load_acquire_label(&(p)->counter, cond_expr, label)
#define atomic_try_cmpxchg_relaxed(p, pold, new ) \
try_cmpxchg_relaxed(&(p)->counter, pold, new )
#define atomic_try_cmpxchg_acquire(p, pold, new ) \
try_cmpxchg_acquire(&(p)->counter, pold, new )
#endif /* BPF_ATOMIC_H */
Messung V0.5 in Prozent C=93 H=86 G=89
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-10-12)
¤
*© Formatika GbR, Deutschland