Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
325 changes: 289 additions & 36 deletions include/bfdev/asm-generic/atomic.h

Large diffs are not rendered by default.

39 changes: 39 additions & 0 deletions include/bfdev/asm-generic/barrier.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* SPDX-License-Identifier: LGPL-3.0-or-later */
/*
* Copyright(c) 2023 John Sanpe <sanpeqf@gmail.com>
*/

#ifndef _BFDEV_ASM_GENERIC_BARRIER_H_
#define _BFDEV_ASM_GENERIC_BARRIER_H_

#include <bfdev/config.h>

BFDEV_BEGIN_DECLS

#ifndef bfdev_arch_mb
# define bfdev_arch_mb() __sync_synchronize()
#endif

#ifndef bfdev_arch_rmb
# define bfdev_arch_rmb() bfdev_arch_mb()
#endif

#ifndef bfdev_arch_wmb
# define bfdev_arch_wmb() bfdev_arch_mb()
#endif

#ifndef bfdev_arch_smp_mb
# define bfdev_arch_smp_mb() bfdev_arch_mb()
#endif

#ifndef bfdev_arch_smp_rmb
# define bfdev_arch_smp_rmb() bfdev_arch_rmb()
#endif

#ifndef bfdev_arch_smp_wmb
# define bfdev_arch_smp_wmb() bfdev_arch_wmb()
#endif

BFDEV_END_DECLS

#endif /* _BFDEV_ASM_GENERIC_BARRIER_H_ */
107 changes: 76 additions & 31 deletions include/bfdev/asm-generic/cmpxchg.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,47 +13,92 @@

BFDEV_BEGIN_DECLS

#ifndef bfdev_arch_cmpxchg
# define bfdev_arch_cmpxchg bfdev_arch_cmpxchg
static __bfdev_always_inline bfdev_atomic_t
bfdev_arch_cmpxchg(bfdev_atomic_t *atomic, bfdev_atomic_t old,
bfdev_atomic_t value)
{
return __sync_val_compare_and_swap(atomic, old, value);
#define BFDEV_GENERIC_XCHG(name, order) \
static __bfdev_always_inline bfdev_atomic_t \
bfdev_arch_##name(bfdev_atomic_t *atomic, bfdev_atomic_t value) \
{ \
bfdev_atomic_t result; \
__atomic_exchange(atomic, &value, &result, order); \
return result; \
}

#define BFDEV_GENERIC_CMPXCHG(name, weak, okay, fail) \
static __bfdev_always_inline bfdev_atomic_t \
bfdev_arch_##name(bfdev_atomic_t *atomic, bfdev_atomic_t old, \
bfdev_atomic_t value) \
{ \
__atomic_compare_exchange(atomic, &old, &value, \
weak, okay, fail); \
return old; \
}

#define BFDEV_GENERIC_TRY_CMPXCHG(name, weak, okay, fail) \
static __bfdev_always_inline bfdev_bool \
bfdev_arch_##name(bfdev_atomic_t *atomic, bfdev_atomic_t *old, \
bfdev_atomic_t value) \
{ \
return __atomic_compare_exchange(atomic, old, &value, \
weak, okay, fail); \
}
#endif

#ifndef bfdev_arch_xchg
# define bfdev_arch_xchg bfdev_arch_xchg
static __bfdev_always_inline bfdev_atomic_t
bfdev_arch_xchg(bfdev_atomic_t *atomic, bfdev_atomic_t value)
{
bfdev_atomic_t prev, result;
BFDEV_GENERIC_XCHG(xchg, __ATOMIC_SEQ_CST)
#endif

do {
prev = *atomic;
result = bfdev_arch_cmpxchg(atomic, prev, value);
} while (bfdev_unlikely(result != prev));
#ifndef bfdev_arch_xchg_acquire
# define bfdev_arch_xchg_acquire bfdev_arch_xchg_acquire
BFDEV_GENERIC_XCHG(xchg_acquire, __ATOMIC_ACQUIRE)
#endif

return result;
}
#ifndef bfdev_arch_xchg_release
# define bfdev_arch_xchg_release bfdev_arch_xchg_release
BFDEV_GENERIC_XCHG(xchg_release, __ATOMIC_RELEASE)
#endif

#ifndef bfdev_arch_xchg_relaxed
# define bfdev_arch_xchg_relaxed bfdev_arch_xchg_relaxed
BFDEV_GENERIC_XCHG(xchg_relaxed, __ATOMIC_RELAXED)
#endif

#ifndef bfdev_arch_cmpxchg
# define bfdev_arch_cmpxchg bfdev_arch_cmpxchg
BFDEV_GENERIC_CMPXCHG(cmpxchg, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#endif

#ifndef bfdev_arch_cmpxchg_acquire
# define bfdev_arch_cmpxchg_acquire bfdev_arch_cmpxchg_acquire
BFDEV_GENERIC_CMPXCHG(cmpxchg_acquire, 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE)
#endif

#ifndef bfdev_arch_cmpxchg_release
# define bfdev_arch_cmpxchg_release bfdev_arch_cmpxchg_release
BFDEV_GENERIC_CMPXCHG(cmpxchg_release, 0, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)
#endif

#ifndef bfdev_arch_cmpxchg_relaxed
# define bfdev_arch_cmpxchg_relaxed bfdev_arch_cmpxchg_relaxed
BFDEV_GENERIC_CMPXCHG(cmpxchg_relaxed, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED)
#endif

#ifndef bfdev_arch_try_cmpxchg
# define bfdev_arch_try_cmpxchg bfdev_arch_try_cmpxchg
static __bfdev_always_inline bfdev_bool
bfdev_arch_try_cmpxchg(bfdev_atomic_t *atomic, bfdev_atomic_t *old,
bfdev_atomic_t value)
{
bfdev_atomic_t result, prev;

prev = *old;
result = bfdev_arch_cmpxchg(atomic, prev, value);
if (bfdev_unlikely(result != prev))
*old = result;

return bfdev_likely(result == prev);
}
BFDEV_GENERIC_TRY_CMPXCHG(try_cmpxchg, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#endif

#ifndef bfdev_arch_try_cmpxchg_acquire
# define bfdev_arch_try_cmpxchg_acquire bfdev_arch_try_cmpxchg_acquire
BFDEV_GENERIC_TRY_CMPXCHG(try_cmpxchg_acquire, 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE)
#endif

#ifndef bfdev_arch_try_cmpxchg_release
# define bfdev_arch_try_cmpxchg_release bfdev_arch_try_cmpxchg_release
BFDEV_GENERIC_TRY_CMPXCHG(try_cmpxchg_release, 0, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)
#endif

#ifndef bfdev_arch_try_cmpxchg_relaxed
# define bfdev_arch_try_cmpxchg_relaxed bfdev_arch_try_cmpxchg_relaxed
BFDEV_GENERIC_TRY_CMPXCHG(try_cmpxchg_relaxed, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED)
#endif

BFDEV_END_DECLS
Expand Down
Loading
Loading