zig/lib/libc/include/aarch64-openbsd-none/arm64/atomic.h
2025-12-01 18:33:08 +01:00

64 lines
No EOL
1.4 KiB
C
Vendored

/* $OpenBSD: atomic.h,v 1.4 2022/08/29 02:01:18 jsg Exp $ */
/* Public Domain */
#ifndef _MACHINE_ATOMIC_H_
#define _MACHINE_ATOMIC_H_
#define __membar(_f) do { __asm volatile(_f ::: "memory"); } while (0)
#define membar_enter() __membar("dmb sy")
#define membar_exit() __membar("dmb sy")
#define membar_producer() __membar("dmb st")
#define membar_consumer() __membar("dmb ld")
#define membar_sync() __membar("dmb sy")
#if defined(_KERNEL)
/* virtio needs MP membars even on SP kernels */
#define virtio_membar_producer() __membar("dmb st")
#define virtio_membar_consumer() __membar("dmb ld")
#define virtio_membar_sync() __membar("dmb sy")
/*
* Set bits
* *p = *p | v
*/
static inline void
atomic_setbits_int(volatile unsigned int *p, unsigned int v)
{
unsigned int modified, tmp;
__asm volatile (
"1: ldxr %w0, [%x3] \n\t"
" orr %w0, %w0, %w2 \n\t"
" stxr %w1, %w0, [%x3] \n\t"
" cbnz %w1, 1b \n\t"
: "=&r" (tmp), "=&r" (modified)
: "r" (v), "r" (p)
: "memory", "cc"
);
}
/*
* Clear bits
* *p = *p & (~v)
*/
static inline void
atomic_clearbits_int(volatile unsigned int *p, unsigned int v)
{
unsigned int modified, tmp;
__asm volatile (
"1: ldxr %w0, [%x3] \n\t"
" bic %w0, %w0, %w2 \n\t"
" stxr %w1, %w0, [%x3] \n\t"
" cbnz %w1, 1b \n\t"
: "=&r" (tmp), "=&r" (modified)
: "r" (v), "r" (p)
: "memory", "cc"
);
}
#endif /* defined(_KERNEL) */
#endif /* _MACHINE_ATOMIC_H_ */