mesytec-mnode/external/taskflow-3.8.0/3rd-party/ff/mpmc/asm/atomic.h

247 lines
5.1 KiB
C
Raw Normal View History

2025-01-04 01:25:05 +01:00
/* Massimo:
* This is a slightly modified version of the linux kernel file
* /<source-dir>/include/asm-generic/atomic.h
*
*/
#ifndef FF_ASM_GENERIC_ATOMIC_H
#define FF_ASM_GENERIC_ATOMIC_H
/*
* Copyright (C) 2005 Silicon Graphics, Inc.
* Christoph Lameter <clameter@sgi.com>
*
* Allows to provide arch independent atomic definitions without the need to
* edit all arch specific atomic.h files.
*/
//#include <asm/types.h>
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
#if defined(__linux__) || defined(__FreeBSD__)
#ifdef __i386__
#include "atomic-i386.h"
// Mauro Mulatero: ARM
#elif __arm__
#include "atomic-arm.h"
#define BITS_PER_LONG 32
#elif __aarch64__
#include "atomic-arm.h"
#define BITS_PER_LONG 64
///
#elif __x86_64__
#include "atomic-x86_64.h"
#if !defined(BITS_PER_LONG)
#define BITS_PER_LONG 64
#endif
#elif __ia64__
#error "IA64 not yet supported"
#endif
#elif __APPLE__
#ifdef __i386__
#include "atomic-i386.h"
#elif __x86_64__
#include "atomic-x86_64.h"
#if !defined(BITS_PER_LONG)
#define BITS_PER_LONG 64
#endif
#elif __POWERPC__
#include "atomic-ppc.h"
#endif
#endif
/*
* Suppport for atomic_long_t
*
* Casts for parameters are avoided for existing atomic functions in order to
* avoid issues with cast-as-lval under gcc 4.x and other limitations that the
* macros of a platform may have.
*/
#if (BITS_PER_LONG == 64)
typedef atomic64_t atomic_long_t;
#define ATOMIC_LONG_INIT(i) ATOMIC64_INIT(i)
static inline unsigned long atomic_long_read(atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
return atomic64_read(v);
}
static inline void atomic_long_set(atomic_long_t *l, long i)
{
atomic64_t *v = (atomic64_t *)l;
atomic64_set(v, i);
}
static inline void atomic_long_inc(atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
atomic64_inc(v);
}
static inline unsigned long atomic_long_inc_return(atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
return atomic64_inc_return(v);
}
static inline void atomic_long_dec(atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
atomic64_dec(v);
}
static inline unsigned long atomic_long_dec_return(atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
return atomic64_dec_return(v);
}
static inline void atomic_long_add(long i, atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
atomic64_add(i, v);
}
static inline void atomic_long_sub(long i, atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
atomic64_sub(i, v);
}
static inline unsigned long atomic_long_add_unless(atomic_long_t *l, long a, long u)
{
atomic64_t *v = (atomic64_t *)l;
return atomic64_add_unless(v, a, u);
}
#define atomic_long_cmpxchg(l, old, new) \
(atomic64_cmpxchg((atomic64_t *)(l), (old), (new)))
#else
typedef atomic_t atomic_long_t;
#define ATOMIC_LONG_INIT(i) ATOMIC_INIT(i)
static inline unsigned long atomic_long_read(atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
return atomic_read(v);
}
static inline void atomic_long_set(atomic_long_t *l, long i)
{
atomic_t *v = (atomic_t *)l;
atomic_set(v, i);
}
static inline void atomic_long_inc(atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
atomic_inc(v);
}
static inline unsigned long atomic_long_inc_return(atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
return atomic_inc_return(v);
}
static inline void atomic_long_dec(atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
atomic_dec(v);
}
static inline unsigned long atomic_long_dec_return(atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
return atomic_dec_return(v);
}
static inline void atomic_long_add(long i, atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
atomic_add(i, v);
}
static inline void atomic_long_sub(long i, atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
atomic_sub(i, v);
}
static inline unsigned long atomic_long_add_unless(atomic_long_t *l, long a, long u)
{
atomic_t *v = (atomic_t *)l;
return atomic_add_unless(v, a, u);
}
#define atomic_long_cmpxchg(l, old, new) \
(atomic_cmpxchg((atomic_t *)(l), (old), (new)))
#endif
#elif defined(_WIN32)
// TODO: Atomic operations to be redefined on top of C++11 atomic ops
typedef __declspec(align(4 /* 32 bit */)) struct { volatile long counter; } atomic_t;
typedef atomic_t atomic_long_t;
#define atomic_set(v,i) (((v)->counter) = (i))
#define atomic_read(v) ((v)->counter)
#define atomic_long_set atomic_set
#define atomic_long_read atomic_read
// This include is useless actually - currently kept for compability
//#include <ff/platforms/platform_msvc_windows.h>
#define BITS_PER_LONG 32 // Both win32 and win64 have long=32 (LLP64 model)
#pragma intrinsic (_InterlockedIncrement)
static inline void atomic_long_inc(atomic_long_t *v) {
_InterlockedIncrement(&v->counter);
}
static inline long atomic_long_inc_return(atomic_long_t *v) {
return _InterlockedIncrement(&v->counter);
//return _InterlockedExchangeAdd((long volatile*)l, 1) + 1;
}
#pragma intrinsic (_InterlockedDecrement)
static inline void atomic_long_dec(atomic_long_t *v) {
_InterlockedDecrement(&v->counter);
}
#endif
#endif /* FF_ASM_GENERIC_ATOMIC_H */