From 4265304230b4abb966b2b162b522873678527178 Mon Sep 17 00:00:00 2001 From: Brian Barrett Date: Mon, 14 Feb 2005 18:04:23 +0000 Subject: [PATCH] * 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. --- configure.ac | 1 + src/asm/Makefile.am | 1 + src/asm/asm.c | 81 ++++++++++++++++ src/include/sys/Makefile.am | 2 +- src/include/sys/alpha/update.sh | 1 + src/include/sys/amd64/update.sh | 1 + src/include/sys/atomic.h | 40 ++++++-- src/include/sys/atomic_impl.h | 3 +- src/include/sys/ia64/update.sh | 1 + src/include/sys/sparc/Makefile.am | 26 ++++++ src/include/sys/sparc/atomic.h | 140 ++++++++++++++++++++++++++++ src/include/sys/sparc/update.sh | 32 +++++++ src/include/sys/sparc64/Makefile.am | 2 +- src/include/sys/sparc64/update.sh | 1 + 14 files changed, 322 insertions(+), 10 deletions(-) create mode 100644 src/asm/asm.c create mode 100644 src/include/sys/sparc/Makefile.am create mode 100644 src/include/sys/sparc/atomic.h create mode 100644 src/include/sys/sparc/update.sh diff --git a/configure.ac b/configure.ac index bcebb47f9b..9a9491e62b 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/src/asm/Makefile.am b/src/asm/Makefile.am index f6b1104c0f..ef015f9e28 100644 --- a/src/asm/Makefile.am +++ b/src/asm/Makefile.am @@ -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 \ diff --git a/src/asm/asm.c b/src/asm/asm.c new file mode 100644 index 0000000000..a15c824728 --- /dev/null +++ b/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 */ diff --git a/src/include/sys/Makefile.am b/src/include/sys/Makefile.am index d9b1510a2d..1cb9acb836 100644 --- a/src/include/sys/Makefile.am +++ b/src/include/sys/Makefile.am @@ -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 diff --git a/src/include/sys/alpha/update.sh b/src/include/sys/alpha/update.sh index 9487684052..83737fcbdc 100644 --- a/src/include/sys/alpha/update.sh +++ b/src/include/sys/alpha/update.sh @@ -25,6 +25,7 @@ cat > $CFILE< $CFILE< $CFILE<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 */ diff --git a/src/include/sys/sparc/update.sh b/src/include/sys/sparc/update.sh new file mode 100644 index 0000000000..83737fcbdc --- /dev/null +++ b/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< +#include +#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 diff --git a/src/include/sys/sparc64/Makefile.am b/src/include/sys/sparc64/Makefile.am index 034552fb4f..ff5ceadb3b 100644 --- a/src/include/sys/sparc64/Makefile.am +++ b/src/include/sys/sparc64/Makefile.am @@ -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 diff --git a/src/include/sys/sparc64/update.sh b/src/include/sys/sparc64/update.sh index 9487684052..83737fcbdc 100644 --- a/src/include/sys/sparc64/update.sh +++ b/src/include/sys/sparc64/update.sh @@ -25,6 +25,7 @@ cat > $CFILE<