mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-03-27 07:58:16 -04:00
The body code didn't use atomic loads, so it had undefined behavior if the body was concurrently modified. Use atomic loads to fix this. Since the memory order is __ATOMIC_RELAXED this has no runtime overhead. Also add barriers around a strncpy call and cast to volatile before checking for a NUL terminator, though NUL-terminated strings in shared memory are unuseable. There are some places where bytewise atomic memcpy(), which doesn't currently exist, is needed. Instead, try to fake it by using two barriers around memcpy().
37 lines
1.2 KiB
C
37 lines
1.2 KiB
C
/* Atomic operations */
|
|
/* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans */
|
|
/* SPDX-License-Identifier: MIT */
|
|
|
|
#ifndef SPA_ATOMIC_H
|
|
#define SPA_ATOMIC_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define SPA_ATOMIC_CAS(v,ov,nv) \
|
|
({ \
|
|
__typeof__(v) __ov = (ov); \
|
|
__atomic_compare_exchange_n(&(v), &__ov, (nv), \
|
|
0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \
|
|
})
|
|
|
|
#define SPA_ATOMIC_DEC(s) __atomic_sub_fetch(&(s), 1, __ATOMIC_SEQ_CST)
|
|
#define SPA_ATOMIC_INC(s) __atomic_add_fetch(&(s), 1, __ATOMIC_SEQ_CST)
|
|
#define SPA_ATOMIC_LOAD(s) __atomic_load_n(&(s), __ATOMIC_SEQ_CST)
|
|
#define SPA_LOAD_ONCE(s) __atomic_load_n((s), __ATOMIC_RELAXED)
|
|
#define SPA_STORE_ONCE(s) __atomic_store_n((s), __ATOMIC_RELAXED)
|
|
#define SPA_ATOMIC_STORE(s,v) __atomic_store_n(&(s), (v), __ATOMIC_SEQ_CST)
|
|
#define SPA_ATOMIC_XCHG(s,v) __atomic_exchange_n(&(s), (v), __ATOMIC_SEQ_CST)
|
|
|
|
#define SPA_SEQ_WRITE(s) SPA_ATOMIC_INC(s)
|
|
#define SPA_SEQ_WRITE_SUCCESS(s1,s2) ((s1) + 1 == (s2) && ((s2) & 1) == 0)
|
|
|
|
#define SPA_SEQ_READ(s) SPA_ATOMIC_LOAD(s)
|
|
#define SPA_SEQ_READ_SUCCESS(s1,s2) ((s1) == (s2) && ((s2) & 1) == 0)
|
|
|
|
#ifdef __cplusplus
|
|
} /* extern "C" */
|
|
#endif
|
|
|
|
#endif /* SPA_ATOMIC_H */
|