* Clean up some minor build system ick in the atomic operations
* Make sure the update.sh scripts all use OMPI_WANT_SMP_LOCKS * Add sparc (32bit) assembly - Memory barriers - spinlocks - emulate add/sub using the spinlock table with hashed lookups, as suggested by the linux kernel folk (better than the other option, requiring the counters only use 24 bits) This commit was SVN r4429.
Этот коммит содержится в:
родитель
2706190b39
Коммит
4265304230
@ -1492,6 +1492,7 @@ AC_CONFIG_FILES([
|
||||
src/include/sys/ia32/Makefile
|
||||
src/include/sys/ia64/Makefile
|
||||
src/include/sys/powerpc/Makefile
|
||||
src/include/sys/sparc/Makefile
|
||||
src/include/sys/sparc64/Makefile
|
||||
src/include/sys/win32/Makefile
|
||||
|
||||
|
@ -47,6 +47,7 @@ endif
|
||||
|
||||
libasm_la_DEPENDENCIES = generated/@OMPI_ASM_FILE@
|
||||
noinst_LTLIBRARIES = libasm.la
|
||||
dist_libasm_la_SOURCES = asm.c
|
||||
|
||||
EXTRA_DIST = \
|
||||
asm-data.txt \
|
||||
|
81
src/asm/asm.c
Обычный файл
81
src/asm/asm.c
Обычный файл
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "ompi_config.h"
|
||||
|
||||
#include "include/sys/atomic.h"
|
||||
#include "include/sys/architecture.h"
|
||||
|
||||
#if OMPI_ASSEMBLY_ARCH == OMPI_SPARC32
|
||||
|
||||
#if OMPI_WANT_SMP_LOCKS
|
||||
|
||||
#define LOCKS_TABLE_SIZE 8
|
||||
/* make sure to get into reasonably useful bits (so shift at least 5) */
|
||||
#define FIND_LOCK(addr) (&(locks_table[(((unsigned long) addr) >> 8) & \
|
||||
(LOCKS_TABLE_SIZE - 1)]))
|
||||
|
||||
/* have to fix if you change LOCKS_TABLE_SIZE */
|
||||
static ompi_lock_t locks_table[LOCKS_TABLE_SIZE] = {
|
||||
OMPI_ATOMIC_UNLOCKED,
|
||||
OMPI_ATOMIC_UNLOCKED,
|
||||
OMPI_ATOMIC_UNLOCKED,
|
||||
OMPI_ATOMIC_UNLOCKED,
|
||||
OMPI_ATOMIC_UNLOCKED,
|
||||
OMPI_ATOMIC_UNLOCKED,
|
||||
OMPI_ATOMIC_UNLOCKED,
|
||||
OMPI_ATOMIC_UNLOCKED
|
||||
};
|
||||
|
||||
# else /* OMPI_WANT_SMP_LOCKS */
|
||||
|
||||
#define LOCKS_TABLE_SIZE 1
|
||||
#define FIND_LOCK(addr) (&(locks_table[0]))
|
||||
|
||||
static ompi_lock_t locks_table[1] = { OMPI_ATOMIC_UNLOCKED };
|
||||
|
||||
#endif /* OMPI_WANT_SMP_LOCKS */
|
||||
|
||||
|
||||
int32_t
|
||||
ompi_atomic_sub_32(volatile int32_t *addr, int delta)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ompi_atomic_lock(FIND_LOCK(addr));
|
||||
|
||||
ret = (*addr += delta);
|
||||
|
||||
ompi_atomic_unlock(FIND_LOCK(addr));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int32_t
|
||||
ompi_atomic_sub_32(volatile int32_t *addr, int delta)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ompi_atomic_lock(FIND_LOCK(addr));
|
||||
|
||||
ret = (*addr -= delta);
|
||||
|
||||
ompi_atomic_unlock(FIND_LOCK(addr));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#endif /* OMPI_ASSEMBLY_ARCH == OMPI_SPARC32 */
|
@ -14,7 +14,7 @@
|
||||
|
||||
include $(top_srcdir)/config/Makefile.options
|
||||
|
||||
SUBDIRS = alpha amd64 ia32 ia64 powerpc sparc64 win32
|
||||
SUBDIRS = alpha amd64 ia32 ia64 powerpc sparc sparc64 win32
|
||||
|
||||
noinst_HEADERS = atomic.h architecture.h atomic_impl.h cache.h
|
||||
|
||||
|
@ -25,6 +25,7 @@ cat > $CFILE<<EOF
|
||||
#define static
|
||||
#define inline
|
||||
#define OMPI_GCC_INLINE_ASSEMBLY 1
|
||||
#define OMPI_WANT_SMP_LOCKS 1
|
||||
#include "atomic.h"
|
||||
EOF
|
||||
|
||||
|
@ -25,6 +25,7 @@ cat > $CFILE<<EOF
|
||||
#define static
|
||||
#define inline
|
||||
#define OMPI_GCC_INLINE_ASSEMBLY 1
|
||||
#define OMPI_WANT_SMP_LOCKS 1
|
||||
#include "atomic.h"
|
||||
EOF
|
||||
|
||||
|
@ -77,7 +77,7 @@ extern "C" {
|
||||
#elif OMPI_ASSEMBLY_ARCH == OMPI_POWERPC64
|
||||
#include "include/sys/powerpc/atomic.h"
|
||||
#elif OMPI_ASSEMBLY_ARCH == OMPI_SPARC32
|
||||
#error "32 bit Sparc support not implemented yet"
|
||||
#include "include/sys/sparc/atomic.h"
|
||||
#elif OMPI_ASSEMBLY_ARCH == OMPI_SPARC64
|
||||
#include "include/sys/sparc64/atomic.h"
|
||||
#endif
|
||||
@ -153,20 +153,28 @@ void ompi_atomic_wmb(void);
|
||||
*********************************************************************/
|
||||
/**
|
||||
* Volatile lock object (with optional padding).
|
||||
*
|
||||
* \note The internals of the lock are included here, but should be
|
||||
* considered private. The implementation currently in use may choose
|
||||
* to use an int or unsigned char as the lock value - the user is not
|
||||
* informed either way.
|
||||
*/
|
||||
struct ompi_lock_t {
|
||||
union {
|
||||
volatile int lock; /**< The lock address (an integer) */
|
||||
volatile unsigned char sparc_lock; /**< The lock address on sparc */
|
||||
char padding[sizeof(int)]; /**< Array for optional padding */
|
||||
} u;
|
||||
};
|
||||
typedef struct ompi_lock_t ompi_lock_t;
|
||||
|
||||
#if !defined(OMPI_HAVE_ATOMIC_SPINLOCKS) && !defined(DOXYGEN)
|
||||
#define OMPI_HAVE_ATOMIC_SPINLOCKS (OMPI_HAVE_ATOMIC_CMPSET_32 || OMPI_HAVE_ATOMIC_CMPSET_64)
|
||||
/* 0 is more like "pending" - we'll fix up at the end after all
|
||||
the static inline functions are declared */
|
||||
#define OMPI_HAVE_ATOMIC_SPINLOCKS 0
|
||||
#endif
|
||||
|
||||
#if defined(DOXYGEN) || OMPI_HAVE_ATOMIC_SPINLOCKS
|
||||
#if defined(DOXYGEN) || OMPI_HAVE_ATOMIC_SPINLOCKS || (OMPI_HAVE_ATOMIC_CMPSET_32 || OMPI_HAVE_ATOMIC_CMPSET_64)
|
||||
|
||||
/**
|
||||
* Enumeration of lock states
|
||||
@ -183,7 +191,10 @@ enum {
|
||||
* @param lock Address of the lock
|
||||
* @param value Initial value to set lock to
|
||||
*/
|
||||
static inline void ompi_atomic_init(ompi_lock_t* lock, int value);
|
||||
#if OMPI_HAVE_ATOMIC_SPINLOCKS == 0
|
||||
static inline
|
||||
#endif
|
||||
void ompi_atomic_init(ompi_lock_t* lock, int value);
|
||||
|
||||
|
||||
/**
|
||||
@ -192,7 +203,10 @@ static inline void ompi_atomic_init(ompi_lock_t* lock, int value);
|
||||
* @param lock Address of the lock.
|
||||
* @return 0 if the lock was acquired, 1 otherwise.
|
||||
*/
|
||||
static inline int ompi_atomic_trylock(ompi_lock_t *lock);
|
||||
#if OMPI_HAVE_ATOMIC_SPINLOCKS == 0
|
||||
static inline
|
||||
#endif
|
||||
int ompi_atomic_trylock(ompi_lock_t *lock);
|
||||
|
||||
|
||||
/**
|
||||
@ -200,7 +214,10 @@ static inline int ompi_atomic_trylock(ompi_lock_t *lock);
|
||||
*
|
||||
* @param lock Address of the lock.
|
||||
*/
|
||||
static inline void ompi_atomic_lock(ompi_lock_t *lock);
|
||||
#if OMPI_HAVE_ATOMIC_SPINLOCKS == 0
|
||||
static inline
|
||||
#endif
|
||||
void ompi_atomic_lock(ompi_lock_t *lock);
|
||||
|
||||
|
||||
/**
|
||||
@ -208,7 +225,16 @@ static inline void ompi_atomic_lock(ompi_lock_t *lock);
|
||||
*
|
||||
* @param lock Address of the lock.
|
||||
*/
|
||||
static inline void ompi_atomic_unlock(ompi_lock_t *lock);
|
||||
#if OMPI_HAVE_ATOMIC_SPINLOCKS == 0
|
||||
static inline
|
||||
#endif
|
||||
void ompi_atomic_unlock(ompi_lock_t *lock);
|
||||
|
||||
|
||||
#if OMPI_HAVE_ATOMIC_SPINLOCKS == 0
|
||||
#define OMPI_HAVE_ATOMIC_SPINLOCKS (OMPI_HAVE_ATOMIC_CMPSET_32 || OMPI_HAVE_ATOMIC_CMPSET_64)
|
||||
#define OMPI_NEED_INLINE_ATOMIC_SPINLOCKS
|
||||
#endif
|
||||
|
||||
#endif /* OMPI_HAVE_ATOMIC_SPINLOCKS */
|
||||
|
||||
|
@ -307,7 +307,8 @@ static inline int ompi_atomic_sub_ptr(volatile void* addr,
|
||||
* Atomic spinlocks
|
||||
*
|
||||
*********************************************************************/
|
||||
#if OMPI_HAVE_ATOMIC_SPINLOCKS
|
||||
#ifdef OMPI_NEED_INLINE_ATOMIC_SPINLOCKS
|
||||
|
||||
/*
|
||||
* Lock initialization function. It set the lock to UNLOCKED.
|
||||
*/
|
||||
|
@ -25,6 +25,7 @@ cat > $CFILE<<EOF
|
||||
#define static
|
||||
#define inline
|
||||
#define OMPI_GCC_INLINE_ASSEMBLY 1
|
||||
#define OMPI_WANT_SMP_LOCKS 1
|
||||
#include "atomic.h"
|
||||
EOF
|
||||
|
||||
|
26
src/include/sys/sparc/Makefile.am
Обычный файл
26
src/include/sys/sparc/Makefile.am
Обычный файл
@ -0,0 +1,26 @@
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University.
|
||||
# All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
||||
# All rights reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
include $(top_srcdir)/config/Makefile.options
|
||||
|
||||
noinst_HEADERS = atomic.h
|
||||
|
||||
# Conditionally install the header files
|
||||
|
||||
if WANT_INSTALL_HEADERS
|
||||
ompidir = $(includedir)/openmpi/include/sys/sparc
|
||||
ompi_HEADERS = $(noinst_HEADERS)
|
||||
else
|
||||
ompidir = $(includedir)
|
||||
endif
|
140
src/include/sys/sparc/atomic.h
Обычный файл
140
src/include/sys/sparc/atomic.h
Обычный файл
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#ifndef OMPI_SYS_ARCH_ATOMIC_H
|
||||
#define OMPI_SYS_ARCH_ATOMIC_H 1
|
||||
|
||||
|
||||
#if OMPI_WANT_SMP_LOCKS
|
||||
#define MB() __asm__ __volatile__ ("" : : : "memory")
|
||||
#else
|
||||
#define MB()
|
||||
#endif
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Define constants for UltraSparc 64
|
||||
*
|
||||
*********************************************************************/
|
||||
#define OMPI_HAVE_MEM_BARRIER 1
|
||||
|
||||
#define OMPI_HAVE_ATOMIC_CMPSET_32 0
|
||||
#define OMPI_HAVE_ATOMIC_CMPSET_64 0
|
||||
|
||||
#define OMPI_HAVE_ATOMIC_MATH_32 1
|
||||
#define OMPI_HAVE_ATOMIC_SUB_32 1
|
||||
#define OMPI_HAVE_ATOMIC_ADD_32 1
|
||||
|
||||
#define OMPI_HAVE_ATOMIC_SPINLOCKS 1
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Memory Barriers
|
||||
*
|
||||
*********************************************************************/
|
||||
#if OMPI_GCC_INLINE_ASSEMBLY
|
||||
|
||||
static inline void ompi_atomic_mb(void)
|
||||
{
|
||||
MB();
|
||||
}
|
||||
|
||||
|
||||
static inline void ompi_atomic_rmb(void)
|
||||
{
|
||||
MB();
|
||||
}
|
||||
|
||||
|
||||
static inline void ompi_atomic_wmb(void)
|
||||
{
|
||||
MB();
|
||||
}
|
||||
|
||||
#endif /* OMPI_GCC_INLINE_ASSEMBLY */
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Atomic spinlocks
|
||||
*
|
||||
*********************************************************************/
|
||||
#if OMPI_GCC_INLINE_ASSEMBLY
|
||||
|
||||
/* for these, the lock is held whenever lock.sparc_lock != 0. We
|
||||
attempt to leave it as OMPI_LOCKED whenever possible */
|
||||
|
||||
|
||||
static inline void ompi_atomic_init(ompi_lock_t* lock, int value)
|
||||
{
|
||||
lock->sparc_lock = (unsigned char) value;
|
||||
}
|
||||
|
||||
|
||||
static inline int ompi_atomic_trylock(ompi_lock_t *lock)
|
||||
{
|
||||
unsigned char result;
|
||||
|
||||
/* try to load the lock byte (atomically making the memory byte
|
||||
contain all 1s). If the byte used to be 0, we now have the
|
||||
lock. Otherwise, someone else has the lock. Either way, the
|
||||
lock is now held. */
|
||||
__asm__ __volatile__ ("\t"
|
||||
"ldstub [%1], %0"
|
||||
: "=r"(result)
|
||||
: "r"(&(lock->sparc_lock))
|
||||
: "memory");
|
||||
return (result == 0);
|
||||
}
|
||||
|
||||
|
||||
static inline void ompi_atomic_lock(ompi_lock_t *lock)
|
||||
{
|
||||
/* From page 264 of The SPARC Architecture Manual, Version 8 */
|
||||
__asm__ __volatile__ (
|
||||
"retry: \n\t"
|
||||
"ldstub [%0], %%l0 \n\t"
|
||||
"tst %%l0 \n\t"
|
||||
"bw out \n\t"
|
||||
"nop \n"
|
||||
"loop: \n\t"
|
||||
"ldb [%0], %%l0 \n\t"
|
||||
"tst %%l0 \n\t"
|
||||
"bne loop \n\t"
|
||||
"nop \n\t"
|
||||
"ba,a retry \n"
|
||||
"out: \n\t"
|
||||
"nop"
|
||||
:
|
||||
: "r"(&(lock->sparc_lock))
|
||||
: "%l0", "memory");
|
||||
}
|
||||
|
||||
|
||||
static inline void ompi_atomic_unlock(ompi_lock_t *lock)
|
||||
{
|
||||
/* 0 out that byte in memory */
|
||||
__asm__ __volatile__ ("\t"
|
||||
"stbar \n\t"
|
||||
"stb %%g0, [%0] \n\t"
|
||||
:
|
||||
: "r"(&(lock->sparc_lock))
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#endif /* OMPI_GCC_INLINE_ASSEMBLY */
|
||||
|
||||
|
||||
#endif /* ! OMPI_SYS_ARCH_ATOMIC_H */
|
32
src/include/sys/sparc/update.sh
Обычный файл
32
src/include/sys/sparc/update.sh
Обычный файл
@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University.
|
||||
# All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
||||
# All rights reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
CFILE=/tmp/ompi_atomic_$$.c
|
||||
|
||||
trap "/bin/rm -f $CFILE; exit 0" 0 1 2 15
|
||||
|
||||
echo Updating atomic.s from atomic.h using gcc
|
||||
|
||||
cat > $CFILE<<EOF
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#define static
|
||||
#define inline
|
||||
#define OMPI_GCC_INLINE_ASSEMBLY 1
|
||||
#define OMPI_WANT_SMP_LOCKS 1
|
||||
#include "atomic.h"
|
||||
EOF
|
||||
|
||||
gcc -I. -S $CFILE -o atomic.s
|
@ -14,7 +14,7 @@
|
||||
|
||||
include $(top_srcdir)/config/Makefile.options
|
||||
|
||||
noinst_HEADERS = atomic.h atomic.s
|
||||
noinst_HEADERS = atomic.h
|
||||
|
||||
# Conditionally install the header files
|
||||
|
||||
|
@ -25,6 +25,7 @@ cat > $CFILE<<EOF
|
||||
#define static
|
||||
#define inline
|
||||
#define OMPI_GCC_INLINE_ASSEMBLY 1
|
||||
#define OMPI_WANT_SMP_LOCKS 1
|
||||
#include "atomic.h"
|
||||
EOF
|
||||
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user