mesytec-mnode/external/taskflow-3.8.0/3rd-party/ff/sysdep.h
2025-01-04 01:25:05 +01:00

250 lines
6.6 KiB
C

/*
* The following has been taken from Cilk (version 5.4.6) file cilk-sysdep.h.
* The Cilk Project web site is http://supertech.csail.mit.edu/cilk/
*
*/
/*
* Copyright (c) 2000 Massachusetts Institute of Technology
* Copyright (c) 2000 Matteo Frigo
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
* USA.
*
*/
/* Don't just include config.h, since that is not installed. */
/* Instead, we must actually #define the useful things here. */
/* #include "../config.h" */
/* Compiler-specific dependencies here, followed by the runtime system dependencies.
* The compiler-specific dependencies were originally written by Eitan Ben Amos.
* Modified by Bradley.
*/
#ifndef FF_SPIN_SYSDEP_H
#define FF_SPIN_SYSDEP_H
#if defined(__APPLE__)
#include <AvailabilityMacros.h>
#endif
/***********************************************************\
* Various types of memory barriers and atomic operations
\***********************************************************/
/* RISCV
Marco Aldinucci
10/04/2022 02:08
RISC-V-Linux/linux/arch/riscv/include/asm/barrier.h
*/
#if defined(__riscv)
#pragma message "RISCV detected - experimental"
#define nop() __asm__ __volatile__ ("nop")
#define RISCV_FENCE(p, s) \
__asm__ __volatile__ ("fence " #p "," #s : : : "memory")
/* These barriers need to enforce ordering on both devices or memory. */
#define mb() RISCV_FENCE(iorw,iorw)
#define rmb() RISCV_FENCE(ir,ir)
#define wmb() RISCV_FENCE(ow,ow)
/* These barriers do not need to enforce ordering on devices, just memory. */
#define __smp_mb() RISCV_FENCE(rw,rw)
#define __smp_rmb() RISCV_FENCE(r,r)
#define __smp_wmb() RISCV_FENCE(w,w)
#define WMB() __smp_wmb()
#define PAUSE()
#endif
/*------------------------
POWERPC
------------------------*/
#if defined(__powerpc__) || defined(__ppc__)
/* This version contributed by Matteo Frigo Wed Jul 13 2005. He wrote:
* lwsync is faster than eieio and has the desired store-barrier
* behavior. The isync in the lock is necessary because the processor is
* allowed to speculate on loads following the branch, which makes the
* program without isync incorrect (in theory at least---I have never
* observed such a speculation).
*/
#define WMB() __asm__ __volatile__ ("lwsync" : : : "memory")
#define PAUSE()
/* atomic swap operation */
static __inline__ int xchg(volatile int *ptr, int x)
{
int result;
__asm__ __volatile__ (
"0: lwarx %0,0,%1\n stwcx. %2,0,%1\n bne- 0b\n isync\n" :
"=&r"(result) :
"r"(ptr), "r"(x) :
"cr0");
return result;
}
#endif
/*------------------------
IA64
------------------------*/
#ifdef __ia64__
#define WMB() __asm__ __volatile__ ("mf" : : : "memory")
#define PAUSE()
/* atomic swap operation */
static inline int xchg(volatile int *ptr, int x)
{
int result;
__asm__ __volatile ("xchg4 %0=%1,%2" : "=r" (result)
: "m" (*(int *) ptr), "r" (x) : "memory");
return result;
}
#endif
/*------------------------
I386
------------------------*/
#ifdef __i386__
#define WMB() __asm__ __volatile__ ("": : :"memory")
#define PAUSE() __asm__ __volatile__ ("rep; nop" : : : "memory")
/* atomic swap operation
Note: no "lock" prefix even on SMP: xchg always implies lock anyway
*/
static inline int xchg(volatile int *ptr, int x)
{
__asm__("xchgl %0,%1" :"=r" (x) :"m" (*(ptr)), "0" (x) :"memory");
return x;
}
#endif /* __i386__ */
/*------------------------
ARM (Mauro Mulatero)
------------------------*/
#if defined(__arm__) || defined(__aarch64__)
#define isb() __asm__ __volatile__ ("isb" : : : "memory")
#define dsb() __asm__ __volatile__ ("dsb" : : : "memory")
#define dmb() __asm__ __volatile__ ("dmb" : : : "memory")
#define smp_mb() dmb()
#define smp_rmb() dmb()
#define smp_wmb() dmb()
#define WMB() __asm__ __volatile__ ("dmb st": : : "memory")
#define PAUSE()
#define xchg(ptr,x) \
((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
{
unsigned long ret;
// MA: updated 12/08/22 unsigned int ==> unsignet long
unsigned long tmp;
smp_mb();
// MA: updated 12/08/22 teq %1, #0 ==> teq %w1, #0
switch (size) {
case 1:
asm volatile("@ __xchg1\n"
"1: ldrexb %0, [%3]\n"
" strexb %1, %2, [%3]\n"
" teq %w1, #0\n"
" bne 1b"
: "=&r" (ret), "=&r" (tmp)
: "r" (x), "r" (ptr)
: "memory", "cc");
break;
case 4:
asm volatile("@ __xchg4\n"
"1: ldrex %0, [%3]\n"
" strex %1, %2, [%3]\n"
" teq %1, #0\n"
" bne 1b"
: "=&r" (ret), "=&r" (tmp)
: "r" (x), "r" (ptr)
: "memory", "cc");
break;
default:
break;
}
smp_mb();
return ret;
}
#endif /* __arm__ */
/*------------------------
amd_64
------------------------*/
#ifdef __x86_64
#define WMB() __asm__ __volatile__ ("": : :"memory")
#define PAUSE() __asm__ __volatile__ ("rep; nop" : : : "memory")
/* atomic swap operation */
static inline int xchg(volatile int *ptr, int x)
{
__asm__("xchgl %0,%1" :"=r" (x) :"m" (*(ptr)), "0" (x) :"memory");
return x;
}
#endif /* __x86_64 */
/*------------------------
(Marco Aldinucci)
------------------------*/
static inline void *getAlignedMemory(size_t align, size_t size) {
void *ptr;
#if (defined(_WIN32)) // || defined(__INTEL_COMPILER)) && defined(_WIN32)
if (posix_memalign(&ptr,align,size)!=0) // defined in platform.h
return NULL;
// Fallback solution in case of strange segfaults on memory allocator
//ptr = ::malloc(size);
#else // linux or MacOS >= 10.6
if (posix_memalign(&ptr,align,size)!=0)
return NULL;
#endif
/* ptr = (void *)memalign(align, size);
if (p == NULL) return NULL;
*/
return ptr;
}
static inline void freeAlignedMemory(void* ptr) {
#if defined(_WIN32)
if (ptr) posix_memalign_free(ptr); // defined in platform.h
// Fallback solution in case of strange segfaults
//::free(ptr);
#else
if (ptr) ::free(ptr);
#endif
}
#endif /* FF_SPIN_SYSDEP_H */