From e1e264711a6da3b8f54fa4872e416f4730a8ddc5 Mon Sep 17 00:00:00 2001 From: Ralph Castain Date: Thu, 25 May 2017 19:42:28 -0700 Subject: [PATCH] Update to pmix v2.0beta Fix atomics - again Fix initialization of notification ring buffer Fix wait_sync definitions Signed-off-by: Ralph Castain --- opal/mca/pmix/pmix2x/pmix/VERSION | 4 +- opal/mca/pmix/pmix2x/pmix/autogen.pl | 6 +- opal/mca/pmix/pmix2x/pmix/config/pmix.m4 | 48 +- .../pmix/config/pmix_check_pthread_pids.m4 | 109 ++ .../pmix2x/pmix/config/pmix_config_asm.m4 | 1307 +++++++++++++++++ .../pmix/config/pmix_config_pthreads.m4 | 669 +++++++++ .../pmix2x/pmix/config/pmix_config_threads.m4 | 71 + .../pmix2x/pmix/config/pmix_try_assemble.m4 | 52 + opal/mca/pmix/pmix2x/pmix/include/Makefile.am | 2 +- opal/mca/pmix/pmix2x/pmix/src/Makefile.am | 5 +- .../pmix2x/pmix/src/atomics/asm/Makefile.am | 92 ++ .../pmix2x/pmix/src/atomics/asm/asm-data.txt | 133 ++ .../pmix/pmix2x/pmix/src/atomics/asm/asm.c | 75 + .../pmix2x/pmix/src/atomics/asm/base/ARM.asm | 153 ++ .../pmix2x/pmix/src/atomics/asm/base/IA32.asm | 110 ++ .../pmix2x/pmix/src/atomics/asm/base/IA64.asm | 109 ++ .../pmix2x/pmix/src/atomics/asm/base/MIPS.asm | 196 +++ .../pmix/src/atomics/asm/base/POWERPC32.asm | 168 +++ .../pmix/src/atomics/asm/base/POWERPC64.asm | 157 ++ .../pmix/src/atomics/asm/base/SPARCV9_32.asm | 171 +++ .../pmix/src/atomics/asm/base/SPARCV9_64.asm | 111 ++ .../pmix/src/atomics/asm/base/X86_64.asm | 52 + .../pmix2x/pmix/src/atomics/asm/base/aix.conf | 44 + .../pmix/src/atomics/asm/base/default.conf | 34 + .../pmix/src/atomics/asm/generate-all-asm.pl | 27 + .../pmix/src/atomics/asm/generate-asm.pl | 123 ++ .../asm/generated/atomic-ia32-cygwin-nongas.s | 109 ++ .../asm/generated/atomic-ia32-cygwin.s | 111 ++ .../asm/generated/atomic-ia32-linux-nongas.s | 125 ++ .../atomics/asm/generated/atomic-ia32-linux.s | 127 ++ .../atomics/asm/generated/atomic-ia32-osx.s | 109 ++ .../asm/generated/atomic-ia64-linux-nongas.s | 108 ++ .../atomics/asm/generated/atomic-ia64-linux.s | 110 ++ .../atomics/asm/generated/atomic-mips-irix.s | 195 +++ .../atomics/asm/generated/atomic-mips-linux.s | 197 +++ .../asm/generated/atomic-mips64-linux.s | 197 +++ .../atomics/asm/generated/atomic-mips64el.s | 195 +++ .../asm/generated/atomic-powerpc32-64-osx.s | 165 +++ .../asm/generated/atomic-powerpc32-aix.s | 156 ++ .../generated/atomic-powerpc32-linux-nongas.s | 118 ++ .../asm/generated/atomic-powerpc32-linux.s | 120 ++ .../asm/generated/atomic-powerpc32-osx.s | 100 ++ .../asm/generated/atomic-powerpc64-aix.s | 230 +++ .../generated/atomic-powerpc64-linux-nongas.s | 180 +++ .../asm/generated/atomic-powerpc64-linux.s | 182 +++ .../asm/generated/atomic-powerpc64-osx.s | 156 ++ .../asm/generated/atomic-sparcv9-32-solaris.s | 190 +++ .../asm/generated/atomic-sparcv9-64-solaris.s | 130 ++ .../generated/atomic-x86_64-linux-nongas.s | 63 + .../asm/generated/atomic-x86_64-linux.s | 65 + .../pmix/src/atomics/sys/Makefile.include | 44 + .../pmix/src/atomics/sys/architecture.h | 57 + .../pmix/src/atomics/sys/arm/Makefile.include | 24 + .../pmix2x/pmix/src/atomics/sys/arm/atomic.h | 277 ++++ .../pmix2x/pmix/src/atomics/sys/arm/timer.h | 34 + .../src/atomics/sys/arm64/Makefile.include | 24 + .../pmix/src/atomics/sys/arm64/atomic.h | 302 ++++ .../pmix2x/pmix/src/atomics/sys/arm64/timer.h | 46 + .../pmix/pmix2x/pmix/src/atomics/sys/atomic.h | 623 ++++++++ .../pmix2x/pmix/src/atomics/sys/atomic_impl.h | 439 ++++++ .../pmix/pmix2x/pmix/src/atomics/sys/cma.h | 125 ++ .../atomics/sys/gcc_builtin/Makefile.include | 26 + .../pmix/src/atomics/sys/gcc_builtin/atomic.h | 229 +++ .../src/atomics/sys/ia32/Makefile.include | 24 + .../pmix2x/pmix/src/atomics/sys/ia32/atomic.h | 223 +++ .../pmix2x/pmix/src/atomics/sys/ia32/timer.h | 59 + .../src/atomics/sys/ia64/Makefile.include | 24 + .../pmix2x/pmix/src/atomics/sys/ia64/atomic.h | 146 ++ .../pmix2x/pmix/src/atomics/sys/ia64/timer.h | 49 + .../src/atomics/sys/mips/Makefile.include | 24 + .../pmix2x/pmix/src/atomics/sys/mips/atomic.h | 199 +++ .../pmix2x/pmix/src/atomics/sys/mips/timer.h | 34 + .../src/atomics/sys/powerpc/Makefile.include | 24 + .../pmix/src/atomics/sys/powerpc/atomic.h | 464 ++++++ .../pmix/src/atomics/sys/powerpc/timer.h | 53 + .../src/atomics/sys/sparcv9/Makefile.include | 24 + .../pmix/src/atomics/sys/sparcv9/atomic.h | 198 +++ .../pmix/src/atomics/sys/sparcv9/timer.h | 68 + .../atomics/sys/sync_builtin/Makefile.include | 24 + .../src/atomics/sys/sync_builtin/atomic.h | 137 ++ .../pmix/pmix2x/pmix/src/atomics/sys/timer.h | 131 ++ .../src/atomics/sys/x86_64/Makefile.include | 26 + .../pmix/src/atomics/sys/x86_64/atomic.h | 281 ++++ .../pmix/src/atomics/sys/x86_64/timer.h | 75 + .../pmix2x/pmix/src/buffer_ops/open_close.c | 32 +- .../pmix/pmix2x/pmix/src/buffer_ops/pack.c | 5 + .../pmix/pmix2x/pmix/src/buffer_ops/unpack.c | 7 +- .../pmix/src/class/pmix_pointer_array.c | 281 ++-- .../pmix/src/class/pmix_pointer_array.h | 56 +- .../pmix2x/pmix/src/client/Makefile.include | 2 +- .../pmix/pmix2x/pmix/src/client/pmix_client.c | 55 +- .../pmix2x/pmix/src/client/pmix_client_ops.h | 5 +- .../pmix/pmix2x/pmix/src/dstore/pmix_esh.c | 8 +- .../pmix/pmix2x/pmix/src/event/pmix_event.h | 80 +- .../pmix/src/event/pmix_event_notification.c | 26 +- .../pmix/src/event/pmix_event_registration.c | 11 +- .../pmix2x/pmix/src/include/pmix_globals.c | 13 +- .../pmix2x/pmix/src/include/pmix_globals.h | 3 + .../pmix2x/pmix/src/include/pmix_stdint.h | 258 +--- .../pmix/src/mca/pdl/pdlopen/configure.m4 | 2 +- .../pmix/src/mca/ptl/base/ptl_base_sendrecv.c | 21 +- .../pmix2x/pmix/src/runtime/pmix_finalize.c | 2 + .../pmix/pmix2x/pmix/src/runtime/pmix_init.c | 9 +- .../pmix2x/pmix/src/runtime/pmix_params.c | 9 + .../pmix/src/runtime/pmix_progress_threads.c | 43 +- .../pmix/pmix2x/pmix/src/runtime/pmix_rte.h | 3 +- .../pmix/pmix2x/pmix/src/server/pmix_server.c | 9 +- .../pmix2x/pmix/src/threads/Makefile.include | 40 + .../pmix/pmix2x/pmix/src/threads/condition.c | 39 + .../pmix/pmix2x/pmix/src/threads/condition.h | 78 + opal/mca/pmix/pmix2x/pmix/src/threads/mutex.c | 94 ++ opal/mca/pmix/pmix2x/pmix/src/threads/mutex.h | 103 ++ .../pmix/pmix2x/pmix/src/threads/mutex_unix.h | 215 +++ .../mca/pmix/pmix2x/pmix/src/threads/thread.c | 134 ++ .../pmix2x/pmix/src/threads/thread_usage.h | 109 ++ .../pmix/pmix2x/pmix/src/threads/threads.h | 128 ++ opal/mca/pmix/pmix2x/pmix/src/threads/tsd.h | 179 +++ .../pmix/pmix2x/pmix/src/threads/wait_sync.c | 102 ++ .../pmix/pmix2x/pmix/src/threads/wait_sync.h | 118 ++ opal/mca/pmix/pmix2x/pmix/test/Makefile.am | 4 +- .../pmix/pmix2x/pmix/test/simple/Makefile.am | 10 +- .../pmix/pmix2x/pmix/test/simple/simpdie.c | 155 ++ .../pmix/pmix2x/pmix/test/simple/simptest.c | 118 +- 123 files changed, 14085 insertions(+), 484 deletions(-) create mode 100644 opal/mca/pmix/pmix2x/pmix/config/pmix_check_pthread_pids.m4 create mode 100644 opal/mca/pmix/pmix2x/pmix/config/pmix_config_asm.m4 create mode 100644 opal/mca/pmix/pmix2x/pmix/config/pmix_config_pthreads.m4 create mode 100644 opal/mca/pmix/pmix2x/pmix/config/pmix_config_threads.m4 create mode 100644 opal/mca/pmix/pmix2x/pmix/config/pmix_try_assemble.m4 create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/Makefile.am create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/asm-data.txt create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/asm.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/ARM.asm create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/IA32.asm create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/IA64.asm create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/MIPS.asm create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/POWERPC32.asm create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/POWERPC64.asm create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/SPARCV9_32.asm create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/SPARCV9_64.asm create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/X86_64.asm create mode 100755 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/aix.conf create mode 100755 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/default.conf create mode 100755 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generate-all-asm.pl create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generate-asm.pl create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-cygwin-nongas.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-cygwin.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-linux-nongas.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-linux.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-osx.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia64-linux-nongas.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia64-linux.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-mips-irix.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-mips-linux.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-mips64-linux.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-mips64el.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-64-osx.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-aix.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-linux-nongas.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-linux.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-osx.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc64-aix.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc64-linux-nongas.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc64-linux.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc64-osx.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-sparcv9-32-solaris.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-sparcv9-64-solaris.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-x86_64-linux-nongas.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-x86_64-linux.s create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/Makefile.include create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/architecture.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm/Makefile.include create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm/atomic.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm/timer.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm64/Makefile.include create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm64/atomic.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm64/timer.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/atomic.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/atomic_impl.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/cma.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/gcc_builtin/Makefile.include create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/gcc_builtin/atomic.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia32/Makefile.include create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia32/atomic.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia32/timer.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia64/Makefile.include create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia64/atomic.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia64/timer.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/mips/Makefile.include create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/mips/atomic.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/mips/timer.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/powerpc/Makefile.include create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/powerpc/atomic.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/powerpc/timer.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sparcv9/Makefile.include create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sparcv9/atomic.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sparcv9/timer.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sync_builtin/Makefile.include create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sync_builtin/atomic.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/timer.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/x86_64/Makefile.include create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/x86_64/atomic.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/atomics/sys/x86_64/timer.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/threads/Makefile.include create mode 100644 opal/mca/pmix/pmix2x/pmix/src/threads/condition.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/threads/condition.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/threads/mutex.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/threads/mutex.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/threads/mutex_unix.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/threads/thread.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/threads/thread_usage.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/threads/threads.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/threads/tsd.h create mode 100644 opal/mca/pmix/pmix2x/pmix/src/threads/wait_sync.c create mode 100644 opal/mca/pmix/pmix2x/pmix/src/threads/wait_sync.h create mode 100644 opal/mca/pmix/pmix2x/pmix/test/simple/simpdie.c diff --git a/opal/mca/pmix/pmix2x/pmix/VERSION b/opal/mca/pmix/pmix2x/pmix/VERSION index b7a9149522..82ead00036 100644 --- a/opal/mca/pmix/pmix2x/pmix/VERSION +++ b/opal/mca/pmix/pmix2x/pmix/VERSION @@ -30,7 +30,7 @@ greek= # command, or with the date (if "git describe" fails) in the form of # "date". -repo_rev=git198a2b0 +repo_rev=git217c369 # If tarball_version is not empty, it is used as the version string in # the tarball filename, regardless of all other versions listed in @@ -44,7 +44,7 @@ tarball_version= # The date when this release was created -date="Apr 12, 2017" +date="May 25, 2017" # The shared library version of each of PMIx's public libraries. # These versions are maintained in accordance with the "Library diff --git a/opal/mca/pmix/pmix2x/pmix/autogen.pl b/opal/mca/pmix/pmix2x/pmix/autogen.pl index 8ca3350362..e8aa569bc9 100755 --- a/opal/mca/pmix/pmix2x/pmix/autogen.pl +++ b/opal/mca/pmix/pmix2x/pmix/autogen.pl @@ -4,7 +4,7 @@ # Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2013 Mellanox Technologies, Inc. # All rights reserved. -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved. +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. # Copyright (c) 2015 Research Organization for Information Science # and Technology (RIST). All rights reserved. # Copyright (c) 2015 IBM Corporation. All rights reserved. @@ -55,9 +55,9 @@ my $include_list; my $exclude_list; # Minimum versions -my $pmix_automake_version = "1.12.2"; +my $pmix_automake_version = "1.15.0"; my $pmix_autoconf_version = "2.69"; -my $pmix_libtool_version = "2.4.2"; +my $pmix_libtool_version = "2.4.6"; # Search paths my $pmix_autoconf_search = "autoconf"; diff --git a/opal/mca/pmix/pmix2x/pmix/config/pmix.m4 b/opal/mca/pmix/pmix2x/pmix/config/pmix.m4 index 236a9fd924..395b78406f 100644 --- a/opal/mca/pmix/pmix2x/pmix/config/pmix.m4 +++ b/opal/mca/pmix/pmix2x/pmix/config/pmix.m4 @@ -179,6 +179,8 @@ AC_DEFUN([PMIX_SETUP_CORE],[ AC_CHECK_TYPES(uint32_t) AC_CHECK_TYPES(int64_t) AC_CHECK_TYPES(uint64_t) + AC_CHECK_TYPES(__int128) + AC_CHECK_TYPES(uint128_t) AC_CHECK_TYPES(long long) AC_CHECK_TYPES(intptr_t) @@ -302,6 +304,17 @@ AC_DEFUN([PMIX_SETUP_CORE],[ PMIX_CHECK_ATTRIBUTES PMIX_CHECK_COMPILER_VERSION_ID + ################################## + # Assembler Configuration + ################################## + + pmix_show_subtitle "Assembler" + + AM_PROG_AS + AC_PATH_PROG(PERL, perl, perl) + PMIX_CONFIG_ASM + + ################################## # Header files ################################## @@ -618,6 +631,28 @@ AC_DEFUN([PMIX_SETUP_CORE],[ AC_C_BIGENDIAN PMIX_CHECK_BROKEN_QSORT + # + # Check out what thread support we have + # + PMIX_CONFIG_THREADS + + CFLAGS="$CFLAGS $THREAD_CFLAGS" + CPPFLAGS="$CPPFLAGS $THREAD_CPPFLAGS" + CXXFLAGS="$CXXFLAGS $THREAD_CXXFLAGS" + CXXCPPFLAGS="$CXXCPPFLAGS $THREAD_CXXCPPFLAGS" + LDFLAGS="$LDFLAGS $THREAD_LDFLAGS" + LIBS="$LIBS $THREAD_LIBS" + + # + # What is the local equivalent of "ln -s" + # + + AC_PROG_LN_S + + AC_PROG_GREP + AC_PROG_EGREP + + ################################## # Visibility ################################## @@ -708,6 +743,7 @@ AC_DEFUN([PMIX_SETUP_CORE],[ pmix_config_prefix[Makefile] pmix_config_prefix[config/Makefile] pmix_config_prefix[include/Makefile] + pmix_config_prefix[src/atomics/asm/Makefile] pmix_config_prefix[src/Makefile] pmix_config_prefix[src/util/keyval/Makefile] pmix_config_prefix[src/mca/base/Makefile] @@ -983,15 +1019,15 @@ fi # Install backward compatibility support for PMI-1 and PMI-2 # AC_MSG_CHECKING([if want backward compatibility for PMI-1 and PMI-2]) -AC_ARG_ENABLE(pmix-backward-compatibility, - AC_HELP_STRING([--enable-pmix-backward-compatibility], +AC_ARG_ENABLE(pmi-backward-compatibility, + AC_HELP_STRING([--enable-pmi-backward-compatibility], [enable PMIx support for PMI-1 and PMI-2 (default: enabled)])) -if test "$enable_pmix_backward_compatibility" = "no"; then +if test "$enable_pmi_backward_compatibility" = "no"; then AC_MSG_RESULT([no]) - WANT_PMIX_BACKWARD=0 + WANT_PMI_BACKWARD=0 else AC_MSG_RESULT([yes]) - WANT_PMIX_BACKWARD=1 + WANT_PMI_BACKWARD=1 fi AM_CONDITIONAL([WANT_INSTALL_HEADERS], [test $WANT_INSTALL_HEADERS -eq 1]) @@ -1009,7 +1045,7 @@ AC_DEFUN([PMIX_DO_AM_CONDITIONALS],[ AM_CONDITIONAL([WANT_DSTORE], [test "x$enable_dstore" != "xno"]) AM_CONDITIONAL([WANT_PRIMARY_HEADERS], [test "x$pmix_install_primary_headers" = "xyes"]) AM_CONDITIONAL(WANT_INSTALL_HEADERS, test "$WANT_INSTALL_HEADERS" = 1) - AM_CONDITIONAL(WANT_PMIX_BACKWARD, test "$WANT_PMIX_BACKWARD" = 1) + AM_CONDITIONAL(WANT_PMI_BACKWARD, test "$WANT_PMI_BACKWARD" = 1) ]) pmix_did_am_conditionals=yes ])dnl diff --git a/opal/mca/pmix/pmix2x/pmix/config/pmix_check_pthread_pids.m4 b/opal/mca/pmix/pmix2x/pmix/config/pmix_check_pthread_pids.m4 new file mode 100644 index 0000000000..2bf03579d8 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/config/pmix_check_pthread_pids.m4 @@ -0,0 +1,109 @@ +dnl +dnl Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana +dnl University Research and Technology +dnl Corporation. All rights reserved. +dnl Copyright (c) 2004-2005 The University of Tennessee and The University +dnl of Tennessee Research Foundation. All rights +dnl reserved. +dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +dnl University of Stuttgart. All rights reserved. +dnl Copyright (c) 2004-2005 The Regents of the University of California. +dnl All rights reserved. +dnl Copyright (c) 2008-2013 Cisco Systems, Inc. All rights reserved. +dnl Copyright (c) 2017 Intel, Inc. All rights reserved. +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ +dnl + +AC_DEFUN([PMIX_CHECK_PTHREAD_PIDS],[ +# +# Arguments: none +# +# Dependencies: None +# +# Sets: +# PMIX_THREADS_HAVE_DIFFERENT_PIDS (variable) +# +# Test for Linux-like threads in the system. PMIX does not support +# systems with different PIDs for threads in the same process, so error +# out if we detect that case. +# + +AC_MSG_CHECKING([if threads have different pids (pthreads on linux)]) + +PMIX_VAR_SCOPE_PUSH([tpids_CFLAGS_save tpids_CPPFLAGS_save tpids_LDFLAGS_save tpids_LIBS_save tpids_MSG]) +tpids_CFLAGS_save="$CFLAGS" +CFLAGS="$CFLAGS $THREAD_CFLAGS" +tpids_CPPFLAGS_save="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $THREAD_CPPFLAGS" +tpids_LDFLAGS_save="$LDFLAGS" +LDFLAGS="$LDFLAGS $THREAD_LDFLAGS" +tpids_LIBS_save="$LIBS" +LIBS="$LIBS $THREAD_LIBS" +AC_RUN_IFELSE([AC_LANG_SOURCE([#include +#include +#include +#include + +void *checkpid(void *arg); +int main() { + pthread_t thr; + int pid, *retval; + pid = getpid(); + pthread_create(&thr, NULL, checkpid, &pid); + pthread_join(thr, (void **) &retval); + exit(*retval); +} + +static int ret; +void *checkpid(void *arg) { + int ppid = *((int *) arg); + if (ppid == getpid()) + ret = 0; + else + ret = 1; + pthread_exit((void *) &ret); +}])], +[tpids_MSG=no PMIX_THREADS_HAVE_DIFFERENT_PIDS=0], +[tpids_MSG=yes PMIX_THREADS_HAVE_DIFFERENT_PIDS=1], +[ + # If we're cross compiling, we can't do another AC_* function here beause + # it we haven't displayed the result from the last one yet. So defer + # another test until below. + PMIX_THREADS_HAVE_DIFFERENT_PIDS= + MSG="cross compiling (need another test)"]) + +CFLAGS="$tpids_CFLAGS_save" +CPPFLAGS="$tpids_CPPFLAGS_save" +LDFLAGS="$tpids_LDFLAGS_save" +LIBS="$tpids_LIBS_save" + +AC_MSG_RESULT([$tpids_MSG]) + +AS_IF([test "x$PMIX_THREADS_HAVE_DIFFERENT_PIDS" = "x"], + [ # If we are cross-compiling, look for the symbol + # __linuxthreads_create_event, which seems to only exist in the + # Linux Threads-based pthreads implementation (i.e., the one + # that has different PIDs for each thread). We *could* switch + # on $host here and only test *linux* hosts, but this test is + # pretty unique, so why bother? Note that AC_CHECK_FUNC works + # properly in cross-compiling environments in recent-enough + # versions of Autoconf (which is one of the reasons we mandate + # recent versions in autogen!). + AC_CHECK_FUNC([__linuxthreads_create_event], + [PMIX_THREADS_HAVE_DIFFERENT_PIDS=1])]) + +AS_IF([test "$PMIX_THREADS_HAVE_DIFFERENT_PIDS" = "1"], + [AC_MSG_WARN([This version of PMIx only supports environments where]) + AC_MSG_WARN([threads have the same PID]) + AC_MSG_ERROR([Cannot continue]) + ]) + +# +# if pthreads is not available, then the system does not have an insane threads +# model +# +PMIX_VAR_SCOPE_POP])dnl diff --git a/opal/mca/pmix/pmix2x/pmix/config/pmix_config_asm.m4 b/opal/mca/pmix/pmix2x/pmix/config/pmix_config_asm.m4 new file mode 100644 index 0000000000..858e1e6309 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/config/pmix_config_asm.m4 @@ -0,0 +1,1307 @@ +dnl +dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +dnl University Research and Technology +dnl Corporation. All rights reserved. +dnl Copyright (c) 2004-2015 The University of Tennessee and The University +dnl of Tennessee Research Foundation. All rights +dnl reserved. +dnl Copyright (c) 2004-2006 High Performance Computing Center Stuttgart, +dnl University of Stuttgart. All rights reserved. +dnl Copyright (c) 2004-2005 The Regents of the University of California. +dnl All rights reserved. +dnl Copyright (c) 2008-2015 Cisco Systems, Inc. All rights reserved. +dnl Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. +dnl Copyright (c) 2015-2017 Research Organization for Information Science +dnl and Technology (RIST). All rights reserved. +dnl Copyright (c) 2014-2016 Los Alamos National Security, LLC. All rights +dnl reserved. +dnl Copyright (c) 2017 Amazon.com, Inc. or its affiliates. All Rights +dnl reserved. +dnl Copyright (c) 2017 Intel, Inc. All rights reserved. +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ +dnl + + +AC_DEFUN([PMIX_CHECK_SYNC_BUILTIN_CSWAP_INT128], [ + + PMIX_VAR_SCOPE_PUSH([sync_bool_compare_and_swap_128_result CFLAGS_save]) + + AC_ARG_ENABLE([cross-cmpset128],[AC_HELP_STRING([--enable-cross-cmpset128], + [enable the use of the __sync builtin atomic compare-and-swap 128 when cross compiling])]) + + sync_bool_compare_and_swap_128_result=0 + + if test ! "$enable_cross_cmpset128" = "yes" ; then + AC_MSG_CHECKING([for processor support of __sync builtin atomic compare-and-swap on 128-bit values]) + + AC_RUN_IFELSE([AC_LANG_PROGRAM([], [__int128 x = 0; __sync_bool_compare_and_swap (&x, 0, 1);])], + [AC_MSG_RESULT([yes]) + sync_bool_compare_and_swap_128_result=1], + [AC_MSG_RESULT([no])], + [AC_MSG_RESULT([no (cross compiling)])]) + + if test $sync_bool_compare_and_swap_128_result = 0 ; then + CFLAGS_save=$CFLAGS + CFLAGS="$CFLAGS -mcx16" + + AC_MSG_CHECKING([for __sync builtin atomic compare-and-swap on 128-bit values with -mcx16 flag]) + AC_RUN_IFELSE([AC_LANG_PROGRAM([], [__int128 x = 0; __sync_bool_compare_and_swap (&x, 0, 1);])], + [AC_MSG_RESULT([yes]) + sync_bool_compare_and_swap_128_result=1 + CFLAGS_save="$CFLAGS"], + [AC_MSG_RESULT([no])], + [AC_MSG_RESULT([no (cross compiling)])]) + + CFLAGS=$CFLAGS_save + fi + else + AC_MSG_CHECKING([for compiler support of __sync builtin atomic compare-and-swap on 128-bit values]) + + # Check if the compiler supports the __sync builtin + AC_TRY_LINK([], [__int128 x = 0; __sync_bool_compare_and_swap (&x, 0, 1);], + [AC_MSG_RESULT([yes]) + sync_bool_compare_and_swap_128_result=1], + [AC_MSG_RESULT([no])]) + + if test $sync_bool_compare_and_swap_128_result = 0 ; then + CFLAGS_save=$CFLAGS + CFLAGS="$CFLAGS -mcx16" + + AC_MSG_CHECKING([for __sync builtin atomic compare-and-swap on 128-bit values with -mcx16 flag]) + AC_TRY_LINK([], [__int128 x = 0; __sync_bool_compare_and_swap (&x, 0, 1);], + [AC_MSG_RESULT([yes]) + sync_bool_compare_and_swap_128_result=1 + CFLAGS_save="$CFLAGS"], + [AC_MSG_RESULT([no])]) + + CFLAGS=$CFLAGS_save + fi + fi + + AC_DEFINE_UNQUOTED([PMIX_HAVE_SYNC_BUILTIN_CSWAP_INT128], [$sync_bool_compare_and_swap_128_result], + [Whether the __sync builtin atomic compare and swap supports 128-bit values]) + + PMIX_VAR_SCOPE_POP +]) + +AC_DEFUN([PMIX_CHECK_SYNC_BUILTINS], [ + AC_MSG_CHECKING([for __sync builtin atomics]) + + AC_TRY_LINK([long tmp;], [__sync_synchronize(); +__sync_bool_compare_and_swap(&tmp, 0, 1); +__sync_add_and_fetch(&tmp, 1);], + [AC_MSG_RESULT([yes]) + $1], + [AC_MSG_RESULT([no]) + $2]) + + AC_MSG_CHECKING([for 64-bit __sync builtin atomics]) + + AC_TRY_LINK([ +#include +uint64_t tmp;], [ +__sync_bool_compare_and_swap(&tmp, 0, 1); +__sync_add_and_fetch(&tmp, 1);], + [AC_MSG_RESULT([yes]) + pmix_asm_sync_have_64bit=1], + [AC_MSG_RESULT([no]) + pmix_asm_sync_have_64bit=0]) + + AC_DEFINE_UNQUOTED([PMIX_ASM_SYNC_HAVE_64BIT],[$pmix_asm_sync_have_64bit], + [Whether 64-bit is supported by the __sync builtin atomics]) + + # Check for 128-bit support + PMIX_CHECK_SYNC_BUILTIN_CSWAP_INT128 +]) + + +AC_DEFUN([PMIX_CHECK_GCC_BUILTIN_CSWAP_INT128], [ + + PMIX_VAR_SCOPE_PUSH([atomic_compare_exchange_n_128_result CFLAGS_save]) + + AC_ARG_ENABLE([cross-cmpset128],[AC_HELP_STRING([--enable-cross-cmpset128], + [enable the use of the __sync builtin atomic compare-and-swap 128 when cross compiling])]) + + atomic_compare_exchange_n_128_result=0 + + if test ! "$enable_cross_cmpset128" = "yes" ; then + AC_MSG_CHECKING([for processor support of __atomic builtin atomic compare-and-swap on 128-bit values]) + + AC_RUN_IFELSE([AC_LANG_PROGRAM([], [__int128 x = 0, y = 0; __atomic_compare_exchange_n (&x, &y, 1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);])], + [AC_MSG_RESULT([yes]) + atomic_compare_exchange_n_128_result=1], + [AC_MSG_RESULT([no])], + [AC_MSG_RESULT([no (cross compiling)])]) + + if test $atomic_compare_exchange_n_128_result = 0 ; then + CFLAGS_save=$CFLAGS + CFLAGS="$CFLAGS -mcx16" + + AC_MSG_CHECKING([for __atomic builtin atomic compare-and-swap on 128-bit values with -mcx16 flag]) + AC_RUN_IFELSE([AC_LANG_PROGRAM([], [__int128 x = 0, y = 0; __atomic_compare_exchange_n (&x, &y, 1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);])], + [AC_MSG_RESULT([yes]) + atomic_compare_exchange_n_128_result=1 + CFLAGS_save="$CFLAGS"], + [AC_MSG_RESULT([no])], + [AC_MSG_RESULT([no (cross compiling)])]) + + CFLAGS=$CFLAGS_save + fi + + if test $atomic_compare_exchange_n_128_result = 1 ; then + AC_MSG_CHECKING([if __int128 atomic compare-and-swap is always lock-free]) + AC_RUN_IFELSE([AC_LANG_PROGRAM([], [if (!__atomic_always_lock_free(16, 0)) { return 1; }])], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + PMIX_CHECK_SYNC_BUILTIN_CSWAP_INT128 + atomic_compare_exchange_n_128_result=0], + [AC_MSG_RESULT([no (cross compiling)])]) + fi + else + AC_MSG_CHECKING([for compiler support of __atomic builtin atomic compare-and-swap on 128-bit values]) + + # Check if the compiler supports the __atomic builtin + AC_TRY_LINK([], [__int128 x = 0, y = 0; __atomic_compare_exchange_n (&x, &y, 1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);], + [AC_MSG_RESULT([yes]) + atomic_compare_exchange_n_128_result=1], + [AC_MSG_RESULT([no])]) + + if test $atomic_compare_exchange_n_128_result = 0 ; then + CFLAGS_save=$CFLAGS + CFLAGS="$CFLAGS -mcx16" + + AC_MSG_CHECKING([for __atomic builtin atomic compare-and-swap on 128-bit values with -mcx16 flag]) + AC_TRY_LINK([], [__int128 x = 0, y = 0; __atomic_compare_exchange_n (&x, &y, 1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);], + [AC_MSG_RESULT([yes]) + atomic_compare_exchange_n_128_result=1 + CFLAGS_save="$CFLAGS"], + [AC_MSG_RESULT([no])]) + + CFLAGS=$CFLAGS_save + fi + fi + + AC_DEFINE_UNQUOTED([PMIX_HAVE_GCC_BUILTIN_CSWAP_INT128], [$atomic_compare_exchange_n_128_result], + [Whether the __atomic builtin atomic compare and swap is lock-free on 128-bit values]) + + PMIX_VAR_SCOPE_POP +]) + +AC_DEFUN([PMIX_CHECK_GCC_ATOMIC_BUILTINS], [ + AC_MSG_CHECKING([for __atomic builtin atomics]) + + AC_TRY_LINK([long tmp, old = 0;], [__atomic_thread_fence(__ATOMIC_SEQ_CST); +__atomic_compare_exchange_n(&tmp, &old, 1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); +__atomic_add_fetch(&tmp, 1, __ATOMIC_RELAXED);], + [AC_MSG_RESULT([yes]) + $1], + [AC_MSG_RESULT([no]) + $2]) + + # Check for 128-bit support + PMIX_CHECK_GCC_BUILTIN_CSWAP_INT128 +]) + + +dnl ################################################################# +dnl +dnl PMIX_CHECK_ASM_TEXT +dnl +dnl Determine how to set current mode as text. +dnl +dnl ################################################################# +AC_DEFUN([PMIX_CHECK_ASM_TEXT],[ + AC_MSG_CHECKING([directive for setting text section]) + pmix_cv_asm_text="" + if test "$pmix_cv_c_compiler_vendor" = "microsoft" ; then + # text section will be brought in with the rest of + # header for MS - leave blank for now + pmix_cv_asm_text="" + else + case $host in + *-aix*) + pmix_cv_asm_text=[".csect .text[PR]"] + ;; + *) + pmix_cv_asm_text=".text" + ;; + esac + fi + AC_MSG_RESULT([$pmix_cv_asm_text]) + AC_DEFINE_UNQUOTED([PMIX_ASM_TEXT], ["$pmix_cv_asm_text"], + [Assembly directive for setting text section]) + PMIX_ASM_TEXT="$pmix_cv_asm_text" + AC_SUBST(PMIX_ASM_TEXT) +])dnl + + +dnl ################################################################# +dnl +dnl PMIX_CHECK_ASM_GLOBAL +dnl +dnl Sets PMIX_ASM_GLOBAL to the value to prefix global values +dnl +dnl I'm sure if I don't have a test for this, there will be some +dnl dumb platform that uses something else +dnl +dnl ################################################################# +AC_DEFUN([PMIX_CHECK_ASM_GLOBAL],[ + AC_MSG_CHECKING([directive for exporting symbols]) + pmix_cv_asm_global="" + if test "$pmix_cv_c_compiler_vendor" = "microsoft" ; then + pmix_cv_asm_global="PUBLIC" + else + case $host in + *) + pmix_cv_asm_global=".globl" + ;; + esac + fi + AC_MSG_RESULT([$pmix_cv_asm_global]) + AC_DEFINE_UNQUOTED([PMIX_ASM_GLOBAL], ["$pmix_cv_asm_global"], + [Assembly directive for exporting symbols]) + PMIX_ASM_GLOBAL="$pmix_cv_asm_global" + AC_SUBST(PMIX_AS_GLOBAL) +])dnl + + +dnl ################################################################# +dnl +dnl PMIX_CHECK_ASM_LSYM +dnl +dnl Sets PMIX_ASM_LSYM to the prefix value on a symbol to make it +dnl an internal label (jump target and whatnot) +dnl +dnl We look for L .L $ L$ (in that order) for something that both +dnl assembles and does not leave a label in the output of nm. Fall +dnl back to L if nothing else seems to work :/ +dnl +dnl ################################################################# + +# _PMIX_CHECK_ASM_LSYM([variable-to-set]) +# --------------------------------------- +AC_DEFUN([_PMIX_CHECK_ASM_LSYM],[ + AC_REQUIRE([AC_PROG_GREP]) + + $1="L" + + for sym in L .L $ L$ ; do + asm_result=0 + echo "configure: trying $sym" >&AC_FD_CC + PMIX_TRY_ASSEMBLE([foobar$pmix_cv_asm_label_suffix +${sym}mytestlabel$pmix_cv_asm_label_suffix], + [# ok, we succeeded at assembling. see if we can nm, + # throwing the results in a file + if $NM conftest.$OBJEXT > conftest.out 2>&AC_FD_CC ; then + if test "`$GREP mytestlabel conftest.out`" = "" ; then + # there was no symbol... looks promising to me + $1="$sym" + asm_result=1 + elif test ["`$GREP ' [Nt] .*mytestlabel' conftest.out`"] = "" ; then + # see if we have a non-global-ish symbol + # but we should see if we can do better. + $1="$sym" + fi + else + # not so much on the NM goodness :/ + echo "$NM failed. Output from NM was:" >&AC_FD_CC + cat conftest.out >&AC_FD_CC + AC_MSG_WARN([$NM could not read object file]) + fi + ]) + if test "$asm_result" = "1" ; then + break + fi + done + rm -f conftest.out + unset asm_result sym +]) + +# PMIX_CHECK_ASM_LSYM() +# --------------------- +AC_DEFUN([PMIX_CHECK_ASM_LSYM],[ + AC_REQUIRE([AC_PROG_NM]) + + AC_CACHE_CHECK([prefix for lsym labels], + [pmix_cv_asm_lsym], + [_PMIX_CHECK_ASM_LSYM([pmix_cv_asm_lsym])]) + AC_DEFINE_UNQUOTED([PMIX_ASM_LSYM], ["$pmix_cv_asm_lsym"], + [Assembly prefix for lsym labels]) + PMIX_ASM_LSYM="$pmix_cv_asm_lsym" + AC_SUBST(PMIX_ASM_LSYM) +])dnl + +dnl ################################################################# +dnl +dnl PMIX_CHECK_ASM_PROC +dnl +dnl Sets a cv-flag, if the compiler needs a proc/endp-definition to +dnl link with C. +dnl +dnl ################################################################# +AC_DEFUN([PMIX_CHECK_ASM_PROC],[ + AC_CACHE_CHECK([if .proc/endp is needed], + [pmix_cv_asm_need_proc], + [pmix_cv_asm_need_proc="no" + PMIX_TRY_ASSEMBLE([ + .proc mysym +mysym: + .endp mysym], + [pmix_cv_asm_need_proc="yes"]) + rm -f conftest.out]) + + if test "$pmix_cv_asm_need_proc" = "yes" ; then + pmix_cv_asm_proc=".proc" + pmix_cv_asm_endproc=".endp" + else + pmix_cv_asm_proc="#" + pmix_cv_asm_endproc="#" + fi +])dnl + + +dnl ################################################################# +dnl +dnl PMIX_CHECK_ASM_GSYM +dnl +dnl Sets PMIX_ASM_GSYM to the prefix value on a symbol to make it +dnl a global linkable from C. Basically, an _ or not. +dnl +dnl ################################################################# +AC_DEFUN([PMIX_CHECK_ASM_GSYM],[ + AC_CACHE_CHECK([prefix for global symbol labels], + [pmix_cv_asm_gsym], + [_PMIX_CHECK_ASM_GSYM]) + + if test "$pmix_cv_asm_gsym" = "none" ; then + AC_MSG_ERROR([Could not determine global symbol label prefix]) + fi + + AC_DEFINE_UNQUOTED([PMIX_ASM_GSYM], ["$pmix_cv_asm_gsym"], + [Assembly prefix for gsym labels]) + PMIX_ASM_GSYM="$pmix_cv_asm_gsym" + AC_SUBST(PMIX_ASM_GSYM) + +]) + +AC_DEFUN([_PMIX_CHECK_ASM_GSYM],[ + pmix_cv_asm_gsym="none" + + for sym in "_" "" "." ; do + asm_result=0 + echo "configure: trying $sym" >&AC_FD_CC +cat > conftest_c.c <&AC_FD_CC + pmix_link="$CC $CFLAGS conftest_c.$OBJEXT conftest.$OBJEXT -o conftest $LDFLAGS $LIBS > conftest.link 2>&1" + if AC_TRY_EVAL(pmix_link) ; then + # save the warnings + cat conftest.link >&AC_FD_CC + asm_result=1 + else + cat conftest.link >&AC_FD_CC + echo "configure: failed C program was: " >&AC_FD_CC + cat conftest_c.c >&AC_FD_CC + echo "configure: failed ASM program was: " >&AC_FD_CC + cat conftest.s >&AC_FD_CC + asm_result=0 + fi + else + # save output and failed program + cat conftest.cmpl >&AC_FD_CC + echo "configure: failed C program was: " >&AC_FD_CC + cat conftest.c >&AC_FD_CC + asm_result=0 + fi], + [asm_result=0]) + if test "$asm_result" = "1" ; then + pmix_cv_asm_gsym="$sym" + break + fi + done + rm -rf conftest.* +])dnl + + +dnl ################################################################# +dnl +dnl PMIX_CHECK_ASM_LABEL_SUFFIX +dnl +dnl Sets PMIX_ASM_LABEL_SUFFIX to the value to suffix for labels +dnl +dnl I'm sure if I don't have a test for this, there will be some +dnl dumb platform that uses something else +dnl +dnl ################################################################# +AC_DEFUN([PMIX_CHECK_ASM_LABEL_SUFFIX],[ + AC_MSG_CHECKING([suffix for labels]) + pmix_cv_asm_label_suffix="" + case $host in + *) + pmix_cv_asm_label_suffix=":" + ;; + esac + AC_MSG_RESULT([$pmix_cv_asm_label_suffix]) + AC_DEFINE_UNQUOTED([PMIX_ASM_LABEL_SUFFIX], ["$pmix_cv_asm_label_suffix"], + [Assembly suffix for labels]) + PMIX_ASM_LABEL_SUFFIX="$pmix_cv_asm_label_suffix" + AC_SUBST(PMIX_AS_LABEL_SUFFIX) +])dnl + + +dnl ################################################################# +dnl +dnl PMIX_CHECK_ASM_ALIGN_LOG +dnl +dnl Sets PMIX_ASM_ALIGN_LOG to 1 if align is specified +dnl logarithmically, 0 otherwise +dnl +dnl ################################################################# +AC_DEFUN([PMIX_CHECK_ASM_ALIGN_LOG],[ + AC_REQUIRE([AC_PROG_NM]) + AC_REQUIRE([AC_PROG_GREP]) + + AC_CACHE_CHECK([if .align directive takes logarithmic value], + [pmix_cv_asm_align_log], + [ PMIX_TRY_ASSEMBLE([ $pmix_cv_asm_text + .align 4 + $pmix_cv_asm_global foo + .byte 1 + .align 4 +foo$pmix_cv_asm_label_suffix + .byte 2], + [pmix_asm_addr=[`$NM conftest.$OBJEXT | $GREP foo | sed -e 's/.*\([0-9a-fA-F][0-9a-fA-F]\).*foo.*/\1/'`]], + [pmix_asm_addr=""]) + # test for both 16 and 10 (decimal and hex notations) + echo "configure: .align test address offset is $pmix_asm_addr" >&AC_FD_CC + if test "$pmix_asm_addr" = "16" || test "$pmix_asm_addr" = "10" ; then + pmix_cv_asm_align_log="yes" + else + pmix_cv_asm_align_log="no" + fi]) + + if test "$pmix_cv_asm_align_log" = "yes" || test "$pmix_cv_asm_align_log" = "1" ; then + pmix_asm_align_log_result=1 + else + pmix_asm_align_log_result=0 + fi + + AC_DEFINE_UNQUOTED([PMIX_ASM_ALIGN_LOG], + [$asm_align_log_result], + [Assembly align directive expects logarithmic value]) + + unset omp_asm_addr asm_result +])dnl + + +dnl ################################################################# +dnl +dnl PMIX_CHECK_ASM_TYPE +dnl +dnl Sets PMIX_ASM_TYPE to the prefix for the function type to +dnl set a symbol's type as function (needed on ELF for shared +dnl libaries). If no .type directive is needed, sets PMIX_ASM_TYPE +dnl to an empty string +dnl +dnl We look for @ \# % +dnl +dnl ################################################################# +AC_DEFUN([PMIX_CHECK_ASM_TYPE],[ + AC_CACHE_CHECK([prefix for function in .type], + [pmix_cv_asm_type], + [_PMIX_CHECK_ASM_TYPE]) + + AC_DEFINE_UNQUOTED([PMIX_ASM_TYPE], ["$pmix_cv_asm_type"], + [How to set function type in .type directive]) + PMIX_ASM_TYPE="$pmix_cv_asm_type" + AC_SUBST(PMIX_ASM_TYPE) +]) + +AC_DEFUN([_PMIX_CHECK_ASM_TYPE],[ + pmix_cv_asm_type="" + + case "${host}" in + *-sun-solaris*) + # GCC on solaris seems to accept just about anything, not + # that what it defines actually works... So just hardwire + # to the right answer + pmix_cv_asm_type="#" + ;; + *) + for type in @ \# % ; do + asm_result=0 + echo "configure: trying $type" >&AC_FD_CC + PMIX_TRY_ASSEMBLE([ .type mysym, ${type}function +mysym:], + [pmix_cv_asm_type="${type}" + asm_result=1]) + if test "$asm_result" = "1" ; then + break + fi + done + ;; + esac + rm -f conftest.out + + unset asm_result type +])dnl + + +dnl ################################################################# +dnl +dnl PMIX_CHECK_ASM_SIZE +dnl +dnl Sets PMIX_ASM_SIZE to 1 if we should set .size directives for +dnl each function, 0 otherwise. +dnl +dnl ################################################################# +AC_DEFUN([PMIX_CHECK_ASM_SIZE],[ + AC_CACHE_CHECK([if .size is needed], + [pmix_cv_asm_need_size], + [pmix_cv_asm_need_size="no" + PMIX_TRY_ASSEMBLE([ .size mysym, 1], + [pmix_cv_asm_need_size="yes"]) + rm -f conftest.out]) + + if test "$pmix_cv_asm_need_size" = "yes" ; then + pmix_asm_size=1 + else + pmix_asm_size=0 + fi + + AC_DEFINE_UNQUOTED([PMIX_ASM_SIZE], ["$pmix_asm_size"], + [Do we need to give a .size directive]) + PMIX_ASM_SIZE="$pmix_asm_size" + AC_SUBST(PMIX_ASM_TYPE) + unset asm_result +])dnl + + +# PMIX_CHECK_ASM_GNU_STACKEXEC(var) +# ---------------------------------- +# sets shell variable var to the things necessary to +# disable execable stacks with GAS +AC_DEFUN([PMIX_CHECK_ASM_GNU_STACKEXEC], [ + AC_REQUIRE([AC_PROG_GREP]) + + AC_CHECK_PROG([OBJDUMP], [objdump], [objdump]) + AC_CACHE_CHECK([if .note.GNU-stack is needed], + [pmix_cv_asm_gnu_stack_result], + [AS_IF([test "$OBJDUMP" != ""], + [ # first, see if a simple C program has it set + cat >conftest.c < /dev/null && pmix_cv_asm_gnu_stack_result=yes], + [PMIX_LOG_MSG([the failed program was:], 1) + PMIX_LOG_FILE([conftest.c]) + pmix_cv_asm_gnu_stack_result=no]) + if test "$pmix_cv_asm_gnu_stack_result" != "yes" ; then + pmix_cv_asm_gnu_stack_result="no" + fi + rm -rf conftest.*], + [pmix_cv_asm_gnu_stack_result="no"])]) + if test "$pmix_cv_asm_gnu_stack_result" = "yes" ; then + pmix_cv_asm_gnu_stack=1 + else + pmix_cv_asm_gnu_stack=0 + fi +])dnl + + +dnl ################################################################# +dnl +dnl PMIX_CHECK_POWERPC_REG +dnl +dnl See if the notation for specifying registers is X (most everyone) +dnl or rX (OS X) +dnl +dnl ################################################################# +AC_DEFUN([PMIX_CHECK_POWERPC_REG],[ + AC_MSG_CHECKING([if PowerPC registers have r prefix]) + PMIX_TRY_ASSEMBLE([$pmix_cv_asm_text + addi 1,1,0], + [pmix_cv_asm_powerpc_r_reg=0], + [PMIX_TRY_ASSEMBLE([$pmix_cv_asm_text + addi r1,r1,0], + [pmix_cv_asm_powerpc_r_reg=1], + [AC_MSG_ERROR([Can not determine how to use PPC registers])])]) + if test "$pmix_cv_asm_powerpc_r_reg" = "1" ; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + + AC_DEFINE_UNQUOTED([PMIX_POWERPC_R_REGISTERS], + [$pmix_cv_asm_powerpc_r_reg], + [Whether r notation is used for ppc registers]) +])dnl + + +dnl ################################################################# +dnl +dnl PMIX_CHECK_POWERPC_64BIT +dnl +dnl On some powerpc chips (the PPC970 or G5), the OS usually runs in +dnl 32 bit mode, even though the hardware can do 64bit things. If +dnl the compiler will let us, emit code for 64bit test and set type +dnl operations (on a long long). +dnl +dnl ################################################################# +AC_DEFUN([PMIX_CHECK_POWERPC_64BIT],[ + if test "$ac_cv_sizeof_long" != "4" ; then + # this function should only be called in the 32 bit case + AC_MSG_ERROR([CHECK_POWERPC_64BIT called on 64 bit platform. Internal error.]) + fi + AC_MSG_CHECKING([for 64-bit PowerPC assembly support]) + case $host in + *-darwin*) + ppc64_result=0 + if test "$pmix_cv_asm_powerpc_r_reg" = "1" ; then + ldarx_asm=" ldarx r1,r1,r1"; + else + ldarx_asm=" ldarx 1,1,1"; + fi + PMIX_TRY_ASSEMBLE([$pmix_cv_asm_text + $ldarx_asm], + [ppc64_result=1], + [ppc64_result=0]) + ;; + *) + ppc64_result=0 + ;; + esac + + if test "$ppc64_result" = "1" ; then + AC_MSG_RESULT([yes]) + ifelse([$1],,:,[$1]) + else + AC_MSG_RESULT([no]) + ifelse([$2],,:,[$2]) + fi + + unset ppc64_result ldarx_asm +])dnl + + +dnl ################################################################# +dnl +dnl PMIX_CHECK_SPARCV8PLUS +dnl +dnl ################################################################# +AC_DEFUN([PMIX_CHECK_SPARCV8PLUS],[ + AC_MSG_CHECKING([if have Sparc v8+/v9 support]) + sparc_result=0 + PMIX_TRY_ASSEMBLE([$pmix_cv_asm_text + casa [%o0] 0x80, %o1, %o2], + [sparc_result=1], + [sparc_result=0]) + if test "$sparc_result" = "1" ; then + AC_MSG_RESULT([yes]) + ifelse([$1],,:,[$1]) + else + AC_MSG_RESULT([no]) + ifelse([$2],,:,[$2]) + fi + + unset sparc_result +])dnl + +dnl ################################################################# +dnl +dnl PMIX_CHECK_CMPXCHG16B +dnl +dnl ################################################################# +AC_DEFUN([PMIX_CHECK_CMPXCHG16B],[ + PMIX_VAR_SCOPE_PUSH([cmpxchg16b_result]) + + AC_ARG_ENABLE([cross-cmpxchg16b],[AC_HELP_STRING([--enable-cross-cmpxchg16b], + [enable the use of the cmpxchg16b instruction when cross compiling])]) + + if test ! "$enable_cross_cmpxchg16b" = "yes" ; then + AC_MSG_CHECKING([if processor supports x86_64 16-byte compare-and-exchange]) + AC_RUN_IFELSE([AC_LANG_PROGRAM([[unsigned char tmp[16];]],[[ + __asm__ __volatile__ ("lock cmpxchg16b (%%rsi)" : : "S" (tmp) : "memory", "cc");]])], + [AC_MSG_RESULT([yes]) + cmpxchg16b_result=1], + [AC_MSG_RESULT([no]) + cmpxchg16b_result=0], + [AC_MSG_RESULT([no (cross-compiling)]) + cmpxchg16b_result=0]) + else + AC_MSG_CHECKING([if assembler supports x86_64 16-byte compare-and-exchange]) + + PMIX_TRY_ASSEMBLE([$pmix_cv_asm_text + cmpxchg16b 0], + [AC_MSG_RESULT([yes]) + cmpxchg16b_result=1], + [AC_MSG_RESULT([no]) + cmpxchg16b_result=0]) + fi + if test "$cmpxchg16b_result" = 1; then + AC_MSG_CHECKING([if compiler correctly handles volatile 128bits]) + AC_RUN_IFELSE([AC_LANG_PROGRAM([#include +#include + +union pmix_counted_pointer_t { + struct { + uint64_t counter; + uint64_t item; + } data; +#if defined(HAVE___INT128) && HAVE___INT128 + __int128 value; +#elif defined(HAVE_INT128_T) && HAVE_INT128_T + int128_t value; +#endif +}; +typedef union pmix_counted_pointer_t pmix_counted_pointer_t;], + [volatile pmix_counted_pointer_t a; + pmix_counted_pointer_t b; + + a.data.counter = 0; + a.data.item = 0x1234567890ABCDEF; + + b.data.counter = a.data.counter; + b.data.item = a.data.item; + + /* bozo checks */ + assert(16 == sizeof(pmix_counted_pointer_t)); + assert(a.data.counter == b.data.counter); + assert(a.data.item == b.data.item); + /* + * the following test fails on buggy compilers + * so far, with icc -o conftest conftest.c + * - intel icc 14.0.0.080 (aka 2013sp1) + * - intel icc 14.0.1.106 (aka 2013sp1u1) + * older and more recents compilers work fine + * buggy compilers work also fine but only with -O0 + */ +#if (defined(HAVE___INT128) && HAVE___INT128) || (defined(HAVE_INT128_T) && HAVE_INT128_T) + return (a.value != b.value); +#else + return 0; +#endif])], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + cmpxchg16b_result=0], + [AC_MSG_RESULT([untested, assuming ok])]) + fi + AC_DEFINE_UNQUOTED([PMIX_HAVE_CMPXCHG16B], [$cmpxchg16b_result], + [Whether the processor supports the cmpxchg16b instruction]) + PMIX_VAR_SCOPE_POP +])dnl + +dnl ################################################################# +dnl +dnl PMIX_CHECK_INLINE_GCC +dnl +dnl Check if the compiler is capable of doing GCC-style inline +dnl assembly. Some compilers emit a warning and ignore the inline +dnl assembly (xlc on OS X) and compile without error. Therefore, +dnl the test attempts to run the emited code to check that the +dnl assembly is actually run. To run this test, one argument to +dnl the macro must be an assembly instruction in gcc format to move +dnl the value 0 into the register containing the variable ret. +dnl For PowerPC, this would be: +dnl +dnl "li %0,0" : "=&r"(ret) +dnl +dnl For testing ia32 assembly, the assembly instruction xaddl is +dnl tested. The xaddl instruction is used by some of the atomic +dnl implementations so it makes sense to test for it. In addition, +dnl some compilers (i.e. earlier versions of Sun Studio 12) do not +dnl necessarily handle xaddl properly, so that needs to be detected +dnl during configure time. +dnl +dnl DEFINE PMIX_GCC_INLINE_ASSEMBLY to 0 or 1 depending on GCC +dnl support +dnl +dnl ################################################################# +AC_DEFUN([PMIX_CHECK_INLINE_C_GCC],[ + assembly="$1" + asm_result="unknown" + + AC_MSG_CHECKING([if $CC supports GCC inline assembly]) + + if test ! "$assembly" = "" ; then + AC_RUN_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],[[ +int ret = 1; +int negone = -1; +__asm__ __volatile__ ($assembly); +return ret; + ]])], + [asm_result="yes"], [asm_result="no"], + [asm_result="unknown"]) + else + assembly="test skipped - assuming no" + fi + + # if we're cross compiling, just try to compile and figure good enough + if test "$asm_result" = "unknown" ; then + AC_LINK_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],[[ +int ret = 1; +int negone = -1; +__asm__ __volatile__ ($assembly); +return ret; + ]])], + [asm_result="yes"], [asm_result="no"]) + fi + + AC_MSG_RESULT([$asm_result]) + + if test "$asm_result" = "yes" ; then + PMIX_C_GCC_INLINE_ASSEMBLY=1 + else + PMIX_C_GCC_INLINE_ASSEMBLY=0 + fi + + AC_DEFINE_UNQUOTED([PMIX_C_GCC_INLINE_ASSEMBLY], + [$PMIX_C_GCC_INLINE_ASSEMBLY], + [Whether C compiler supports GCC style inline assembly]) + + unset PMIX_C_GCC_INLINE_ASSEMBLY assembly asm_result +])dnl + + +dnl ################################################################# +dnl +dnl PMIX_CHECK_INLINE_DEC +dnl +dnl DEFINE PMIX_DEC to 0 or 1 depending on DEC +dnl support +dnl +dnl ################################################################# +AC_DEFUN([PMIX_CHECK_INLINE_C_DEC],[ + + AC_MSG_CHECKING([if $CC supports DEC inline assembly]) + + AC_LINK_IFELSE([AC_LANG_PROGRAM([ +AC_INCLUDES_DEFAULT +#include ], +[[asm(""); +return 0;]])], + [asm_result="yes"], [asm_result="no"]) + + AC_MSG_RESULT([$asm_result]) + + if test "$asm_result" = "yes" ; then + PMIX_C_DEC_INLINE_ASSEMBLY=1 + else + PMIX_C_DEC_INLINE_ASSEMBLY=0 + fi + + AC_DEFINE_UNQUOTED([PMIX_C_DEC_INLINE_ASSEMBLY], + [$PMIX_C_DEC_INLINE_ASSEMBLY], + [Whether C compiler supports DEC style inline assembly]) + + unset PMIX_C_DEC_INLINE_ASSEMBLY asm_result +])dnl + + +dnl ################################################################# +dnl +dnl PMIX_CHECK_INLINE_XLC +dnl +dnl DEFINE PMIX_XLC to 0 or 1 depending on XLC +dnl support +dnl +dnl ################################################################# +AC_DEFUN([PMIX_CHECK_INLINE_C_XLC],[ + + AC_MSG_CHECKING([if $CC supports XLC inline assembly]) + + PMIX_C_XLC_INLINE_ASSEMBLY=0 + asm_result="no" + if test "$CC" = "xlc" ; then + PMIX_XLC_INLINE_ASSEMBLY=1 + asm_result="yes" + fi + + AC_MSG_RESULT([$asm_result]) + AC_DEFINE_UNQUOTED([PMIX_C_XLC_INLINE_ASSEMBLY], + [$PMIX_C_XLC_INLINE_ASSEMBLY], + [Whether C compiler supports XLC style inline assembly]) + + unset PMIX_C_XLC_INLINE_ASSEMBLY +])dnl + + +dnl ################################################################# +dnl +dnl PMIX_CONFIG_ASM +dnl +dnl DEFINE PMIX_ASSEMBLY_ARCH to something in sys/architecture.h +dnl DEFINE PMIX_ASSEMBLY_FORMAT to string containing correct +dnl format for assembly (not user friendly) +dnl SUBST PMIX_ASSEMBLY_FORMAT to string containing correct +dnl format for assembly (not user friendly) +dnl +dnl ################################################################# +AC_DEFUN([PMIX_CONFIG_ASM],[ + AC_REQUIRE([PMIX_SETUP_CC]) + AC_REQUIRE([AM_PROG_AS]) + + AC_ARG_ENABLE([builtin-atomics], + [AC_HELP_STRING([--enable-builtin-atomics], + [Enable use of __sync builtin atomics (default: enabled)])], + [], [enable_builtin_atomics="yes"]) + + pmix_cv_asm_builtin="BUILTIN_NO" + if test "$pmix_cv_asm_builtin" = "BUILTIN_NO" && test "$enable_builtin_atomics" = "yes" ; then + PMIX_CHECK_GCC_ATOMIC_BUILTINS([pmix_cv_asm_builtin="BUILTIN_GCC"], []) + fi + if test "$pmix_cv_asm_builtin" = "BUILTIN_NO" && test "$enable_builtin_atomics" = "yes" ; then + PMIX_CHECK_SYNC_BUILTINS([pmix_cv_asm_builtin="BUILTIN_SYNC"], []) + fi + + PMIX_CHECK_ASM_PROC + PMIX_CHECK_ASM_TEXT + PMIX_CHECK_ASM_GLOBAL + PMIX_CHECK_ASM_GNU_STACKEXEC + PMIX_CHECK_ASM_LABEL_SUFFIX + PMIX_CHECK_ASM_GSYM + PMIX_CHECK_ASM_LSYM + PMIX_CHECK_ASM_TYPE + PMIX_CHECK_ASM_SIZE + PMIX_CHECK_ASM_ALIGN_LOG + + # find our architecture for purposes of assembly stuff + pmix_cv_asm_arch="UNSUPPORTED" + PMIX_GCC_INLINE_ASSIGN="" + PMIX_ASM_SUPPORT_64BIT=0 + case "${host}" in + x86_64-*x32) + pmix_cv_asm_arch="X86_64" + PMIX_ASM_SUPPORT_64BIT=1 + PMIX_GCC_INLINE_ASSIGN='"xaddl %1,%0" : "=m"(ret), "+r"(negone) : "m"(ret)' + ;; + i?86-*|x86_64*|amd64*) + if test "$ac_cv_sizeof_long" = "4" ; then + pmix_cv_asm_arch="IA32" + else + pmix_cv_asm_arch="X86_64" + fi + PMIX_ASM_SUPPORT_64BIT=1 + PMIX_GCC_INLINE_ASSIGN='"xaddl %1,%0" : "=m"(ret), "+r"(negone) : "m"(ret)' + PMIX_CHECK_CMPXCHG16B + ;; + + ia64-*) + pmix_cv_asm_arch="IA64" + PMIX_ASM_SUPPORT_64BIT=1 + PMIX_GCC_INLINE_ASSIGN='"mov %0=r0\n;;\n" : "=&r"(ret)' + ;; + aarch64*) + pmix_cv_asm_arch="ARM64" + PMIX_ASM_SUPPORT_64BIT=1 + PMIX_ASM_ARM_VERSION=8 + AC_DEFINE_UNQUOTED([PMIX_ASM_ARM_VERSION], [$PMIX_ASM_ARM_VERSION], + [What ARM assembly version to use]) + PMIX_GCC_INLINE_ASSIGN='"mov %0, #0" : "=&r"(ret)' + ;; + + armv7*|arm-*-linux-gnueabihf) + pmix_cv_asm_arch="ARM" + PMIX_ASM_SUPPORT_64BIT=1 + PMIX_ASM_ARM_VERSION=7 + AC_DEFINE_UNQUOTED([PMIX_ASM_ARM_VERSION], [$PMIX_ASM_ARM_VERSION], + [What ARM assembly version to use]) + PMIX_GCC_INLINE_ASSIGN='"mov %0, #0" : "=&r"(ret)' + ;; + + armv6*) + pmix_cv_asm_arch="ARM" + PMIX_ASM_SUPPORT_64BIT=0 + PMIX_ASM_ARM_VERSION=6 + CCASFLAGS="$CCASFLAGS -march=armv7-a" + AC_DEFINE_UNQUOTED([PMIX_ASM_ARM_VERSION], [$PMIX_ASM_ARM_VERSION], + [What ARM assembly version to use]) + PMIX_GCC_INLINE_ASSIGN='"mov %0, #0" : "=&r"(ret)' + ;; + + armv5*linux*|armv4*linux*|arm-*-linux-gnueabi) + # uses Linux kernel helpers for some atomic operations + pmix_cv_asm_arch="ARM" + PMIX_ASM_SUPPORT_64BIT=0 + PMIX_ASM_ARM_VERSION=5 + CCASFLAGS="$CCASFLAGS -march=armv7-a" + AC_DEFINE_UNQUOTED([PMIX_ASM_ARM_VERSION], [$PMIX_ASM_ARM_VERSION], + [What ARM assembly version to use]) + PMIX_GCC_INLINE_ASSIGN='"mov %0, #0" : "=&r"(ret)' + ;; + + mips-*|mips64*) + # Should really find some way to make sure that we are on + # a MIPS III machine (r4000 and later) + pmix_cv_asm_arch="MIPS" + PMIX_ASM_SUPPORT_64BIT=1 + PMIX_GCC_INLINE_ASSIGN='"or %0,[$]0,[$]0" : "=&r"(ret)' + ;; + + powerpc-*|powerpc64-*|powerpcle-*|powerpc64le-*|rs6000-*|ppc-*) + PMIX_CHECK_POWERPC_REG + if test "$ac_cv_sizeof_long" = "4" ; then + pmix_cv_asm_arch="POWERPC32" + + # Note that on some platforms (Apple G5), even if we are + # compiling in 32 bit mode (and therefore should assume + # sizeof(long) == 4), we can use the 64 bit test and set + # operations. + PMIX_CHECK_POWERPC_64BIT(PMIX_ASM_SUPPORT_64BIT=1) + elif test "$ac_cv_sizeof_long" = "8" ; then + PMIX_ASM_SUPPORT_64BIT=1 + pmix_cv_asm_arch="POWERPC64" + else + AC_MSG_ERROR([Could not determine PowerPC word size: $ac_cv_sizeof_long]) + fi + PMIX_GCC_INLINE_ASSIGN='"1: li %0,0" : "=&r"(ret)' + ;; + + # There is no current difference between s390 and s390x + # But use two different defines in case some come later + # as s390 is 31bits while s390x is 64bits + s390-*) + pmix_cv_asm_arch="S390" + ;; + s390x-*) + pmix_cv_asm_arch="S390X" + ;; + + sparc*-*) + # SPARC v9 (and above) are the only ones with 64bit support + # if compiling 32 bit, see if we are v9 (aka v8plus) or + # earlier (casa is v8+/v9). + if test "$ac_cv_sizeof_long" = "4" ; then + have_v8plus=0 + PMIX_CHECK_SPARCV8PLUS([have_v8plus=1]) + if test "$have_v8plus" = "0" ; then + PMIX_ASM_SUPPORT_64BIT=0 + pmix_cv_asm_arch="SPARC" +AC_MSG_WARN([Sparc v8 target is not supported in this release of Open MPI.]) +AC_MSG_WARN([You must specify the target architecture v8plus to compile]) +AC_MSG_WARN([Open MPI in 32 bit mode on Sparc processors (see the README).]) +AC_MSG_ERROR([Can not continue.]) + else + PMIX_ASM_SUPPORT_64BIT=1 + pmix_cv_asm_arch="SPARCV9_32" + fi + + elif test "$ac_cv_sizeof_long" = "8" ; then + PMIX_ASM_SUPPORT_64BIT=1 + pmix_cv_asm_arch="SPARCV9_64" + else + AC_MSG_ERROR([Could not determine Sparc word size: $ac_cv_sizeof_long]) + fi + PMIX_GCC_INLINE_ASSIGN='"mov 0,%0" : "=&r"(ret)' + ;; + + *) + PMIX_CHECK_SYNC_BUILTINS([pmix_cv_asm_builtin="BUILTIN_SYNC"], + [AC_MSG_ERROR([No atomic primitives available for $host])]) + ;; + esac + + if test "x$PMIX_ASM_SUPPORT_64BIT" = "x1" && test "$pmix_cv_asm_builtin" = "BUILTIN_SYNC" && + test "$pmix_asm_sync_have_64bit" = "0" ; then + # __sync builtins exist but do not implement 64-bit support. Fall back on inline asm. + pmix_cv_asm_builtin="BUILTIN_NO" + fi + + if test "$pmix_cv_asm_builtin" = "BUILTIN_SYNC" || test "$pmix_cv_asm_builtin" = "BUILTIN_GCC" ; then + AC_DEFINE([PMIX_C_GCC_INLINE_ASSEMBLY], [1], + [Whether C compiler supports GCC style inline assembly]) + else + AC_DEFINE_UNQUOTED([PMIX_ASM_SUPPORT_64BIT], + [$PMIX_ASM_SUPPORT_64BIT], + [Whether we can do 64bit assembly operations or not. Should not be used outside of the assembly header files]) + AC_SUBST([PMIX_ASM_SUPPORT_64BIT]) + + # + # figure out if we need any special function start / stop code + # + case $host_os in + aix*) + pmix_asm_arch_config="aix" + ;; + *) + pmix_asm_arch_config="default" + ;; + esac + + # now that we know our architecture, try to inline assemble + PMIX_CHECK_INLINE_C_GCC([$PMIX_GCC_INLINE_ASSIGN]) + PMIX_CHECK_INLINE_C_DEC + PMIX_CHECK_INLINE_C_XLC + + # format: + # config_file-text-global-label_suffix-gsym-lsym-type-size-align_log-ppc_r_reg-64_bit-gnu_stack + asm_format="${pmix_asm_arch_config}" + asm_format="${asm_format}-${pmix_cv_asm_text}-${pmix_cv_asm_global}" + asm_format="${asm_format}-${pmix_cv_asm_label_suffix}-${pmix_cv_asm_gsym}" + asm_format="${asm_format}-${pmix_cv_asm_lsym}" + asm_format="${asm_format}-${pmix_cv_asm_type}-${pmix_asm_size}" + asm_format="${asm_format}-${pmix_asm_align_log_result}" + if test "$pmix_cv_asm_arch" = "POWERPC32" || test "$pmix_cv_asm_arch" = "POWERPC64" ; then + asm_format="${asm_format}-${pmix_cv_asm_powerpc_r_reg}" + else + asm_format="${asm_format}-1" + fi + asm_format="${asm_format}-${PMIX_ASM_SUPPORT_64BIT}" + pmix_cv_asm_format="${asm_format}-${pmix_cv_asm_gnu_stack}" + # For the Makefile, need to escape the $ as $$. Don't display + # this version, but make sure the Makefile gives the right thing + # when regenerating the files because the base has been touched. + PMIX_ASSEMBLY_FORMAT=`echo "$pmix_cv_asm_format" | sed -e 's/\\\$/\\\$\\\$/'` + + AC_MSG_CHECKING([for assembly format]) + AC_MSG_RESULT([$pmix_cv_asm_format]) + AC_DEFINE_UNQUOTED([PMIX_ASSEMBLY_FORMAT], ["$PMIX_ASSEMBLY_FORMAT"], + [Format of assembly file]) + AC_SUBST([PMIX_ASSEMBLY_FORMAT]) + fi # if pmix_cv_asm_builtin = BUILTIN_SYNC + + result="PMIX_$pmix_cv_asm_arch" + PMIX_ASSEMBLY_ARCH="$pmix_cv_asm_arch" + AC_MSG_CHECKING([for assembly architecture]) + AC_MSG_RESULT([$pmix_cv_asm_arch]) + AC_DEFINE_UNQUOTED([PMIX_ASSEMBLY_ARCH], [$result], + [Architecture type of assembly to use for atomic operations and CMA]) + AC_SUBST([PMIX_ASSEMBLY_ARCH]) + + # Check for RDTSCP support + result=0 + AS_IF([test "$pmix_cv_asm_arch" = "PMIX_X86_64" || test "$pmix_cv_asm_arch" = "PMIX_IA32"], + [AC_MSG_CHECKING([for RDTSCP assembly support]) + AC_LANG_PUSH([C]) + AC_TRY_RUN([[ +int main(int argc, char* argv[]) +{ + unsigned int rax, rdx; + __asm__ __volatile__ ("rdtscp\n": "=a" (rax), "=d" (rdx):: "%rax", "%rdx"); + return 0; +} + ]], + [result=1 + AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no])], + [#cross compile not supported + AC_MSG_RESULT(["no (cross compiling)"])]) + AC_LANG_POP([C])]) + AC_DEFINE_UNQUOTED([PMIX_ASSEMBLY_SUPPORTS_RDTSCP], [$result], + [Whether we have support for RDTSCP instruction]) + + result="PMIX_$pmix_cv_asm_builtin" + PMIX_ASSEMBLY_BUILTIN="$pmix_cv_asm_builtin" + AC_MSG_CHECKING([for builtin atomics]) + AC_MSG_RESULT([$pmix_cv_asm_builtin]) + AC_DEFINE_UNQUOTED([PMIX_ASSEMBLY_BUILTIN], [$result], + [Whether to use builtin atomics]) + AC_SUBST([PMIX_ASSEMBLY_BUILTIN]) + + PMIX_ASM_FIND_FILE + + unset result asm_format +])dnl + + +dnl ################################################################# +dnl +dnl PMIX_ASM_FIND_FILE +dnl +dnl +dnl do all the evil mojo to provide a working assembly file +dnl +dnl ################################################################# +AC_DEFUN([PMIX_ASM_FIND_FILE], [ + AC_REQUIRE([AC_PROG_GREP]) + AC_REQUIRE([AC_PROG_FGREP]) + +if test "$pmix_cv_asm_arch" != "WINDOWS" && test "$pmix_cv_asm_builtin" != "BUILTIN_SYNC" && test "$pmix_cv_asm_builtin" != "BUILTIN_GCC" && test "$pmix_cv_asm_builtin" != "BUILTIN_OSX" ; then + # see if we have a pre-built one already + AC_MSG_CHECKING([for pre-built assembly file]) + pmix_cv_asm_file="" + if $GREP "$pmix_cv_asm_arch" "${PMIX_TOP_SRCDIR}/src/atomics/asm/asm-data.txt" | $FGREP "$pmix_cv_asm_format" >conftest.out 2>&1 ; then + pmix_cv_asm_file="`cut -f3 conftest.out`" + if test ! "$pmix_cv_asm_file" = "" ; then + pmix_cv_asm_file="atomic-${pmix_cv_asm_file}.s" + if test -f "${PMIX_TOP_SRCDIR}/src/atomics/asm/generated/${pmix_cv_asm_file}" ; then + AC_MSG_RESULT([yes ($pmix_cv_asm_file)]) + else + AC_MSG_RESULT([no ($pmix_cv_asm_file not found)]) + pmix_cv_asm_file="" + fi + fi + else + AC_MSG_RESULT([no (not in asm-data)]) + fi + rm -rf conftest.* + + if test "$pmix_cv_asm_file" = "" ; then + # Can we generate a file? + AC_MSG_CHECKING([whether possible to generate assembly file]) + mkdir -p pmix/asm/generated + pmix_cv_asm_file="atomic-local.s" + pmix_try='$PERL $PMIX_TOP_SRCDIR/src/atomics/asm/generate-asm.pl $pmix_cv_asm_arch "$pmix_cv_asm_format" $PMIX_TOP_SRCDIR/src/atomics/asm/base $PMIX_TOP_BUILDDIR/src/atomics/asm/generated/$pmix_cv_asm_file >conftest.out 2>&1' + if AC_TRY_EVAL(pmix_try) ; then + # save the warnings + cat conftest.out >&AC_FD_CC + AC_MSG_RESULT([yes]) + else + # save output + cat conftest.out >&AC_FD_CC + pmix_cv_asm_file="" + AC_MSG_RESULT([failed]) + AC_MSG_WARN([Could not build atomic operations assembly file.]) + AC_MSG_WARN([There will be no atomic operations for this build.]) + fi + fi + rm -rf conftest.* +else + # On windows with VC++, atomics are done with compiler primitives + pmix_cv_asm_file="" +fi + + AC_MSG_CHECKING([for atomic assembly filename]) + if test "$pmix_cv_asm_file" = "" ; then + AC_MSG_RESULT([none]) + result=0 + else + AC_MSG_RESULT([$pmix_cv_asm_file]) + result=1 + fi + + AC_DEFINE_UNQUOTED([PMIX_HAVE_ASM_FILE], [$result], + [Whether there is an atomic assembly file available]) + AM_CONDITIONAL([PMIX_HAVE_ASM_FILE], [test "$result" = "1"]) + + PMIX_ASM_FILE=$pmix_cv_asm_file + AC_SUBST(PMIX_ASM_FILE) +])dnl diff --git a/opal/mca/pmix/pmix2x/pmix/config/pmix_config_pthreads.m4 b/opal/mca/pmix/pmix2x/pmix/config/pmix_config_pthreads.m4 new file mode 100644 index 0000000000..2e2f1fd8f9 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/config/pmix_config_pthreads.m4 @@ -0,0 +1,669 @@ +dnl +dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +dnl University Research and Technology +dnl Corporation. All rights reserved. +dnl Copyright (c) 2004-2005 The University of Tennessee and The University +dnl of Tennessee Research Foundation. All rights +dnl reserved. +dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +dnl University of Stuttgart. All rights reserved. +dnl Copyright (c) 2004-2005 The Regents of the University of California. +dnl All rights reserved. +dnl Copyright (c) 2012 Cisco Systems, Inc. All rights reserved. +dnl Copyright (c) 2014-2017 Intel, Inc. All rights reserved. +dnl Copyright (c) 2014-2016 Research Organization for Information Science +dnl and Technology (RIST). All rights reserved. +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ +dnl +dnl PMIX_CONFIG_POSIX_THREADS() +dnl +dnl Configure posix threads, setting the following variables (but +dnl not calling AC_SUBST on them). + +# ******************************************************************** +# +# Internal macros - do not call from outside PMIX_CONFIG_POSIX_THREADS +# +# ******************************************************************** + + +AC_DEFUN([PMIX_INTL_PTHREAD_TRY_LINK], [ +# BEGIN: PMIX_INTL_PTHREAD_TRY_LINK +# +# Make sure that we can run a small application in C or C++, which +# ever is the current language. Do make sure that C or C++ is the +# current language. +# +# As long as this is not being run.... +# pthread_t may be anything from an int to a struct -- init with self-tid. +# + AC_LINK_IFELSE([AC_LANG_SOURCE([[ +#include + +int i = 3; +pthread_t me, newthread; + +void cleanup_routine(void *foo); +void *thread_main(void *foo); + +void cleanup_routine(void *foo) { i = 4; } +void *thread_main(void *foo) { i = 2; return (void*) &i; } + +int main(int argc, char* argv[]) +{ + pthread_attr_t attr; + + me = pthread_self(); + pthread_atfork(NULL, NULL, NULL); + pthread_attr_init(&attr); + pthread_cleanup_push(cleanup_routine, 0); + pthread_create(&newthread, &attr, thread_main, 0); + pthread_join(newthread, 0); + pthread_cleanup_pop(0); + + return 0; +}]])], + [$1], [$2]) +# END: PMIX_INTL_PTHREAD_TRY_LINK +])dnl + + +AC_DEFUN([PMIX_INTL_PTHREAD_TRY_LINK_FORTRAN], [ +# BEGIN: PMIX_INTL_PTHREAD_TRY_LINK_FORTRAN +# +# Make sure that we can run a small application in Fortran, with +# pthreads living in a C object file + +# Fortran module +cat > conftestf.f < conftest.c < +#include +#include +$pmix_conftest_h + +#ifdef __cplusplus +extern "C" { +#endif +int i = 3; +pthread_t me, newthread; + +void cleanup_routine(void *foo); +void *thread_main(void *foo); +void pthreadtest_f(void); + +void cleanup_routine(void *foo) { i = 4; } +void *thread_main(void *foo) { i = 2; return (void*) &i; } + +void pthreadtest_f(void) +{ + pthread_attr_t attr; + + me = pthread_self(); + pthread_atfork(NULL, NULL, NULL); + pthread_attr_init(&attr); + pthread_cleanup_push(cleanup_routine, 0); + pthread_create(&newthread, &attr, thread_main, 0); + pthread_join(newthread, 0); + pthread_cleanup_pop(0); +} + +void pthreadtest(void) +{ pthreadtest_f(); } + +void pthreadtest_(void) +{ pthreadtest_f(); } + +void pthreadtest__(void) +{ pthreadtest_f(); } + +void PTHREADTEST(void) +{ pthreadtest_f(); } + +#ifdef __cplusplus +} +#endif +EOF + +# Try the compile +PMIX_LOG_COMMAND( + [$CC $CFLAGS -I. -c conftest.c], + PMIX_LOG_COMMAND( + [$FC $FCFLAGS conftestf.f conftest.o -o conftest $LDFLAGS $LIBS], + [HAPPY=1], + [HAPPY=0]), + [HAPPY=0]) + +if test "$HAPPY" = "1"; then + $1 +else + PMIX_LOG_MSG([here is the C program:], 1) + PMIX_LOG_FILE([conftest.c]) + if test -f conftest.h; then + PMIX_LOG_MSG([here is contest.h:], 1) + PMIX_LOG_FILE([conftest.h]) + fi + PMIX_LOG_MSG([here is the fortran program:], 1) + PMIX_LOG_FILE([conftestf.f]) + $2 +fi + +unset HAPPY pmix_conftest_h +rm -rf conftest* +# END: PMIX_INTL_PTHREAD_TRY_LINK_FORTRAN +])dnl + + +# ******************************************************************** +# +# Try to compile thread support without any special flags +# +# ******************************************************************** +AC_DEFUN([PMIX_INTL_POSIX_THREADS_PLAIN_C], [ +# +# C compiler +# +if test "$pmix_pthread_c_success" = "0"; then + AC_MSG_CHECKING([if C compiler and POSIX threads work as is]) + + AC_LANG_PUSH(C) + PMIX_INTL_PTHREAD_TRY_LINK(pmix_pthread_c_success=1, + pmix_pthread_c_success=0) + AC_LANG_POP(C) + if test "$pmix_pthread_c_success" = "1"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi +fi +])dnl + + +AC_DEFUN([PMIX_INTL_POSIX_THREADS_PLAIN_CXX], [ +# +# C++ compiler +# +if test "$pmix_pthread_cxx_success" = "0"; then + AC_MSG_CHECKING([if C++ compiler and POSIX threads work as is]) + + AC_LANG_PUSH(C++) + PMIX_INTL_PTHREAD_TRY_LINK(pmix_pthread_cxx_success=1, + pmix_pthread_cxx_success=0) + AC_LANG_POP(C++) + if test "$pmix_pthread_cxx_success" = "1"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi +fi +])dnl + + +AC_DEFUN([PMIX_INTL_POSIX_THREADS_PLAIN_FC], [ +# +# Fortran compiler +# +if test "$pmix_pthread_fortran_success" = "0" && \ + test "$OMPI_TRY_FORTRAN_BINDINGS" -gt "$OMPI_FORTRAN_NO_BINDINGS" && \ + test $ompi_fortran_happy -eq 1; then + AC_MSG_CHECKING([if Fortran compiler and POSIX threads work as is]) + + AC_LANG_PUSH(C) + PMIX_INTL_PTHREAD_TRY_LINK_FORTRAN(pmix_pthread_fortran_success=1, + pmix_pthread_fortran_success=0) + AC_LANG_POP(C) + if test "$pmix_pthread_fortran_success" = "1"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi +fi +])dnl + + +AC_DEFUN([PMIX_INTL_POSIX_THREADS_PLAIN], [ +# BEGIN: PMIX_INTL_POSIX_THREADS_PLAIN +# +# Check if can compile without any special flags +# we throw -D_REENTRANT or -D_THREAD_SAFE in here, just in +# case. Some systems (OS X, for example) generally don't need +# the defines, but then will on one system header here or there +# why take chances? +# + +# Only run C++ and Fortran if those compilers already configured +AC_PROVIDE_IFELSE([AC_PROG_CC], + [PMIX_INTL_POSIX_THREADS_PLAIN_C], + [pmix_pthread_c_success=1]) + +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [PMIX_INTL_POSIX_THREADS_PLAIN_CXX], + [pmix_pthread_cxx_success=1]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [PMIX_INTL_POSIX_THREADS_PLAIN_FC], + [pmix_pthread_fortran_success=1]) + +# End: PMIX_INTL_POSIX_THREADS_PLAIN +])dnl + + +# ******************************************************************** +# +# Try to compile thread support with special compiler flags +# +# ******************************************************************** +AC_DEFUN([PMIX_INTL_POSIX_THREADS_SPECIAL_FLAGS_C], [ +# +# C compiler +# +if test "$pmix_pthread_c_success" = "0"; then + for pf in $pflags; do + AC_MSG_CHECKING([if C compiler and POSIX threads work with $pf]) + CFLAGS="$orig_CFLAGS $pf" + AC_LANG_PUSH(C) + PMIX_INTL_PTHREAD_TRY_LINK(pmix_pthread_c_success=1, + pmix_pthread_c_success=0) + AC_LANG_POP(C) + if test "$pmix_pthread_c_success" = "1"; then + PTHREAD_CFLAGS="$pf" + AC_MSG_RESULT([yes]) + break + else + PTHREAD_CFLAGS= + CFLAGS="$orig_CFLAGS" + AC_MSG_RESULT([no]) + fi + done +fi +]) + + +AC_DEFUN([PMIX_INTL_POSIX_THREADS_SPECIAL_FLAGS_CXX], [ +# +# C++ compiler +# +if test "$pmix_pthread_cxx_success" = "0"; then + for pf in $pflags; do + AC_MSG_CHECKING([if C++ compiler and POSIX threads work with $pf]) + CXXFLAGS="$orig_CXXFLAGS $pf" + AC_LANG_PUSH(C++) + PMIX_INTL_PTHREAD_TRY_LINK(pmix_pthread_cxx_success=1, + pmix_pthread_cxx_success=0) + AC_LANG_POP(C++) + if test "$pmix_pthread_cxx_success" = "1"; then + PTHREAD_CXXFLAGS="$pf" + AC_MSG_RESULT([yes]) + break + else + PTHREAD_CXXFLAGS= + CXXFLAGS="$orig_CXXFLAGS" + AC_MSG_RESULT([no]) + fi + done +fi +]) + + +AC_DEFUN([PMIX_INTL_POSIX_THREADS_SPECIAL_FLAGS_FC], [ +# +# Fortran compiler +# +if test "$pmix_pthread_fortran_success" = "0" && \ + test "$OMPI_TRY_FORTRAN_BINDINGS" -gt "$OMPI_FORTRAN_NO_BINDINGS" && \ + test $ompi_fortran_happy -eq 1; then + for pf in $pflags; do + AC_MSG_CHECKING([if Fortran compiler and POSIX threads work with $pf]) + FCFLAGS="$orig_FCFLAGS $pf" + AC_LANG_PUSH(C) + PMIX_INTL_PTHREAD_TRY_LINK_FORTRAN(pmix_pthread_fortran_success=1, + pmix_pthread_fortran_success=0) + AC_LANG_POP(C) + if test "$pmix_pthread_fortran_success" = "1"; then + PTHREAD_FCFLAGS="$pf" + AC_MSG_RESULT([yes]) + break + else + PTHREAD_FCFLAGS= + FCFLAGS="$orig_FCFLAGS" + AC_MSG_RESULT([no]) + fi + done +fi +]) + + +AC_DEFUN([PMIX_INTL_POSIX_THREADS_SPECIAL_FLAGS],[ +# Begin: PMIX_INTL_POSIX_THREADS_SPECIAL_FLAGS +# +# If above didn't work, try some super-special compiler flags +# that get evaluated to the "right" things. +# +# -Kthread: +# -kthread: FreeBSD kernel threads +# -pthread: Modern GCC (most all platforms) +# -pthreads: GCC on solaris +# -mthreads: +# -mt: Solaris native compilers / HP-UX aCC +# +# Put -mt before -mthreads because HP-UX aCC will properly compile +# with -mthreads (reading as -mt), but emit a warning about unknown +# flags hreads. Stupid compilers. + +case "${host_cpu}-${host_os}" in + *solaris*) + pflags="-pthread -pthreads -mt" + ;; + *) + pflags="-Kthread -kthread -pthread -pthreads -mt -mthreads" + ;; +esac + +# Only run C++ and Fortran if those compilers already configured +AC_PROVIDE_IFELSE([AC_PROG_CC], + [PMIX_INTL_POSIX_THREADS_SPECIAL_FLAGS_C], + [pmix_pthread_c_success=1]) + +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [PMIX_INTL_POSIX_THREADS_SPECIAL_FLAGS_CXX], + [pmix_pthread_cxx_success=1]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [PMIX_INTL_POSIX_THREADS_SPECIAL_FLAGS_FC], + [pmix_pthread_fortran_success=1]) + +# End: PMIX_INTL_POSIX_THREADS_SPECIAL_FLAGS +])dnl + + +# ******************************************************************** +# +# Try to compile thread support with extra libs +# +# ******************************************************************** +AC_DEFUN([PMIX_INTL_POSIX_THREADS_LIBS_C],[ +# +# C compiler +# +if test "$pmix_pthread_c_success" = "0"; then + for pl in $plibs; do + AC_MSG_CHECKING([if C compiler and POSIX threads work with $pl]) + case "${host_cpu}-${host-_os}" in + *-aix* | *-freebsd*) + if test "`echo $CPPFLAGS | $GREP 'D_THREAD_SAFE'`" = ""; then + PTHREAD_CPPFLAGS="-D_THREAD_SAFE" + CPPFLAGS="$CPPFLAGS $PTHREAD_CPPFLAGS" + fi + ;; + *) + if test "`echo $CPPFLAGS | $GREP 'D_REENTRANT'`" = ""; then + PTHREAD_CPPFLAGS="-D_REENTRANT" + CPPFLAGS="$CPPFLAGS $PTHREAD_CPPFLAGS" + fi + ;; + esac + LIBS="$orig_LIBS $pl" + AC_LANG_PUSH(C) + PMIX_INTL_PTHREAD_TRY_LINK(pmix_pthread_c_success=1, + pmix_pthread_c_success=0) + AC_LANG_POP(C) + if test "$pmix_pthread_c_success" = "1"; then + PTHREAD_LIBS="$pl" + AC_MSG_RESULT([yes]) + else + PTHREAD_CPPFLAGS= + CPPFLAGS="$orig_CPPFLAGS" + LIBS="$orig_LIBS" + AC_MSG_RESULT([no]) + fi + done +fi +])dnl + + +AC_DEFUN([PMIX_INTL_POSIX_THREADS_LIBS_CXX],[ +# +# C++ compiler +# +if test "$pmix_pthread_cxx_success" = "0"; then + if test ! "$pmix_pthread_c_success" = "0" && test ! "$PTHREAD_LIBS" = "" ; then + AC_MSG_CHECKING([if C++ compiler and POSIX threads work with $PTHREAD_LIBS]) + case "${host_cpu}-${host-_os}" in + *-aix* | *-freebsd*) + if test "`echo $CXXCPPFLAGS | $GREP 'D_THREAD_SAFE'`" = ""; then + PTHREAD_CXXCPPFLAGS="-D_THREAD_SAFE" + CXXCPPFLAGS="$CXXCPPFLAGS $PTHREAD_CXXCPPFLAGS" + fi + ;; + *) + if test "`echo $CXXCPPFLAGS | $GREP 'D_REENTRANT'`" = ""; then + PTHREAD_CXXCPPFLAGS="-D_REENTRANT" + CXXCPPFLAGS="$CXXCPPFLAGS $PTHREAD_CXXCPPFLAGS" + fi + ;; + esac + LIBS="$orig_LIBS $PTHREAD_LIBS" + AC_LANG_PUSH(C++) + PMIX_INTL_PTHREAD_TRY_LINK(pmix_pthread_cxx_success=1, + pmix_pthread_cxx_success=0) + AC_LANG_POP(C++) + if test "$pmix_pthread_cxx_success" = "1"; then + AC_MSG_RESULT([yes]) + else + CXXCPPFLAGS="$orig_CXXCPPFLAGS" + LIBS="$orig_LIBS" + AC_MSG_RESULT([no]) + AC_MSG_ERROR([Can not find working threads configuration. aborting]) + fi + else + for pl in $plibs; do + AC_MSG_CHECKING([if C++ compiler and POSIX threads work with $pl]) + case "${host_cpu}-${host-_os}" in + *-aix* | *-freebsd*) + if test "`echo $CXXCPPFLAGS | $GREP 'D_THREAD_SAFE'`" = ""; then + PTHREAD_CXXCPPFLAGS="-D_THREAD_SAFE" + CXXCPPFLAGS="$CXXCPPFLAGS $PTHREAD_CXXCPPFLAGS" + fi + ;; + *) + if test "`echo $CXXCPPFLAGS | $GREP 'D_REENTRANT'`" = ""; then + PTHREAD_CXXCPPFLAGS="-D_REENTRANT" + CXXCPPFLAGS="$CXXCPPFLAGS $PTHREAD_CXXCPPFLAGS" + fi + ;; + esac + LIBS="$orig_LIBS $pl" + AC_LANG_PUSH(C++) + PMIX_INTL_PTHREAD_TRY_LINK(pmix_pthread_cxx_success=1, + pmix_pthread_cxx_success=0) + AC_LANG_POP(C++) + if test "$pmix_pthread_cxx_success" = "1"; then + PTHREAD_LIBS="$pl" + AC_MSG_RESULT([yes]) + else + PTHREAD_CXXCPPFLAGS= + CXXCPPFLAGS="$orig_CXXCPPFLAGS" + LIBS="$orig_LIBS" + AC_MSG_RESULT([no]) + fi + done + fi +fi +])dnl + + +AC_DEFUN([PMIX_INTL_POSIX_THREADS_LIBS_FC],[ +# +# Fortran compiler +# +if test "$pmix_pthread_fortran_success" = "0" && \ + test "$OMPI_TRY_FORTRAN_BINDINGS" -gt "$OMPI_FORTRAN_NO_BINDINGS" && \ + test $ompi_fortran_happy -eq 1; then + if test ! "$pmix_pthread_c_success" = "0" && test ! "$PTHREAD_LIBS" = "" ; then + AC_MSG_CHECKING([if Fortran compiler and POSIX threads work with $PTHREAD_LIBS]) + LIBS="$orig_LIBS $PTHREAD_LIBS" + AC_LANG_PUSH(C) + PMIX_INTL_PTHREAD_TRY_LINK_FORTRAN(pmix_pthread_fortran_success=1, + pmix_pthread_fortran_success=0) + AC_LANG_POP(C) + if test "$pmix_pthread_fortran_success" = "1"; then + AC_MSG_RESULT([yes]) + else + LIBS="$orig_LIBS" + AC_MSG_RESULT([no]) + AC_MSG_ERROR([Can not find working threads configuration. aborting]) + fi + else + for pl in $plibs; do + AC_MSG_CHECKING([if Fortran compiler and POSIX threads work with $pl]) + LIBS="$orig_LIBS $pl" + AC_LANG_PUSH(C) + PMIX_INTL_PTHREAD_TRY_LINK_FORTRAN(pmix_pthread_fortran_success=1, + pmix_pthread_fortran_success=0) + AC_LANG_POP(C) + if test "$pmix_pthread_fortran_success" = "1"; then + PTHREAD_LIBS="$pl" + AC_MSG_RESULT([yes]) + break + else + LIBS="$orig_LIBS" + AC_MSG_RESULT([no]) + fi + done + fi +fi +])dnl + + +AC_DEFUN([PMIX_INTL_POSIX_THREADS_LIBS],[ +# Begin: PMIX_INTL_POSIX_THREADS_LIBS +# +# if we can't find a super-special compiler flags, try some libraries. +# we throw -D_REENTRANT or -D_THREAD_SAFE in here, just in case. Some +# systems (OS X, for example) generally don't need the defines, but +# then will on one system header here or there why take chances? +# +# libpthreads: AIX - must check before libpthread +# liblthread: LinuxThreads on FreeBSD +# libpthread: The usual place (like we can define usual!) +plibs="-lpthreads -llthread -lpthread" + +# Only run C++ and Fortran if those compilers already configured +AC_PROVIDE_IFELSE([AC_PROG_CC], + [PMIX_INTL_POSIX_THREADS_LIBS_C], + [pmix_pthread_c_success=1]) + +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [PMIX_INTL_POSIX_THREADS_LIBS_CXX], + [pmix_pthread_cxx_success=1]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [PMIX_INTL_POSIX_THREADS_LIBS_FC], + [pmix_pthread_fortran_success=1]) + +# End: PMIX_INTL_POSIX_THREADS_LIBS] +)dnl + + +#******************************************************************** +# +# External macro (aka, the real thing) +# +#******************************************************************** +AC_DEFUN([PMIX_CONFIG_POSIX_THREADS],[ + AC_REQUIRE([AC_PROG_GREP]) + +pmix_pthread_c_success=0 +pmix_pthread_cxx_success=0 + +orig_CFLAGS="$CFLAGS" +orig_FCFLAGS="$FCFLAGS" +orig_CXXFLAGS="$CXXFLAGS" +orig_CPPFLAGS="$CPPFLAGS" +orig_CXXCPPFLAGS="$CXXCPPFLAGS" +orig_LDFLAGS="$LDFLAGS" +orig_LIBS="$LIBS" + +PTHREAD_CFLAGS= +PTHREAD_FCFLAGS= +PTHREAD_CXXFLAGS= +PTHREAD_CPPFLAGS= +PTHREAD_CXXCPPFLAGS= +PTHREAD_LDFLAGS= +PTHREAD_LIBS= + +# Try with the basics, mam. +PMIX_INTL_POSIX_THREADS_PLAIN + +# Try the super-special compiler flags. +PMIX_INTL_POSIX_THREADS_SPECIAL_FLAGS + +# Try the normal linking methods (that's no fun) +PMIX_INTL_POSIX_THREADS_LIBS + +# +# check to see if we can create shared memory mutexes and conditions +# +AC_CHECK_FUNCS([pthread_mutexattr_setpshared pthread_condattr_setpshared]) + +# +# check to see if we can set error checking mutexes +# + +# LinuxThreads +AC_MSG_CHECKING([for PTHREAD_MUTEX_ERRORCHECK_NP]) +AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[pthread_mutexattr_settype(NULL, PTHREAD_MUTEX_ERRORCHECK_NP);]])], + [result="yes" defval=1], [result="no" defval=0]) +AC_MSG_RESULT([$result]) +AC_DEFINE_UNQUOTED([PMIX_HAVE_PTHREAD_MUTEX_ERRORCHECK_NP], [$defval], + [If PTHREADS implementation supports PTHREAD_MUTEX_ERRORCHECK_NP]) + +# Mac OS X +AC_MSG_CHECKING([for PTHREAD_MUTEX_ERRORCHECK]) +AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[pthread_mutexattr_settype(NULL, PTHREAD_MUTEX_ERRORCHECK);]])], + [result="yes" defval=1], [result="no" defval=0]) +AC_MSG_RESULT([$result]) +AC_DEFINE_UNQUOTED([PMIX_HAVE_PTHREAD_MUTEX_ERRORCHECK], [$defval], + [If PTHREADS implementation supports PTHREAD_MUTEX_ERRORCHECK]) + +CFLAGS="$orig_CFLAGS" +FCFLAGS="$orig_FCFLAGS" +CXXFLAGS="$orig_CXXFLAGS" +CPPFLAGS="$orig_CPPFLAGS" +CXXCPPFLAGS="$orig_CXXCPPFLAGS" +LDFLAGS="$orig_LDFLAGS" +LIBS="$orig_LIBS" + +if test "$pmix_pthread_c_success" = "1" && \ + test "$pmix_pthread_cxx_success" = "1"; then + internal_useless=1 + $1 +else + internal_useless=1 + $2 +fi + +unset pmix_pthread_c_success pmix_pthread_fortran_success pmix_pthread_cxx_success +unset internal_useless +])dnl diff --git a/opal/mca/pmix/pmix2x/pmix/config/pmix_config_threads.m4 b/opal/mca/pmix/pmix2x/pmix/config/pmix_config_threads.m4 new file mode 100644 index 0000000000..541e63f726 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/config/pmix_config_threads.m4 @@ -0,0 +1,71 @@ +dnl +dnl Copyright (c) 2004-2010 The Trustees of Indiana University and Indiana +dnl University Research and Technology +dnl Corporation. All rights reserved. +dnl Copyright (c) 2004-2005 The University of Tennessee and The University +dnl of Tennessee Research Foundation. All rights +dnl reserved. +dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +dnl University of Stuttgart. All rights reserved. +dnl Copyright (c) 2004-2005 The Regents of the University of California. +dnl All rights reserved. +dnl Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. +dnl Copyright (c) 2009-2011 Oak Ridge National Labs. All rights reserved. +dnl Copyright (c) 2014-2017 Intel, Inc. All rights reserved. +dnl Copyright (c) 2015 Research Organization for Information Science +dnl and Technology (RIST). All rights reserved. +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ +dnl + +AC_DEFUN([PMIX_CONFIG_THREADS],[ +# +# Arguments: none +# +# Dependencies: None +# +# Modifies: +# none - see called tests +# +# configure threads +# + +# +# Check we have POSIX threads +# +PMIX_CONFIG_POSIX_THREADS(HAVE_POSIX_THREADS=1, HAVE_POSIX_THREADS=0) +AC_MSG_CHECKING([for working POSIX threads package]) +if test "$HAVE_POSIX_THREADS" = "1" ; then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi +export HAVE_POSIX_THREADS + +# +# Ask what threading we want (allow posix right now) +# + +if test "$HAVE_POSIX_THREADS" = "0"; then + AC_MSG_WARN(["*** POSIX threads are not"]) + AC_MSG_WARN(["*** available on your system "]) + AC_MSG_ERROR(["*** Can not continue"]) +fi + +THREAD_CFLAGS="$PTHREAD_CFLAGS" +THREAD_FCFLAGS="$PTHREAD_FCFLAGS" +THREAD_CXXFLAGS="$PTHREAD_CXXFLAGS" +THREAD_CPPFLAGS="$PTHREAD_CPPFLAGS" +THREAD_CXXCPPFLAGS="$PTHREAD_CXXCPPFLAGS" +THREAD_LDFLAGS="$PTHREAD_LDFLAGS" +THREAD_LIBS="$PTHREAD_LIBS" + +PMIX_CHECK_PTHREAD_PIDS + +AC_DEFINE_UNQUOTED([PMIX_ENABLE_MULTI_THREADS], [1], + [Whether we should enable thread support within the PMIX code base]) + +])dnl diff --git a/opal/mca/pmix/pmix2x/pmix/config/pmix_try_assemble.m4 b/opal/mca/pmix/pmix2x/pmix/config/pmix_try_assemble.m4 new file mode 100644 index 0000000000..eba8dfd629 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/config/pmix_try_assemble.m4 @@ -0,0 +1,52 @@ +dnl +dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +dnl University Research and Technology +dnl Corporation. All rights reserved. +dnl Copyright (c) 2004-2005 The University of Tennessee and The University +dnl of Tennessee Research Foundation. All rights +dnl reserved. +dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +dnl University of Stuttgart. All rights reserved. +dnl Copyright (c) 2004-2005 The Regents of the University of California. +dnl All rights reserved. +dnl Copyright (c) 2014-2017 Intel, Inc. All rights reserved. +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ +dnl + +dnl PMIX_TRY_ASSEMBLE(asm-code, [action-if-success], [action-if-fail]) +dnl +dnl Attempt to assemble asm-code. If success, run action-if-success. +dnl Otherwise, run action-if-fail. Neither action-if-success nor +dnl action-if-fail are required. +dnl +dnl No preprocessing is guaranteed to be done on asm-code. Some +dnl compilers do not run the preprocessor on assembly files. +dnl +dnl On failure, asm-test.s will be included in config.out +AC_DEFUN([PMIX_TRY_ASSEMBLE], +[cat >conftest.s <&AC_FD_CC + ifelse([$2],,:,[$2]) +else + # save compiler output and failed program + cat conftest.out >&AC_FD_CC + echo "configure: failed program was:" >&AC_FD_CC + cat conftest.s >&AC_FD_CC + ifelse([$3],,:,[$3]) +fi +rm -rf conftest* +unset pmix_assemble +])dnl diff --git a/opal/mca/pmix/pmix2x/pmix/include/Makefile.am b/opal/mca/pmix/pmix2x/pmix/include/Makefile.am index 52ad624c51..35bcf6d78c 100644 --- a/opal/mca/pmix/pmix2x/pmix/include/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/include/Makefile.am @@ -17,7 +17,7 @@ include_HEADERS = \ pmix_server.h \ pmix_tool.h -if WANT_PMIX_BACKWARD +if WANT_PMI_BACKWARD include_HEADERS += \ pmi.h \ pmi2.h diff --git a/opal/mca/pmix/pmix2x/pmix/src/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/Makefile.am index e70a8a39d5..6337039084 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/src/Makefile.am @@ -24,6 +24,7 @@ ACLOCAL_AMFLAGS = -I ./config SUBDIRS = \ + atomics/asm \ util/keyval \ mca/base \ $(MCA_pmix_FRAMEWORKS_SUBDIRS) \ @@ -32,6 +33,7 @@ SUBDIRS = \ $(MCA_pmix_FRAMEWORK_COMPONENT_DSO_SUBDIRS) DIST_SUBDIRS = \ + atomics/asm \ util/keyval \ mca/base \ $(MCA_pmix_FRAMEWORKS_SUBDIRS) \ @@ -52,7 +54,6 @@ if PMIX_EMBEDDED_MODE if WANT_INSTALL_HEADERS -# retain output of pmix library lib_LTLIBRARIES = libpmix.la libpmix_la_SOURCES = $(headers) $(sources) libpmix_la_LDFLAGS = -version-info $(libpmix_so_version) @@ -73,6 +74,8 @@ libpmix_la_LDFLAGS = -version-info $(libpmix_so_version) endif !PMIX_EMBEDDED_MODE +include atomics/sys/Makefile.include +include threads/Makefile.include include class/Makefile.include include event/Makefile.include include include/Makefile.include diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/Makefile.am b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/Makefile.am new file mode 100644 index 0000000000..4aee801de8 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/Makefile.am @@ -0,0 +1,92 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2011-2014 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2017 Research Organization for Information Science +# and Technology (RIST). All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +###################################################################### +# +# This is a bit complicated. If there is anything in the library, +# it will always be atomic-asm.S. We just symlink atomic-asm.S to +# the best atomic operations available (as determined at configure +# time) +# +###################################################################### +generated/@PMIX_ASM_FILE@: base/@PMIX_ASSEMBLY_ARCH@.asm + @ if test ! -f "$(top_srcdir)/src/atomics/asm/$@" ; then \ + cmd="$(PERL) '$(top_srcdir)/src/atomics/asm/generate-asm.pl' '@PMIX_ASSEMBLY_ARCH@' '@PMIX_ASSEMBLY_FORMAT@' '$(top_srcdir)/src/atomics/asm/base' '$(top_builddir)/src/atomics/asm/generated/@PMIX_ASM_FILE@'" ; \ + echo "$$cmd" ; \ + eval $$cmd ; \ + fi + +atomic-asm.S: generated/@PMIX_ASM_FILE@ + rm -f atomic-asm.S + @ if test -f "$(top_builddir)/src/atomics/asm/generated/@PMIX_ASM_FILE@" ; then \ + cmd="ln -s \"$(top_builddir)/src/atomics/asm/generated/@PMIX_ASM_FILE@\" atomic-asm.S" ; \ + echo "$$cmd" ; \ + eval $$cmd ; \ + else \ + cmd="ln -s \"$(top_srcdir)/src/atomics/asm/generated/@PMIX_ASM_FILE@\" atomic-asm.S" ; \ + echo "$$cmd" ; \ + eval $$cmd ; \ + fi + +if PMIX_HAVE_ASM_FILE +nodist_libasm_la_SOURCES = atomic-asm.S +libasm_la_DEPENDENCIES = generated/@PMIX_ASM_FILE@ +else +nodist_libasm_la_SOURCES = +libasm_la_DEPENDENCIES = +endif + +noinst_LTLIBRARIES = libasm.la +dist_libasm_la_SOURCES = asm.c + +EXTRA_DIST = \ + asm-data.txt \ + generate-asm.pl \ + generate-all-asm.pl \ + base/aix.conf \ + base/default.conf \ + base/X86_64.asm \ + base/ARM.asm \ + base/IA32.asm \ + base/IA64.asm \ + base/MIPS.asm \ + base/POWERPC32.asm \ + base/POWERPC64.asm \ + base/SPARCV9_32.asm \ + base/SPARCV9_64.asm + +###################################################################### + +clean-local: + rm -f atomic-asm.S + +distclean-local: + rm -f generated/atomic-local.s + +###################################################################### + +# +# Copy over all the generated files +# +dist-hook: + mkdir "${distdir}/generated" + $(PERL) "$(top_srcdir)/src/atomics/asm/generate-all-asm.pl" "$(PERL)" "$(srcdir)" "$(distdir)" diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/asm-data.txt b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/asm-data.txt new file mode 100644 index 0000000000..55360354fb --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/asm-data.txt @@ -0,0 +1,133 @@ +# -*- sh -*- +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2014-2017 Intel, Inc. All rights reserved. +# Copyright (c) 2017 Research Organization for Information Science +# and Technology (RIST). All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# +# Database for mapping architecture and assembly format to prebuilt +# assembly files. For explination of the assembly operations, see +# the inline assembly header files in src/include/sys/. +# +# FORMAT: +# ARCHITECTURE ASSEMBLY FORMAT BASE FILENAME +# +# Assembly Format field: +# config_file-text-global-label_suffix-gsym-lsym-type-size-align_log-ppc_r_reg-64_bit-gnu_stack + +###################################################################### +# +# AMD Opteron / Intel EM64T +# +###################################################################### + +X86_64 default-.text-.globl-:--.L-@-1-0-1-1-1 x86_64-linux +X86_64 default-.text-.globl-:--.L-@-1-0-1-1-0 x86_64-linux-nongas + + +###################################################################### +# +# ARM (ARMv7 and later) +# +###################################################################### + +ARM default-.text-.globl-:--.L-#-1-1-1-1-1 arm-linux + + +###################################################################### +# +# Intel Pentium Class +# +###################################################################### + +IA32 default-.text-.globl-:--.L-@-1-0-1-1-1 ia32-linux +IA32 default-.text-.globl-:--.L-@-1-0-1-1-0 ia32-linux-nongas +IA32 default-.text-.globl-:-_-L--0-1-1-1-0 ia32-osx +IA32 default-.text-.globl-:-_-L--0-0-1-1-1 ia32-cygwin +IA32 default-.text-.globl-:-_-L--0-0-1-1-0 ia32-cygwin-nongas + + +###################################################################### +# +# IA64 (Intel Itanium) +# +###################################################################### + +IA64 default-.text-.globl-:--.L-@-1-0-1-1-1 ia64-linux +IA64 default-.text-.globl-:--.L-@-1-0-1-1-0 ia64-linux-nongas + + +###################################################################### +# +# PowerPC / POWER +# +###################################################################### + +# standard ppc instruction set (AIX calls it ppc). This is not the +# true intersection of all the POWER / PowerPC machines, but works +# on PowerPCs since the 601 and on at least POWER 3 and above. +POWERPC32 default-.text-.globl-:-_-L--0-1-1-0-0 powerpc32-osx +POWERPC32 default-.text-.globl-:--.L-@-1-1-0-0-1 powerpc32-linux +POWERPC32 default-.text-.globl-:--.L-@-1-1-0-0-0 powerpc32-linux-nongas +POWERPC32 aix-.csect .text[PR]-.globl-:-.-L--0-1-0-0-0 powerpc32-aix + +# The ppc code above, plus support for the 64 bit operations. This +# mode is really only available on OS X when using the OS X 10.3 +# compiler chain with the -mcpu=970 option. +POWERPC32 default-.text-.globl-:-_-L--0-1-1-1-0 powerpc32-64-osx + +# PowerPC / POWER 64bit machines. sizeof(void*) == 8. +POWERPC64 default-.text-.globl-:-_-L--0-1-1-1-0 powerpc64-osx +POWERPC64 default-.text-.globl-:-.-.L-@-1-1-0-1-1 powerpc64-linux +POWERPC64 default-.text-.globl-:-.-.L-@-1-1-0-1-0 powerpc64-linux-nongas +POWERPC64 aix-.csect .text[PR]-.globl-:-.-L--0-1-0-1-0 powerpc64-aix + + +###################################################################### +# +# SPARC / UltraSPARC (Scalalable Processor ARChitecture) +# +###################################################################### + +# Usually compiled with -xarch=v8plus. Basically Sparc V9, but with +# sizeof(void*) == 4 instead of 8. Different from V9_64 because still +# uses 2 registers to pass in a 64bit integer +SPARCV9_32 default-.text-.globl-:--.L-#-1-0-1-1-0 sparcv9-32-solaris + +# The Sparc v9 (aka Ultra Sparc). Sizeof(void*) == 8. +SPARCV9_64 default-.text-.globl-:--.L-#-1-0-1-1-0 sparcv9-64-solaris + + +###################################################################### +# +# MIPS III (Microprocessor without Interlocked Pipeline Stages) +# R4000 and above +# +###################################################################### + +# So MIPS, in it's infinite wisdom (thank you!) decided that when +# compiling in 32bit mode and passing in a 64bit integer, it is done +# in one register (instead of SPARC and POWER, who use two). Which +# means that we can use the same code either way. Woo hoo! + +MIPS default-.text-.globl-:--L--1-1-1-1-0 mips-irix +MIPS default-.text-.globl-:--L--1-1-1-1-0 mips64el +MIPS default-.text-.globl-:--L-@-1-1-1-1-1 mips64-linux + +# However, this doesn't hold true for 32-bit MIPS as used on Linux. +MIPS default-.text-.globl-:--L-@-1-1-1-0-1 mips-linux diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/asm.c b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/asm.c new file mode 100644 index 0000000000..e2d4deabe7 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/asm.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "pmix_config.h" + +#include "src/atomics/sys/atomic.h" +#include "src/atomics/sys/architecture.h" + +#if PMIX_ASSEMBLY_ARCH == PMIX_SPARC + +#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 pmix_atomic_lock_t locks_table[LOCKS_TABLE_SIZE] = { + { { PMIX_ATOMIC_UNLOCKED } }, + { { PMIX_ATOMIC_UNLOCKED } }, + { { PMIX_ATOMIC_UNLOCKED } }, + { { PMIX_ATOMIC_UNLOCKED } }, + { { PMIX_ATOMIC_UNLOCKED } }, + { { PMIX_ATOMIC_UNLOCKED } }, + { { PMIX_ATOMIC_UNLOCKED } }, + { { PMIX_ATOMIC_UNLOCKED } } +}; + + +int32_t +pmix_atomic_add_32(volatile int32_t *addr, int delta) +{ + int32_t ret; + + pmix_atomic_lock(FIND_LOCK(addr)); + + ret = (*addr += delta); + + pmix_atomic_unlock(FIND_LOCK(addr)); + + return ret; +} + + +int32_t +pmix_atomic_sub_32(volatile int32_t *addr, int delta) +{ + int32_t ret; + + pmix_atomic_lock(FIND_LOCK(addr)); + + ret = (*addr -= delta); + + pmix_atomic_unlock(FIND_LOCK(addr)); + + return ret; +} + + +#endif /* PMIX_ASSEMBLY_ARCH == PMIX_SPARC32 */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/ARM.asm b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/ARM.asm new file mode 100644 index 0000000000..e3720299f7 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/ARM.asm @@ -0,0 +1,153 @@ +START_FILE + TEXT + + ALIGN(4) +START_FUNC(pmix_atomic_mb) + dmb + bx lr +END_FUNC(pmix_atomic_mb) + + +START_FUNC(pmix_atomic_rmb) + dmb + bx lr +END_FUNC(pmix_atomic_rmb) + + +START_FUNC(pmix_atomic_wmb) + dmb + bx lr +END_FUNC(pmix_atomic_wmb) + + +START_FUNC(pmix_atomic_cmpset_32) + LSYM(1) + ldrex r3, [r0] + cmp r1, r3 + bne REFLSYM(2) + strex r12, r2, [r0] + cmp r12, #0 + bne REFLSYM(1) + mov r0, #1 + LSYM(2) + movne r0, #0 + bx lr +END_FUNC(pmix_atomic_cmpset_32) + + +START_FUNC(pmix_atomic_cmpset_acq_32) + LSYM(3) + ldrex r3, [r0] + cmp r1, r3 + bne REFLSYM(4) + strex r12, r2, [r0] + cmp r12, #0 + bne REFLSYM(3) + dmb + mov r0, #1 + LSYM(4) + movne r0, #0 + bx lr +END_FUNC(pmix_atomic_cmpset_acq_32) + + +START_FUNC(pmix_atomic_cmpset_rel_32) + LSYM(5) + ldrex r3, [r0] + cmp r1, r3 + bne REFLSYM(6) + dmb + strex r12, r2, [r0] + cmp r12, #0 + bne REFLSYM(4) + mov r0, #1 + LSYM(6) + movne r0, #0 + bx lr +END_FUNC(pmix_atomic_cmpset_rel_32) + +#START_64BIT +START_FUNC(pmix_atomic_cmpset_64) + push {r4-r7} + ldrd r6, r7, [sp, #16] + LSYM(7) + ldrexd r4, r5, [r0] + cmp r4, r2 + it eq + cmpeq r5, r3 + bne REFLSYM(8) + strexd r1, r6, r7, [r0] + cmp r1, #0 + bne REFLSYM(7) + mov r0, #1 + LSYM(8) + movne r0, #0 + pop {r4-r7} + bx lr +END_FUNC(pmix_atomic_cmpset_64) + +START_FUNC(pmix_atomic_cmpset_acq_64) + push {r4-r7} + ldrd r6, r7, [sp, #16] + LSYM(9) + ldrexd r4, r5, [r0] + cmp r4, r2 + it eq + cmpeq r5, r3 + bne REFLSYM(10) + strexd r1, r6, r7, [r0] + cmp r1, #0 + bne REFLSYM(9) + dmb + mov r0, #1 + LSYM(10) + movne r0, #0 + pop {r4-r7} + bx lr +END_FUNC(pmix_atomic_cmpset_acq_64) + + +START_FUNC(pmix_atomic_cmpset_rel_64) + push {r4-r7} + ldrd r6, r7, [sp, #16] + LSYM(11) + ldrexd r4, r5, [r0] + cmp r4, r2 + it eq + cmpeq r5, r3 + bne REFLSYM(12) + dmb + strexd r1, r6, r7, [r0] + cmp r1, #0 + bne REFLSYM(11) + mov r0, #1 + LSYM(12) + movne r0, #0 + pop {r4-r7} + bx lr +END_FUNC(pmix_atomic_cmpset_rel_64) +#END_64BIT + + +START_FUNC(pmix_atomic_add_32) + LSYM(13) + ldrex r2, [r0] + add r2, r2, r1 + strex r3, r2, [r0] + cmp r3, #0 + bne REFLSYM(13) + mov r0, r2 + bx lr +END_FUNC(pmix_atomic_add_32) + + +START_FUNC(pmix_atomic_sub_32) + LSYM(14) + ldrex r2, [r0] + sub r2, r2, r1 + strex r3, r2, [r0] + cmp r3, #0 + bne REFLSYM(14) + mov r0, r2 + bx lr +END_FUNC(pmix_atomic_sub_32) diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/IA32.asm b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/IA32.asm new file mode 100644 index 0000000000..d145aa237e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/IA32.asm @@ -0,0 +1,110 @@ +START_FILE + TEXT + +START_FUNC(pmix_atomic_mb) + pushl %ebp + movl %esp, %ebp + leave + ret +END_FUNC(pmix_atomic_mb) + + +START_FUNC(pmix_atomic_rmb) + pushl %ebp + movl %esp, %ebp + leave + ret +END_FUNC(pmix_atomic_rmb) + + +START_FUNC(pmix_atomic_wmb) + pushl %ebp + movl %esp, %ebp + leave + ret +END_FUNC(pmix_atomic_wmb) + + +START_FUNC(pmix_atomic_cmpset_32) + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %edx + movl 16(%ebp), %ecx + movl 12(%ebp), %eax + lock; cmpxchgl %ecx,(%edx) + sete %dl + + movzbl %dl, %eax + leave + ret +END_FUNC(pmix_atomic_cmpset_32) + + +START_FUNC(pmix_atomic_cmpset_64) + pushl %ebp + movl %esp, %ebp + subl $32, %esp + movl %ebx, -12(%ebp) + movl %esi, -8(%ebp) + movl %edi, -4(%ebp) + movl 8(%ebp), %edi + movl 12(%ebp), %eax + movl 16(%ebp), %edx + movl %eax, -24(%ebp) + movl %edx, -20(%ebp) + movl 20(%ebp), %eax + movl 24(%ebp), %edx + movl %eax, -32(%ebp) + movl %edx, -28(%ebp) + movl -24(%ebp), %ebx + movl -20(%ebp), %edx + movl -32(%ebp), %esi + movl -28(%ebp), %ecx + movl %ebx, %eax + push %ebx + movl %esi, %ebx + lock; cmpxchg8b (%edi) + sete %dl + pop %ebx + + movzbl %dl, %eax + movl -12(%ebp), %ebx + movl -8(%ebp), %esi + movl -4(%ebp), %edi + movl %ebp, %esp + popl %ebp + ret +END_FUNC(pmix_atomic_cmpset_64) + + +START_FUNC(pmix_atomic_add_32) + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %eax + movl 12(%ebp), %edx + lock; addl %edx,(%eax) + movl (%eax), %eax + leave + ret +END_FUNC(pmix_atomic_add_32) + + +START_FUNC(pmix_atomic_sub_32) + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %eax + movl 12(%ebp), %edx + lock; subl %edx,(%eax) + movl (%eax), %eax + leave + ret +END_FUNC(pmix_atomic_sub_32) + + +START_FUNC(pmix_sys_timer_get_cycles) + pushl %ebp + movl %esp, %ebp + rdtsc + popl %ebp + ret +END_FUNC(pmix_sys_timer_get_cycles) diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/IA64.asm b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/IA64.asm new file mode 100644 index 0000000000..a7287a8ffc --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/IA64.asm @@ -0,0 +1,109 @@ +START_FILE + + .pred.safe_across_calls p1-p5,p16-p63 + .text + .align 16 + .global pmix_atomic_mb# + .proc pmix_atomic_mb# +pmix_atomic_mb: + .prologue + .body + mf + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_mb# + .align 16 + .global pmix_atomic_rmb# + .proc pmix_atomic_rmb# +pmix_atomic_rmb: + .prologue + .body + mf + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_rmb# + .align 16 + .global pmix_atomic_wmb# + .proc pmix_atomic_wmb# +pmix_atomic_wmb: + .prologue + .body + mf + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_wmb# + .align 16 + .global pmix_atomic_cmpset_acq_32# + .proc pmix_atomic_cmpset_acq_32# +pmix_atomic_cmpset_acq_32: + .prologue + .body + mov ar.ccv=r33;; + cmpxchg4.acq r32=[r32],r34,ar.ccv + ;; + cmp4.eq p6, p7 = r32, r33 + ;; + (p6) addl r8 = 1, r0 + (p7) mov r8 = r0 + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_cmpset_acq_32# + .align 16 + .global pmix_atomic_cmpset_rel_32# + .proc pmix_atomic_cmpset_rel_32# +pmix_atomic_cmpset_rel_32: + .prologue + .body + mov ar.ccv=r33;; + cmpxchg4.rel r32=[r32],r34,ar.ccv + ;; + cmp4.eq p6, p7 = r32, r33 + ;; + (p6) addl r8 = 1, r0 + (p7) mov r8 = r0 + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_cmpset_rel_32# + .align 16 + .global pmix_atomic_cmpset_acq_64# + .proc pmix_atomic_cmpset_acq_64# +pmix_atomic_cmpset_acq_64: + .prologue + .body + mov ar.ccv=r33;; + cmpxchg8.acq r32=[r32],r34,ar.ccv + ;; + cmp.eq p6, p7 = r33, r32 + ;; + (p6) addl r8 = 1, r0 + (p7) mov r8 = r0 + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_cmpset_acq_64# + .align 16 + .global pmix_atomic_cmpset_rel_64# + .proc pmix_atomic_cmpset_rel_64# +pmix_atomic_cmpset_rel_64: + .prologue + .body + mov ar.ccv=r33;; + cmpxchg8.rel r32=[r32],r34,ar.ccv + ;; + cmp.eq p6, p7 = r33, r32 + ;; + (p6) addl r8 = 1, r0 + (p7) mov r8 = r0 + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_cmpset_rel_64# + .align 16 + .global pmix_sys_timer_get_cycles# + .proc pmix_sys_timer_get_cycles# +pmix_sys_timer_get_cycles: + .prologue + .body + mov r8=ar.itc + br.ret.sptk.many b0 + ;; + .endp pmix_sys_timer_get_cycles# + .ident "GCC: (GNU) 3.2.3 20030502 (Red Hat Linux 3.2.3-49)" diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/MIPS.asm b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/MIPS.asm new file mode 100644 index 0000000000..a30ac9f9b5 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/MIPS.asm @@ -0,0 +1,196 @@ +START_FILE + +#ifdef __linux__ +#include +#else +#include +#endif +#include + + TEXT + + ALIGN(8) +LEAF(pmix_atomic_mb) +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + j ra +END(pmix_atomic_mb) + + + ALIGN(8) +LEAF(pmix_atomic_rmb) +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + j ra +END(pmix_atomic_rmb) + + +LEAF(pmix_atomic_wmb) +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + j ra +END(pmix_atomic_wmb) + + +LEAF(pmix_atomic_cmpset_32) + .set noreorder +retry1: +#ifdef __linux__ + .set mips2 +#endif + ll $3, 0($4) +#ifdef __linux__ + .set mips0 +#endif + bne $3, $5, done1 + or $2, $6, 0 +#ifdef __linux__ + .set mips2 +#endif + sc $2, 0($4) +#ifdef __linux__ + .set mips0 +#endif + beqz $2, retry1 +done1: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_32) + + +LEAF(pmix_atomic_cmpset_acq_32) + .set noreorder +retry2: +#ifdef __linux__ + .set mips2 +#endif + ll $3, 0($4) +#ifdef __linux__ + .set mips0 +#endif + bne $3, $5, done2 + or $2, $6, 0 +#ifdef __linux__ + .set mips2 +#endif + sc $2, 0($4) +#ifdef __linux__ + .set mips0 +#endif + beqz $2, retry2 +done2: +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_acq_32) + + +LEAF(pmix_atomic_cmpset_rel_32) + .set noreorder +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif +retry3: +#ifdef __linux__ + .set mips2 +#endif + ll $3, 0($4) +#ifdef __linux__ + .set mips0 +#endif + bne $3, $5, done3 + or $2, $6, 0 +#ifdef __linux__ + .set mips2 +#endif + sc $2, 0($4) +#ifdef __linux__ + .set mips0 +#endif + beqz $2, retry3 +done3: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_rel_32) + +#ifdef __mips64 +LEAF(pmix_atomic_cmpset_64) + .set noreorder +retry4: + lld $3, 0($4) + bne $3, $5, done4 + or $2, $6, 0 + scd $2, 0($4) + beqz $2, retry4 +done4: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_64) + + +LEAF(pmix_atomic_cmpset_acq_64) + .set noreorder +retry5: + lld $3, 0($4) + bne $3, $5, done5 + or $2, $6, 0 + scd $2, 0($4) + beqz $2, retry5 +done5: + sync + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_acq_64) + + +LEAF(pmix_atomic_cmpset_rel_64) + .set noreorder + sync +retry6: + lld $3, 0($4) + bne $3, $5, done6 + or $2, $6, 0 + scd $2, 0($4) + beqz $2, retry6 +done6: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_rel_64) +#endif /* __mips64 */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/POWERPC32.asm b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/POWERPC32.asm new file mode 100644 index 0000000000..f341367806 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/POWERPC32.asm @@ -0,0 +1,168 @@ +START_FILE + TEXT + + ALIGN(4) +START_FUNC(pmix_atomic_mb) + sync + blr +END_FUNC(pmix_atomic_mb) + + +START_FUNC(pmix_atomic_rmb) + lwsync + blr +END_FUNC(pmix_atomic_rmb) + + +START_FUNC(pmix_atomic_wmb) + eieio + blr +END_FUNC(pmix_atomic_wmb) + + +START_FUNC(pmix_atomic_cmpset_32) + LSYM(1) lwarx r0, 0, r3 + cmpw 0, r0, r4 + bne- REFLSYM(2) + stwcx. r5, 0, r3 + bne- REFLSYM(1) + LSYM(2) + xor r3,r0,r4 + subfic r5,r3,0 + adde r3,r5,r3 + blr +END_FUNC(pmix_atomic_cmpset_32) + + +START_FUNC(pmix_atomic_cmpset_acq_32) + LSYM(3) lwarx r0, 0, r3 + cmpw 0, r0, r4 + bne- REFLSYM(4) + stwcx. r5, 0, r3 + bne- REFLSYM(3) + sync + LSYM(4) + xor r3,r0,r4 + subfic r5,r3,0 + adde r3,r5,r3 + lwsync + blr +END_FUNC(pmix_atomic_cmpset_acq_32) + + +START_FUNC(pmix_atomic_cmpset_rel_32) + eieio + LSYM(5) lwarx r0, 0, r3 + cmpw 0, r0, r4 + bne- REFLSYM(6) + stwcx. r5, 0, r3 + bne- REFLSYM(5) + sync + LSYM(6) + xor r3,r0,r4 + subfic r5,r3,0 + adde r3,r5,r3 + blr +END_FUNC(pmix_atomic_cmpset_rel_32) + +#START_64BIT +START_FUNC(pmix_atomic_cmpset_64) + stw r4,-32(r1) + stw r5,-28(r1) + stw r6,-24(r1) + stw r7,-20(r1) + ld r5,-32(r1) + ld r7,-24(r1) + LSYM(7) ldarx r9, 0, r3 + cmpd 0, r9, r5 + bne- REFLSYM(8) + stdcx. r7, 0, r3 + bne- REFLSYM(7) + LSYM(8) + xor r3,r5,r9 + subfic r5,r3,0 + adde r3,r5,r3 + blr +END_FUNC(pmix_atomic_cmpset_64) + + +START_FUNC(pmix_atomic_cmpset_acq_64) + stw r4,-32(r1) + stw r5,-28(r1) + stw r6,-24(r1) + stw r7,-20(r1) + ld r5,-32(r1) + ld r7,-24(r1) + + LSYM(9) ldarx r9, 0, r3 + cmpd 0, r9, r5 + bne- REFLSYM(10) + stdcx. r7, 0, r3 + bne- REFLSYM(9) + LSYM(10) + xor r3,r5,r9 + subfic r5,r3,0 + adde r3,r5,r3 + blr + lwsync + blr +END_FUNC(pmix_atomic_cmpset_acq_64) + + +START_FUNC(pmix_atomic_cmpset_rel_64) + stw r4,-32(r1) + stw r5,-28(r1) + stw r6,-24(r1) + stw r7,-20(r1) + ld r5,-32(r1) + ld r7,-24(r1) + + eieio + LSYM(11) ldarx r9, 0, r3 + cmpd 0, r9, r5 + bne- REFLSYM(12) + stdcx. r7, 0, r3 + bne- REFLSYM(11) + LSYM(12) + xor r3,r5,r9 + subfic r5,r3,0 + adde r3,r5,r3 + blr + lwsync + blr +END_FUNC(pmix_atomic_cmpset_rel_64) +#END_64BIT + + +START_FUNC(pmix_atomic_add_32) + LSYM(13) lwarx r0, 0, r3 + add r0, r4, r0 + stwcx. r0, 0, r3 + bne- REFLSYM(13) + mr r3,r0 + blr +END_FUNC(pmix_atomic_add_32) + + +START_FUNC(pmix_atomic_sub_32) + LSYM(14) lwarx r0,0,r3 + subf r0,r4,r0 + stwcx. r0,0,r3 + bne- REFLSYM(14) + mr r3,r0 + blr +END_FUNC(pmix_atomic_sub_32) + +START_FUNC(pmix_sys_timer_get_cycles) + LSYM(15) + mftbu r0 + mftb r11 + mftbu r2 + cmpw cr7,r2,r0 + bne+ cr7,REFLSYM(15) + li r4,0 + li r9,0 + or r3,r2,r9 + or r4,r4,r11 + blr +END_FUNC(pmix_sys_timer_get_cycles) diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/POWERPC64.asm b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/POWERPC64.asm new file mode 100644 index 0000000000..6fc4ad717c --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/POWERPC64.asm @@ -0,0 +1,157 @@ +START_FILE + TEXT + + ALIGN(4) +START_FUNC(pmix_atomic_mb) + sync + blr +END_FUNC(pmix_atomic_mb) + + +START_FUNC(pmix_atomic_rmb) + lwsync + blr +END_FUNC(pmix_atomic_rmb) + + +START_FUNC(pmix_atomic_wmb) + eieio + blr +END_FUNC(pmix_atomic_wmb) + + +START_FUNC(pmix_atomic_cmpset_32) + LSYM(1) lwarx r0, 0, r3 + cmpw 0, r0, r4 + bne- REFLSYM(2) + stwcx. r5, 0, r3 + bne- REFLSYM(1) + LSYM(2) + cmpw cr7,r0,r4 + mfcr r3 + rlwinm r3,r3,31,1 + blr +END_FUNC(pmix_atomic_cmpset_32) + + +START_FUNC(pmix_atomic_cmpset_acq_32) + mflr r0 + std r29,-24(r1) + std r0,16(r1) + stdu r1,-144(r1) + bl REFGSYM(pmix_atomic_cmpset_32) + mr r29,r3 + bl REFGSYM(pmix_atomic_rmb) + mr r3,r29 + addi r1,r1,144 + ld r0,16(r1) + mtlr r0 + ld r29,-24(r1) + blr +END_FUNC(pmix_atomic_cmpset_acq_32) + + +START_FUNC(pmix_atomic_cmpset_rel_32) + mflr r0 + std r27,-40(r1) + std r28,-32(r1) + std r29,-24(r1) + std r0,16(r1) + stdu r1,-160(r1) + mr r29,r3 + mr r28,r4 + mr r27,r5 + bl REFGSYM(pmix_atomic_wmb) + mr r3,r29 + mr r4,r28 + mr r5,r27 + bl REFGSYM(pmix_atomic_cmpset_32) + addi r1,r1,160 + ld r0,16(r1) + mtlr r0 + ld r27,-40(r1) + ld r28,-32(r1) + ld r29,-24(r1) + blr +END_FUNC(pmix_atomic_cmpset_rel_32) + + +START_FUNC(pmix_atomic_cmpset_64) + LSYM(3) ldarx r0, 0, r3 + cmpd 0, r0, r4 + bne- REFLSYM(4) + stdcx. r5, 0, r3 + bne- REFLSYM(3) + LSYM(4) + xor r3,r4,r0 + subfic r5,r3,0 + adde r3,r5,r3 + blr +END_FUNC(pmix_atomic_cmpset_64) + + +START_FUNC(pmix_atomic_cmpset_acq_64) + LSYM(7) ldarx r0, 0, r3 + cmpd 0, r0, r4 + bne- REFLSYM(8) + stdcx. r5, 0, r3 + bne- REFLSYM(7) + LSYM(8) + lwsync + xor r3,r4,r0 + subfic r5,r3,0 + adde r3,r5,r3 + blr +END_FUNC(pmix_atomic_cmpset_acq_64) + + +START_FUNC(pmix_atomic_cmpset_rel_64) + eieio + LSYM(9) ldarx r0, 0, r3 + cmpd 0, r0, r4 + bne- REFLSYM(10) + stdcx. r5, 0, r3 + bne- REFLSYM(9) + LSYM(10) + xor r3,r4,r0 + subfic r5,r3,0 + adde r3,r5,r3 + blr +END_FUNC(pmix_atomic_cmpset_rel_64) + + +START_FUNC(pmix_atomic_add_32) + LSYM(5) lwarx r0, 0, r3 + add r0, r4, r0 + stwcx. r0, 0, r3 + bne- REFLSYM(5) + + mr r3,r0 + blr +END_FUNC(pmix_atomic_add_32) + + +START_FUNC(pmix_atomic_sub_32) + LSYM(6) lwarx r0,0,r3 + subf r0,r4,r0 + stwcx. r0,0,r3 + bne- REFLSYM(6) + + mr r3,r0 + blr +END_FUNC(pmix_atomic_sub_32) + +START_FUNC(pmix_sys_timer_get_cycles) + LSYM(11) + mftbu r2 + rldicl r2,r2,0,32 + mftb r0 + rldicl r9,r0,0,32 + mftbu r0 + rldicl r0,r0,0,32 + cmpw cr7,r0,r2 + bne cr7,REFLSYM(11) + sldi r3,r0,32 + or r3,r3,r9 + blr +END_FUNC(pmix_sys_timer_get_cycles) diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/SPARCV9_32.asm b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/SPARCV9_32.asm new file mode 100644 index 0000000000..1ec34125a0 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/SPARCV9_32.asm @@ -0,0 +1,171 @@ +START_FILE + TEXT + + ALIGN(4) + + +START_FUNC(pmix_atomic_mb) + !#PROLOGUE# 0 + !#PROLOGUE# 1 + membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad + retl + nop +END_FUNC(pmix_atomic_mb) + + +START_FUNC(pmix_atomic_rmb) + !#PROLOGUE# 0 + !#PROLOGUE# 1 + membar #LoadLoad + retl + nop +END_FUNC(pmix_atomic_rmb) + + +START_FUNC(pmix_atomic_wmb) + !#PROLOGUE# 0 + !#PROLOGUE# 1 + membar #StoreStore + retl + nop +END_FUNC(pmix_atomic_wmb) + + +START_FUNC(pmix_atomic_cmpset_32) + !#PROLOGUE# 0 + !#PROLOGUE# 1 + casa [%o0] 0x80, %o1, %o2 + xor %o2, %o1, %o2 + subcc %g0, %o2, %g0 + retl + subx %g0, -1, %o0 +END_FUNC(pmix_atomic_cmpset_32) + + +START_FUNC(pmix_atomic_cmpset_acq_32) + !#PROLOGUE# 0 + !#PROLOGUE# 1 + casa [%o0] 0x80, %o1, %o2 + xor %o2, %o1, %o2 + subcc %g0, %o2, %g0 + subx %g0, -1, %o0 + membar #LoadLoad + retl + sra %o0, 0, %o0 +END_FUNC(pmix_atomic_cmpset_acq_32) + + +START_FUNC(pmix_atomic_cmpset_rel_32) + !#PROLOGUE# 0 + !#PROLOGUE# 1 + membar #StoreStore + casa [%o0] 0x80, %o1, %o2 + xor %o2, %o1, %o2 + subcc %g0, %o2, %g0 + retl + subx %g0, -1, %o0 +END_FUNC(pmix_atomic_cmpset_rel_32) + + +START_FUNC(pmix_atomic_cmpset_64) + !#PROLOGUE# 0 + save %sp, -128, %sp + !#PROLOGUE# 1 + mov %i3, %o4 + mov %i4, %o5 + st %i1, [%fp-32] + st %i2, [%fp-28] + std %o4, [%fp-24] + ldx [%fp-24], %g1 + ldx [%fp-32], %g2 + casxa [%i0] 0x80, %g2, %g1 + stx %g1, [%fp-24] + + ld [%fp-24], %i5 + ld [%fp-32], %g1 + cmp %i5, %g1 + bne REFLSYM(12) + mov 0, %i0 + ld [%fp-20], %i2 + ld [%fp-28], %i1 + cmp %i2, %i1 + be,a REFLSYM(12) + mov 1, %i0 +LSYM(12) + ret + restore +END_FUNC(pmix_atomic_cmpset_64) + + +START_FUNC(pmix_atomic_cmpset_acq_64) + !#PROLOGUE# 0 + save %sp, -128, %sp + !#PROLOGUE# 1 + mov %i1, %o4 + mov %i2, %o5 + mov %i3, %o2 + mov %i4, %o3 + std %o4, [%fp-32] + std %o2, [%fp-24] + ldx [%fp-24], %g1 + ldx [%fp-32], %g2 + casxa [%i0] 0x80, %g2, %g1 + stx %g1, [%fp-24] + + ld [%fp-24], %i5 + ld [%fp-32], %g1 + cmp %i5, %g1 + bne REFLSYM(16) + mov 0, %i0 + ld [%fp-20], %i2 + ld [%fp-28], %i1 + cmp %i2, %i1 + be,a REFLSYM(16) + mov 1, %i0 +LSYM(16) + membar #LoadLoad + ret + restore +END_FUNC(pmix_atomic_cmpset_acq_64) + + +START_FUNC(pmix_atomic_cmpset_rel_64) + !#PROLOGUE# 0 + save %sp, -128, %sp + !#PROLOGUE# 1 + mov %i1, %o4 + mov %i2, %o5 + mov %i3, %o2 + mov %i4, %o3 + membar #StoreStore + std %o4, [%fp-32] + std %o2, [%fp-24] + ldx [%fp-24], %g1 + ldx [%fp-32], %g2 + casxa [%i0] 0x80, %g2, %g1 + stx %g1, [%fp-24] + + ld [%fp-24], %i5 + ld [%fp-32], %g1 + cmp %i5, %g1 + bne REFLSYM(21) + mov 0, %i0 + ld [%fp-20], %i2 + ld [%fp-28], %i1 + cmp %i2, %i1 + be,a REFLSYM(21) + mov 1, %i0 +LSYM(21) + ret + restore +END_FUNC(pmix_atomic_cmpset_rel_64) + + +START_FUNC(pmix_sys_timer_get_cycles) + save %sp,-96,%sp + rd %tick,%o0 + srlx %o0,32,%o1 + or %g0,%o1,%i0 + ret ! Result = %i0 + restore %o0,0,%o1 +END_FUNC(pmix_sys_timer_get_cycles) diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/SPARCV9_64.asm b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/SPARCV9_64.asm new file mode 100644 index 0000000000..85825577db --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/SPARCV9_64.asm @@ -0,0 +1,111 @@ +START_FILE + TEXT + + ALIGN(4) + + +START_FUNC(pmix_atomic_mb) + !#PROLOGUE# 0 + !#PROLOGUE# 1 + membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad + retl + nop +END_FUNC(pmix_atomic_mb) + + +START_FUNC(pmix_atomic_rmb) + !#PROLOGUE# 0 + !#PROLOGUE# 1 + membar #LoadLoad + retl + nop +END_FUNC(pmix_atomic_rmb) + + +START_FUNC(pmix_atomic_wmb) + !#PROLOGUE# 0 + !#PROLOGUE# 1 + membar #StoreStore + retl + nop +END_FUNC(pmix_atomic_wmb) + + +START_FUNC(pmix_atomic_cmpset_32) + !#PROLOGUE# 0 + !#PROLOGUE# 1 + casa [%o0] 0x80, %o1, %o2 + xor %o2, %o1, %o2 + subcc %g0, %o2, %g0 + retl + subx %g0, -1, %o0 +END_FUNC(pmix_atomic_cmpset_32) + + +START_FUNC(pmix_atomic_cmpset_acq_32) + !#PROLOGUE# 0 + !#PROLOGUE# 1 + casa [%o0] 0x80, %o1, %o2 + xor %o2, %o1, %o2 + subcc %g0, %o2, %g0 + subx %g0, -1, %o0 + membar #LoadLoad + retl + sra %o0, 0, %o0 +END_FUNC(pmix_atomic_cmpset_acq_32) + + +START_FUNC(pmix_atomic_cmpset_rel_32) + !#PROLOGUE# 0 + !#PROLOGUE# 1 + membar #StoreStore + casa [%o0] 0x80, %o1, %o2 + xor %o2, %o1, %o2 + subcc %g0, %o2, %g0 + retl + subx %g0, -1, %o0 +END_FUNC(pmix_atomic_cmpset_rel_32) + + +START_FUNC(pmix_atomic_cmpset_64) + !#PROLOGUE# 0 + !#PROLOGUE# 1 + casxa [%o0] 0x80, %o1, %o2 + mov 0, %o0 + xor %o2, %o1, %o2 + retl + movre %o2, 1, %o0 +END_FUNC(pmix_atomic_cmpset_64) + + +START_FUNC(pmix_atomic_cmpset_acq_64) + !#PROLOGUE# 0 + !#PROLOGUE# 1 + casxa [%o0] 0x80, %o1, %o2 + mov 0, %o0 + xor %o2, %o1, %o2 + movre %o2, 1, %o0 + membar #LoadLoad + retl + sra %o0, 0, %o0 +END_FUNC(pmix_atomic_cmpset_acq_64) + + +START_FUNC(pmix_atomic_cmpset_rel_64) + !#PROLOGUE# 0 + !#PROLOGUE# 1 + membar #StoreStore + casxa [%o0] 0x80, %o1, %o2 + mov 0, %o0 + xor %o2, %o1, %o2 + retl + movre %o2, 1, %o0 +END_FUNC(pmix_atomic_cmpset_rel_64) + + +START_FUNC(pmix_sys_timer_get_cycles) + save %sp,-176,%sp + rd %tick,%o0 + ret ! Result = %i0 + restore %o0,0,%o0 +END_FUNC(pmix_sys_timer_get_cycles) diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/X86_64.asm b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/X86_64.asm new file mode 100644 index 0000000000..042c07109e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/X86_64.asm @@ -0,0 +1,52 @@ +START_FILE + TEXT + +START_FUNC(pmix_atomic_mb) + pushq %rbp + movq %rsp, %rbp + leave + ret +END_FUNC(pmix_atomic_mb) + + +START_FUNC(pmix_atomic_rmb) + pushq %rbp + movq %rsp, %rbp + leave + ret +END_FUNC(pmix_atomic_rmb) + + +START_FUNC(pmix_atomic_wmb) + pushq %rbp + movq %rsp, %rbp + leave + ret +END_FUNC(pmix_atomic_wmb) + + +START_FUNC(pmix_atomic_cmpset_32) + movl %esi, %eax + lock; cmpxchgl %edx,(%rdi) + sete %dl + movzbl %dl, %eax + ret +END_FUNC(pmix_atomic_cmpset_32) + + +START_FUNC(pmix_atomic_cmpset_64) + movq %rsi, %rax + lock; cmpxchgq %rdx,(%rdi) + sete %dl + movzbl %dl, %eax + ret +END_FUNC(pmix_atomic_cmpset_64) + + +START_FUNC(pmix_sys_timer_get_cycles) + rdtsc + salq $32, %rdx + mov %eax, %eax + orq %rdx, %rax + ret +END_FUNC(pmix_sys_timer_get_cycles) diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/aix.conf b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/aix.conf new file mode 100755 index 0000000000..482aabdd41 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/aix.conf @@ -0,0 +1,44 @@ +sub start_file() +{ + my $ret = ""; + if ($IS64BIT == 1) { + $ret .= "\t.machine \"ppc64\"\n"; + } else { + $ret .= "\t.machine \"ppc\"\n"; + } + $ret .= "\t.toc\n"; + return $ret; +} + + +sub start_func($) +{ + my $func_name = shift; + my $ret = ""; + + $ret = "\t$GLOBAL $func_name\n"; + $ret .= "\t$GLOBAL $GSYM$func_name\n"; + $ret .= "\t.csect [DS],3\n"; + + $ret .= "$func_name$SUFFIX\n"; + + if ($IS64BIT == 1) { + $ret .= "\t.llong .$func_name, TOC[tc0], 0\n"; + } else { + $ret .= "\t.long .$func_name, TOC[tc0], 0\n"; + } + $ret .= "\t.csect [PR]\n"; + + $ret .= "\t.align 2\n"; + $ret .= "$GSYM$func_name$SUFFIX\n"; + + return $ret; +} + + +sub end_func($) +{ + return ""; +} + +1 diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/default.conf b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/default.conf new file mode 100755 index 0000000000..c54f085cf9 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/base/default.conf @@ -0,0 +1,34 @@ +sub start_file +{ + return ""; +} + + +sub start_func($) +{ + my $func_name = shift; + my $ret = ""; + + $ret = "\t$GLOBAL $GSYM$func_name\n"; + if (! $TYPE eq "") { + $ret .= "\t.type $GSYM$func_name, $TYPE" . "function\n"; + } + $ret .= "$GSYM$func_name$SUFFIX\n"; + + return $ret; +} + + +sub end_func($) +{ + my $func_name = shift; + my $ret = ""; + + if ($SIZE != 0) { + $ret = "\t.size $GSYM$func_name, .-$GSYM$func_name\n"; + } + + return $ret; +} + +1 diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generate-all-asm.pl b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generate-all-asm.pl new file mode 100755 index 0000000000..e452cbeaf2 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generate-all-asm.pl @@ -0,0 +1,27 @@ +#!/usr/bin/perl -w + +my $perl = shift; +my $srcdir = shift; +my $destdir = shift; + +if (! $perl || ! $srcdir || ! $destdir) { + print "ERROR: invalid argument to generate-all-asm.pl\n"; + print "usage: generate-all-asm.pl [PERL] [SRCDIR] [DESTDIR]\n"; + exit 1; +} + +open(DATAFILE, "$srcdir/asm-data.txt") || die "Could not open data file: $!\n"; + +my $ASMARCH = ""; +my $ASMFORMAT = ""; +my $ASMFILE = ""; + +while() { + if (/^#/) { next; } + ($ASMARCH, $ASMFORMAT, $ASMFILE) = /(.*)\t(.*)\t(.*)/; + if (! $ASMARCH || ! $ASMFORMAT) { next; } + + print "--> Generating assembly for \"$ASMARCH\" \"$ASMFORMAT\"\n"; + system("$perl \'$srcdir/generate-asm.pl\' \'$ASMARCH\' \'$ASMFORMAT\' \'$srcdir/base\' \'$destdir/generated/atomic-$ASMFILE.s\'"); + +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generate-asm.pl b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generate-asm.pl new file mode 100644 index 0000000000..167a2a6e5e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generate-asm.pl @@ -0,0 +1,123 @@ +#!/usr/bin/perl -w +# +# Copyright (c) 2014 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + + +my $asmarch = shift; +my $asmformat = shift; +my $basedir = shift; +my $output = shift; + +if ( ! $asmarch) { + print "usage: generate-asm.pl [ASMARCH] [ASMFORMAT] [BASEDIR] [OUTPUT NAME]\n"; + exit(1); +} + +open(INPUT, "$basedir/$asmarch.asm") || + die "Could not open $basedir/$asmarch.asm: $!\n"; +open(OUTPUT, ">$output") || die "Could not open $output: $!\n"; + +$CONFIG = "default"; +$TEXT = ""; +$GLOBAL = ""; +$SUFFIX = ""; +$GSYM = ""; +$LSYM = ""; +$TYPE = ""; +$SIZE = 0; +$ALIGN_LOG = 0; +$DEL_R_REG = 0; +$IS64BIT = 0; + +($CONFIG, $TEXT, $GLOBAL, $SUFFIX, $GSYM, $LSYM, $TYPE, $SIZE, $ALIGN_LOG, $DEL_R_REG, $IS64BIT, $GNU_STACK) = ( + $asmformat =~ /(.*)\-(.*)\-(.*)\-(.*)\-(.*)\-(.*)\-(.*)\-(.*)\-(.*)\-(.*)\-(.*)\-(.*)/); + +if (0) { +print "$asmformat\n"; +print "CONFIG: $CONFIG\n"; +print "TEXT: $TEXT\n"; +print "GLOBAL: $GLOBAL\n"; +print "SUFFIX: $SUFFIX\n"; +print "GSYM: $GSYM\n"; +print "LSYM: $LSYM\n"; +print "GNU_STACK: $GNU_STACK\n"; +} + +my $current_func = ""; +my $delete = 0; + +# load our configuration +do "$basedir/$CONFIG.conf" or die "Could not open config file $basedir/$CONFIG.conf: $!\n"; + +while () { + s/TEXT/$TEXT/g; + s/GLOBAL/$GLOBAL/g; + s/REFGSYM\((.*)\)/$GSYM$1/g; + s/REFLSYM\((.*)\)/$LSYM$1/g; + s/GSYM\((.*)\)/$GSYM$1$SUFFIX/g; + s/LSYM\((.*)\)/$LSYM$1$SUFFIX/g; + + if ($DEL_R_REG == 0) { + s/cr([0-9][0-9]?)/$1/g; + s/r([0-9][0-9]?)/$1/g; + } + + if (/START_FILE/) { + $_ = start_file(); + } + + if (/START_FUNC\((.*)\)/) { + $current_func = $1; + $_ = start_func($current_func); + } + + if (/END_FUNC\((.*)\)/) { + $current_func = $1; + $_ = end_func($current_func); + } + + if ($ALIGN_LOG == 0) { + s/ALIGN\((\d*)\)/.align $1/g; + } else { + # Ugh... + if (m/ALIGN\((\d*)\)/) { + $val = $1; + $result = 0; + while ($val > 1) { $val /= 2; $result++ } + s/ALIGN\((\d*)\)/.align $result/; + } + } + + if (/^\#START_64BIT/) { + $_ = ""; + if ($IS64BIT == 0) { + $delete = 1; + } + } + if (/^\#END_64BIT/) { + $_ = ""; + $delete = 0; + } + + if ($delete == 0) { + print OUTPUT $_; + } +} + +if ($GNU_STACK == 1) { + if ($asmarch eq "ARM") { + print OUTPUT "\n\t.section\t.note.GNU-stack,\"\",\%progbits\n"; + } else { + print OUTPUT "\n\t.section\t.note.GNU-stack,\"\",\@progbits\n"; + } +} + +close(INPUT); +close(OUTPUT); diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-cygwin-nongas.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-cygwin-nongas.s new file mode 100644 index 0000000000..0eabeddf48 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-cygwin-nongas.s @@ -0,0 +1,109 @@ + .text + + .globl _pmix_atomic_mb +_pmix_atomic_mb: + pushl %ebp + movl %esp, %ebp + leave + ret + + + .globl _pmix_atomic_rmb +_pmix_atomic_rmb: + pushl %ebp + movl %esp, %ebp + leave + ret + + + .globl _pmix_atomic_wmb +_pmix_atomic_wmb: + pushl %ebp + movl %esp, %ebp + leave + ret + + + .globl _pmix_atomic_cmpset_32 +_pmix_atomic_cmpset_32: + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %edx + movl 16(%ebp), %ecx + movl 12(%ebp), %eax + lock; cmpxchgl %ecx,(%edx) + sete %dl + + movzbl %dl, %eax + leave + ret + + + .globl _pmix_atomic_cmpset_64 +_pmix_atomic_cmpset_64: + pushl %ebp + movl %esp, %ebp + subl $32, %esp + movl %ebx, -12(%ebp) + movl %esi, -8(%ebp) + movl %edi, -4(%ebp) + movl 8(%ebp), %edi + movl 12(%ebp), %eax + movl 16(%ebp), %edx + movl %eax, -24(%ebp) + movl %edx, -20(%ebp) + movl 20(%ebp), %eax + movl 24(%ebp), %edx + movl %eax, -32(%ebp) + movl %edx, -28(%ebp) + movl -24(%ebp), %ebx + movl -20(%ebp), %edx + movl -32(%ebp), %esi + movl -28(%ebp), %ecx + movl %ebx, %eax + push %ebx + movl %esi, %ebx + lock; cmpxchg8b (%edi) + sete %dl + pop %ebx + + movzbl %dl, %eax + movl -12(%ebp), %ebx + movl -8(%ebp), %esi + movl -4(%ebp), %edi + movl %ebp, %esp + popl %ebp + ret + + + .globl _pmix_atomic_add_32 +_pmix_atomic_add_32: + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %eax + movl 12(%ebp), %edx + lock; addl %edx,(%eax) + movl (%eax), %eax + leave + ret + + + .globl _pmix_atomic_sub_32 +_pmix_atomic_sub_32: + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %eax + movl 12(%ebp), %edx + lock; subl %edx,(%eax) + movl (%eax), %eax + leave + ret + + + .globl _pmix_sys_timer_get_cycles +_pmix_sys_timer_get_cycles: + pushl %ebp + movl %esp, %ebp + rdtsc + popl %ebp + ret diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-cygwin.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-cygwin.s new file mode 100644 index 0000000000..9ffab89085 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-cygwin.s @@ -0,0 +1,111 @@ + .text + + .globl _pmix_atomic_mb +_pmix_atomic_mb: + pushl %ebp + movl %esp, %ebp + leave + ret + + + .globl _pmix_atomic_rmb +_pmix_atomic_rmb: + pushl %ebp + movl %esp, %ebp + leave + ret + + + .globl _pmix_atomic_wmb +_pmix_atomic_wmb: + pushl %ebp + movl %esp, %ebp + leave + ret + + + .globl _pmix_atomic_cmpset_32 +_pmix_atomic_cmpset_32: + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %edx + movl 16(%ebp), %ecx + movl 12(%ebp), %eax + lock; cmpxchgl %ecx,(%edx) + sete %dl + + movzbl %dl, %eax + leave + ret + + + .globl _pmix_atomic_cmpset_64 +_pmix_atomic_cmpset_64: + pushl %ebp + movl %esp, %ebp + subl $32, %esp + movl %ebx, -12(%ebp) + movl %esi, -8(%ebp) + movl %edi, -4(%ebp) + movl 8(%ebp), %edi + movl 12(%ebp), %eax + movl 16(%ebp), %edx + movl %eax, -24(%ebp) + movl %edx, -20(%ebp) + movl 20(%ebp), %eax + movl 24(%ebp), %edx + movl %eax, -32(%ebp) + movl %edx, -28(%ebp) + movl -24(%ebp), %ebx + movl -20(%ebp), %edx + movl -32(%ebp), %esi + movl -28(%ebp), %ecx + movl %ebx, %eax + push %ebx + movl %esi, %ebx + lock; cmpxchg8b (%edi) + sete %dl + pop %ebx + + movzbl %dl, %eax + movl -12(%ebp), %ebx + movl -8(%ebp), %esi + movl -4(%ebp), %edi + movl %ebp, %esp + popl %ebp + ret + + + .globl _pmix_atomic_add_32 +_pmix_atomic_add_32: + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %eax + movl 12(%ebp), %edx + lock; addl %edx,(%eax) + movl (%eax), %eax + leave + ret + + + .globl _pmix_atomic_sub_32 +_pmix_atomic_sub_32: + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %eax + movl 12(%ebp), %edx + lock; subl %edx,(%eax) + movl (%eax), %eax + leave + ret + + + .globl _pmix_sys_timer_get_cycles +_pmix_sys_timer_get_cycles: + pushl %ebp + movl %esp, %ebp + rdtsc + popl %ebp + ret + + .section .note.GNU-stack,"",@progbits diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-linux-nongas.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-linux-nongas.s new file mode 100644 index 0000000000..99971a156e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-linux-nongas.s @@ -0,0 +1,125 @@ + .text + + .globl pmix_atomic_mb + .type pmix_atomic_mb, @function +pmix_atomic_mb: + pushl %ebp + movl %esp, %ebp + leave + ret + .size pmix_atomic_mb, .-pmix_atomic_mb + + + .globl pmix_atomic_rmb + .type pmix_atomic_rmb, @function +pmix_atomic_rmb: + pushl %ebp + movl %esp, %ebp + leave + ret + .size pmix_atomic_rmb, .-pmix_atomic_rmb + + + .globl pmix_atomic_wmb + .type pmix_atomic_wmb, @function +pmix_atomic_wmb: + pushl %ebp + movl %esp, %ebp + leave + ret + .size pmix_atomic_wmb, .-pmix_atomic_wmb + + + .globl pmix_atomic_cmpset_32 + .type pmix_atomic_cmpset_32, @function +pmix_atomic_cmpset_32: + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %edx + movl 16(%ebp), %ecx + movl 12(%ebp), %eax + lock; cmpxchgl %ecx,(%edx) + sete %dl + + movzbl %dl, %eax + leave + ret + .size pmix_atomic_cmpset_32, .-pmix_atomic_cmpset_32 + + + .globl pmix_atomic_cmpset_64 + .type pmix_atomic_cmpset_64, @function +pmix_atomic_cmpset_64: + pushl %ebp + movl %esp, %ebp + subl $32, %esp + movl %ebx, -12(%ebp) + movl %esi, -8(%ebp) + movl %edi, -4(%ebp) + movl 8(%ebp), %edi + movl 12(%ebp), %eax + movl 16(%ebp), %edx + movl %eax, -24(%ebp) + movl %edx, -20(%ebp) + movl 20(%ebp), %eax + movl 24(%ebp), %edx + movl %eax, -32(%ebp) + movl %edx, -28(%ebp) + movl -24(%ebp), %ebx + movl -20(%ebp), %edx + movl -32(%ebp), %esi + movl -28(%ebp), %ecx + movl %ebx, %eax + push %ebx + movl %esi, %ebx + lock; cmpxchg8b (%edi) + sete %dl + pop %ebx + + movzbl %dl, %eax + movl -12(%ebp), %ebx + movl -8(%ebp), %esi + movl -4(%ebp), %edi + movl %ebp, %esp + popl %ebp + ret + .size pmix_atomic_cmpset_64, .-pmix_atomic_cmpset_64 + + + .globl pmix_atomic_add_32 + .type pmix_atomic_add_32, @function +pmix_atomic_add_32: + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %eax + movl 12(%ebp), %edx + lock; addl %edx,(%eax) + movl (%eax), %eax + leave + ret + .size pmix_atomic_add_32, .-pmix_atomic_add_32 + + + .globl pmix_atomic_sub_32 + .type pmix_atomic_sub_32, @function +pmix_atomic_sub_32: + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %eax + movl 12(%ebp), %edx + lock; subl %edx,(%eax) + movl (%eax), %eax + leave + ret + .size pmix_atomic_sub_32, .-pmix_atomic_sub_32 + + + .globl pmix_sys_timer_get_cycles + .type pmix_sys_timer_get_cycles, @function +pmix_sys_timer_get_cycles: + pushl %ebp + movl %esp, %ebp + rdtsc + popl %ebp + ret + .size pmix_sys_timer_get_cycles, .-pmix_sys_timer_get_cycles diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-linux.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-linux.s new file mode 100644 index 0000000000..a1f639ea51 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-linux.s @@ -0,0 +1,127 @@ + .text + + .globl pmix_atomic_mb + .type pmix_atomic_mb, @function +pmix_atomic_mb: + pushl %ebp + movl %esp, %ebp + leave + ret + .size pmix_atomic_mb, .-pmix_atomic_mb + + + .globl pmix_atomic_rmb + .type pmix_atomic_rmb, @function +pmix_atomic_rmb: + pushl %ebp + movl %esp, %ebp + leave + ret + .size pmix_atomic_rmb, .-pmix_atomic_rmb + + + .globl pmix_atomic_wmb + .type pmix_atomic_wmb, @function +pmix_atomic_wmb: + pushl %ebp + movl %esp, %ebp + leave + ret + .size pmix_atomic_wmb, .-pmix_atomic_wmb + + + .globl pmix_atomic_cmpset_32 + .type pmix_atomic_cmpset_32, @function +pmix_atomic_cmpset_32: + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %edx + movl 16(%ebp), %ecx + movl 12(%ebp), %eax + lock; cmpxchgl %ecx,(%edx) + sete %dl + + movzbl %dl, %eax + leave + ret + .size pmix_atomic_cmpset_32, .-pmix_atomic_cmpset_32 + + + .globl pmix_atomic_cmpset_64 + .type pmix_atomic_cmpset_64, @function +pmix_atomic_cmpset_64: + pushl %ebp + movl %esp, %ebp + subl $32, %esp + movl %ebx, -12(%ebp) + movl %esi, -8(%ebp) + movl %edi, -4(%ebp) + movl 8(%ebp), %edi + movl 12(%ebp), %eax + movl 16(%ebp), %edx + movl %eax, -24(%ebp) + movl %edx, -20(%ebp) + movl 20(%ebp), %eax + movl 24(%ebp), %edx + movl %eax, -32(%ebp) + movl %edx, -28(%ebp) + movl -24(%ebp), %ebx + movl -20(%ebp), %edx + movl -32(%ebp), %esi + movl -28(%ebp), %ecx + movl %ebx, %eax + push %ebx + movl %esi, %ebx + lock; cmpxchg8b (%edi) + sete %dl + pop %ebx + + movzbl %dl, %eax + movl -12(%ebp), %ebx + movl -8(%ebp), %esi + movl -4(%ebp), %edi + movl %ebp, %esp + popl %ebp + ret + .size pmix_atomic_cmpset_64, .-pmix_atomic_cmpset_64 + + + .globl pmix_atomic_add_32 + .type pmix_atomic_add_32, @function +pmix_atomic_add_32: + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %eax + movl 12(%ebp), %edx + lock; addl %edx,(%eax) + movl (%eax), %eax + leave + ret + .size pmix_atomic_add_32, .-pmix_atomic_add_32 + + + .globl pmix_atomic_sub_32 + .type pmix_atomic_sub_32, @function +pmix_atomic_sub_32: + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %eax + movl 12(%ebp), %edx + lock; subl %edx,(%eax) + movl (%eax), %eax + leave + ret + .size pmix_atomic_sub_32, .-pmix_atomic_sub_32 + + + .globl pmix_sys_timer_get_cycles + .type pmix_sys_timer_get_cycles, @function +pmix_sys_timer_get_cycles: + pushl %ebp + movl %esp, %ebp + rdtsc + popl %ebp + ret + .size pmix_sys_timer_get_cycles, .-pmix_sys_timer_get_cycles + + .section .note.GNU-stack,"",@progbits diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-osx.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-osx.s new file mode 100644 index 0000000000..0eabeddf48 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia32-osx.s @@ -0,0 +1,109 @@ + .text + + .globl _pmix_atomic_mb +_pmix_atomic_mb: + pushl %ebp + movl %esp, %ebp + leave + ret + + + .globl _pmix_atomic_rmb +_pmix_atomic_rmb: + pushl %ebp + movl %esp, %ebp + leave + ret + + + .globl _pmix_atomic_wmb +_pmix_atomic_wmb: + pushl %ebp + movl %esp, %ebp + leave + ret + + + .globl _pmix_atomic_cmpset_32 +_pmix_atomic_cmpset_32: + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %edx + movl 16(%ebp), %ecx + movl 12(%ebp), %eax + lock; cmpxchgl %ecx,(%edx) + sete %dl + + movzbl %dl, %eax + leave + ret + + + .globl _pmix_atomic_cmpset_64 +_pmix_atomic_cmpset_64: + pushl %ebp + movl %esp, %ebp + subl $32, %esp + movl %ebx, -12(%ebp) + movl %esi, -8(%ebp) + movl %edi, -4(%ebp) + movl 8(%ebp), %edi + movl 12(%ebp), %eax + movl 16(%ebp), %edx + movl %eax, -24(%ebp) + movl %edx, -20(%ebp) + movl 20(%ebp), %eax + movl 24(%ebp), %edx + movl %eax, -32(%ebp) + movl %edx, -28(%ebp) + movl -24(%ebp), %ebx + movl -20(%ebp), %edx + movl -32(%ebp), %esi + movl -28(%ebp), %ecx + movl %ebx, %eax + push %ebx + movl %esi, %ebx + lock; cmpxchg8b (%edi) + sete %dl + pop %ebx + + movzbl %dl, %eax + movl -12(%ebp), %ebx + movl -8(%ebp), %esi + movl -4(%ebp), %edi + movl %ebp, %esp + popl %ebp + ret + + + .globl _pmix_atomic_add_32 +_pmix_atomic_add_32: + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %eax + movl 12(%ebp), %edx + lock; addl %edx,(%eax) + movl (%eax), %eax + leave + ret + + + .globl _pmix_atomic_sub_32 +_pmix_atomic_sub_32: + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %eax + movl 12(%ebp), %edx + lock; subl %edx,(%eax) + movl (%eax), %eax + leave + ret + + + .globl _pmix_sys_timer_get_cycles +_pmix_sys_timer_get_cycles: + pushl %ebp + movl %esp, %ebp + rdtsc + popl %ebp + ret diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia64-linux-nongas.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia64-linux-nongas.s new file mode 100644 index 0000000000..9e13953f4b --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia64-linux-nongas.s @@ -0,0 +1,108 @@ + + .pred.safe_across_calls p1-p5,p16-p63 + .text + .align 16 + .global pmix_atomic_mb# + .proc pmix_atomic_mb# +pmix_atomic_mb: + .prologue + .body + mf + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_mb# + .align 16 + .global pmix_atomic_rmb# + .proc pmix_atomic_rmb# +pmix_atomic_rmb: + .prologue + .body + mf + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_rmb# + .align 16 + .global pmix_atomic_wmb# + .proc pmix_atomic_wmb# +pmix_atomic_wmb: + .prologue + .body + mf + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_wmb# + .align 16 + .global pmix_atomic_cmpset_acq_32# + .proc pmix_atomic_cmpset_acq_32# +pmix_atomic_cmpset_acq_32: + .prologue + .body + mov ar.ccv=r33;; + cmpxchg4.acq r32=[r32],r34,ar.ccv + ;; + cmp4.eq p6, p7 = r32, r33 + ;; + (p6) addl r8 = 1, r0 + (p7) mov r8 = r0 + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_cmpset_acq_32# + .align 16 + .global pmix_atomic_cmpset_rel_32# + .proc pmix_atomic_cmpset_rel_32# +pmix_atomic_cmpset_rel_32: + .prologue + .body + mov ar.ccv=r33;; + cmpxchg4.rel r32=[r32],r34,ar.ccv + ;; + cmp4.eq p6, p7 = r32, r33 + ;; + (p6) addl r8 = 1, r0 + (p7) mov r8 = r0 + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_cmpset_rel_32# + .align 16 + .global pmix_atomic_cmpset_acq_64# + .proc pmix_atomic_cmpset_acq_64# +pmix_atomic_cmpset_acq_64: + .prologue + .body + mov ar.ccv=r33;; + cmpxchg8.acq r32=[r32],r34,ar.ccv + ;; + cmp.eq p6, p7 = r33, r32 + ;; + (p6) addl r8 = 1, r0 + (p7) mov r8 = r0 + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_cmpset_acq_64# + .align 16 + .global pmix_atomic_cmpset_rel_64# + .proc pmix_atomic_cmpset_rel_64# +pmix_atomic_cmpset_rel_64: + .prologue + .body + mov ar.ccv=r33;; + cmpxchg8.rel r32=[r32],r34,ar.ccv + ;; + cmp.eq p6, p7 = r33, r32 + ;; + (p6) addl r8 = 1, r0 + (p7) mov r8 = r0 + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_cmpset_rel_64# + .align 16 + .global pmix_sys_timer_get_cycles# + .proc pmix_sys_timer_get_cycles# +pmix_sys_timer_get_cycles: + .prologue + .body + mov r8=ar.itc + br.ret.sptk.many b0 + ;; + .endp pmix_sys_timer_get_cycles# + .ident "GCC: (GNU) 3.2.3 20030502 (Red Hat Linux 3.2.3-49)" diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia64-linux.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia64-linux.s new file mode 100644 index 0000000000..2bc097f2af --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-ia64-linux.s @@ -0,0 +1,110 @@ + + .pred.safe_across_calls p1-p5,p16-p63 + .text + .align 16 + .global pmix_atomic_mb# + .proc pmix_atomic_mb# +pmix_atomic_mb: + .prologue + .body + mf + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_mb# + .align 16 + .global pmix_atomic_rmb# + .proc pmix_atomic_rmb# +pmix_atomic_rmb: + .prologue + .body + mf + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_rmb# + .align 16 + .global pmix_atomic_wmb# + .proc pmix_atomic_wmb# +pmix_atomic_wmb: + .prologue + .body + mf + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_wmb# + .align 16 + .global pmix_atomic_cmpset_acq_32# + .proc pmix_atomic_cmpset_acq_32# +pmix_atomic_cmpset_acq_32: + .prologue + .body + mov ar.ccv=r33;; + cmpxchg4.acq r32=[r32],r34,ar.ccv + ;; + cmp4.eq p6, p7 = r32, r33 + ;; + (p6) addl r8 = 1, r0 + (p7) mov r8 = r0 + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_cmpset_acq_32# + .align 16 + .global pmix_atomic_cmpset_rel_32# + .proc pmix_atomic_cmpset_rel_32# +pmix_atomic_cmpset_rel_32: + .prologue + .body + mov ar.ccv=r33;; + cmpxchg4.rel r32=[r32],r34,ar.ccv + ;; + cmp4.eq p6, p7 = r32, r33 + ;; + (p6) addl r8 = 1, r0 + (p7) mov r8 = r0 + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_cmpset_rel_32# + .align 16 + .global pmix_atomic_cmpset_acq_64# + .proc pmix_atomic_cmpset_acq_64# +pmix_atomic_cmpset_acq_64: + .prologue + .body + mov ar.ccv=r33;; + cmpxchg8.acq r32=[r32],r34,ar.ccv + ;; + cmp.eq p6, p7 = r33, r32 + ;; + (p6) addl r8 = 1, r0 + (p7) mov r8 = r0 + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_cmpset_acq_64# + .align 16 + .global pmix_atomic_cmpset_rel_64# + .proc pmix_atomic_cmpset_rel_64# +pmix_atomic_cmpset_rel_64: + .prologue + .body + mov ar.ccv=r33;; + cmpxchg8.rel r32=[r32],r34,ar.ccv + ;; + cmp.eq p6, p7 = r33, r32 + ;; + (p6) addl r8 = 1, r0 + (p7) mov r8 = r0 + br.ret.sptk.many b0 + ;; + .endp pmix_atomic_cmpset_rel_64# + .align 16 + .global pmix_sys_timer_get_cycles# + .proc pmix_sys_timer_get_cycles# +pmix_sys_timer_get_cycles: + .prologue + .body + mov r8=ar.itc + br.ret.sptk.many b0 + ;; + .endp pmix_sys_timer_get_cycles# + .ident "GCC: (GNU) 3.2.3 20030502 (Red Hat Linux 3.2.3-49)" + + .section .note.GNU-stack,"",@progbits diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-mips-irix.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-mips-irix.s new file mode 100644 index 0000000000..27d4ae3d87 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-mips-irix.s @@ -0,0 +1,195 @@ + +#ifdef __linux__ +#include +#else +#include +#endif +#include + + .text + + .align 3 +LEAF(pmix_atomic_mb) +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + j ra +END(pmix_atomic_mb) + + + .align 3 +LEAF(pmix_atomic_rmb) +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + j ra +END(pmix_atomic_rmb) + + +LEAF(pmix_atomic_wmb) +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + j ra +END(pmix_atomic_wmb) + + +LEAF(pmix_atomic_cmpset_32) + .set noreorder +retry1: +#ifdef __linux__ + .set mips2 +#endif + ll $3, 0($4) +#ifdef __linux__ + .set mips0 +#endif + bne $3, $5, done1 + or $2, $6, 0 +#ifdef __linux__ + .set mips2 +#endif + sc $2, 0($4) +#ifdef __linux__ + .set mips0 +#endif + beqz $2, retry1 +done1: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_32) + + +LEAF(pmix_atomic_cmpset_acq_32) + .set noreorder +retry2: +#ifdef __linux__ + .set mips2 +#endif + ll $3, 0($4) +#ifdef __linux__ + .set mips0 +#endif + bne $3, $5, done2 + or $2, $6, 0 +#ifdef __linux__ + .set mips2 +#endif + sc $2, 0($4) +#ifdef __linux__ + .set mips0 +#endif + beqz $2, retry2 +done2: +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_acq_32) + + +LEAF(pmix_atomic_cmpset_rel_32) + .set noreorder +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif +retry3: +#ifdef __linux__ + .set mips2 +#endif + ll $3, 0($4) +#ifdef __linux__ + .set mips0 +#endif + bne $3, $5, done3 + or $2, $6, 0 +#ifdef __linux__ + .set mips2 +#endif + sc $2, 0($4) +#ifdef __linux__ + .set mips0 +#endif + beqz $2, retry3 +done3: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_rel_32) + +#ifdef __mips64 +LEAF(pmix_atomic_cmpset_64) + .set noreorder +retry4: + lld $3, 0($4) + bne $3, $5, done4 + or $2, $6, 0 + scd $2, 0($4) + beqz $2, retry4 +done4: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_64) + + +LEAF(pmix_atomic_cmpset_acq_64) + .set noreorder +retry5: + lld $3, 0($4) + bne $3, $5, done5 + or $2, $6, 0 + scd $2, 0($4) + beqz $2, retry5 +done5: + sync + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_acq_64) + + +LEAF(pmix_atomic_cmpset_rel_64) + .set noreorder + sync +retry6: + lld $3, 0($4) + bne $3, $5, done6 + or $2, $6, 0 + scd $2, 0($4) + beqz $2, retry6 +done6: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_rel_64) +#endif /* __mips64 */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-mips-linux.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-mips-linux.s new file mode 100644 index 0000000000..9339285f89 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-mips-linux.s @@ -0,0 +1,197 @@ + +#ifdef __linux__ +#include +#else +#include +#endif +#include + + .text + + .align 3 +LEAF(pmix_atomic_mb) +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + j ra +END(pmix_atomic_mb) + + + .align 3 +LEAF(pmix_atomic_rmb) +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + j ra +END(pmix_atomic_rmb) + + +LEAF(pmix_atomic_wmb) +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + j ra +END(pmix_atomic_wmb) + + +LEAF(pmix_atomic_cmpset_32) + .set noreorder +retry1: +#ifdef __linux__ + .set mips2 +#endif + ll $3, 0($4) +#ifdef __linux__ + .set mips0 +#endif + bne $3, $5, done1 + or $2, $6, 0 +#ifdef __linux__ + .set mips2 +#endif + sc $2, 0($4) +#ifdef __linux__ + .set mips0 +#endif + beqz $2, retry1 +done1: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_32) + + +LEAF(pmix_atomic_cmpset_acq_32) + .set noreorder +retry2: +#ifdef __linux__ + .set mips2 +#endif + ll $3, 0($4) +#ifdef __linux__ + .set mips0 +#endif + bne $3, $5, done2 + or $2, $6, 0 +#ifdef __linux__ + .set mips2 +#endif + sc $2, 0($4) +#ifdef __linux__ + .set mips0 +#endif + beqz $2, retry2 +done2: +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_acq_32) + + +LEAF(pmix_atomic_cmpset_rel_32) + .set noreorder +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif +retry3: +#ifdef __linux__ + .set mips2 +#endif + ll $3, 0($4) +#ifdef __linux__ + .set mips0 +#endif + bne $3, $5, done3 + or $2, $6, 0 +#ifdef __linux__ + .set mips2 +#endif + sc $2, 0($4) +#ifdef __linux__ + .set mips0 +#endif + beqz $2, retry3 +done3: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_rel_32) + +#ifdef __mips64 +LEAF(pmix_atomic_cmpset_64) + .set noreorder +retry4: + lld $3, 0($4) + bne $3, $5, done4 + or $2, $6, 0 + scd $2, 0($4) + beqz $2, retry4 +done4: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_64) + + +LEAF(pmix_atomic_cmpset_acq_64) + .set noreorder +retry5: + lld $3, 0($4) + bne $3, $5, done5 + or $2, $6, 0 + scd $2, 0($4) + beqz $2, retry5 +done5: + sync + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_acq_64) + + +LEAF(pmix_atomic_cmpset_rel_64) + .set noreorder + sync +retry6: + lld $3, 0($4) + bne $3, $5, done6 + or $2, $6, 0 + scd $2, 0($4) + beqz $2, retry6 +done6: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_rel_64) +#endif /* __mips64 */ + + .section .note.GNU-stack,"",@progbits diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-mips64-linux.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-mips64-linux.s new file mode 100644 index 0000000000..9339285f89 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-mips64-linux.s @@ -0,0 +1,197 @@ + +#ifdef __linux__ +#include +#else +#include +#endif +#include + + .text + + .align 3 +LEAF(pmix_atomic_mb) +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + j ra +END(pmix_atomic_mb) + + + .align 3 +LEAF(pmix_atomic_rmb) +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + j ra +END(pmix_atomic_rmb) + + +LEAF(pmix_atomic_wmb) +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + j ra +END(pmix_atomic_wmb) + + +LEAF(pmix_atomic_cmpset_32) + .set noreorder +retry1: +#ifdef __linux__ + .set mips2 +#endif + ll $3, 0($4) +#ifdef __linux__ + .set mips0 +#endif + bne $3, $5, done1 + or $2, $6, 0 +#ifdef __linux__ + .set mips2 +#endif + sc $2, 0($4) +#ifdef __linux__ + .set mips0 +#endif + beqz $2, retry1 +done1: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_32) + + +LEAF(pmix_atomic_cmpset_acq_32) + .set noreorder +retry2: +#ifdef __linux__ + .set mips2 +#endif + ll $3, 0($4) +#ifdef __linux__ + .set mips0 +#endif + bne $3, $5, done2 + or $2, $6, 0 +#ifdef __linux__ + .set mips2 +#endif + sc $2, 0($4) +#ifdef __linux__ + .set mips0 +#endif + beqz $2, retry2 +done2: +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_acq_32) + + +LEAF(pmix_atomic_cmpset_rel_32) + .set noreorder +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif +retry3: +#ifdef __linux__ + .set mips2 +#endif + ll $3, 0($4) +#ifdef __linux__ + .set mips0 +#endif + bne $3, $5, done3 + or $2, $6, 0 +#ifdef __linux__ + .set mips2 +#endif + sc $2, 0($4) +#ifdef __linux__ + .set mips0 +#endif + beqz $2, retry3 +done3: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_rel_32) + +#ifdef __mips64 +LEAF(pmix_atomic_cmpset_64) + .set noreorder +retry4: + lld $3, 0($4) + bne $3, $5, done4 + or $2, $6, 0 + scd $2, 0($4) + beqz $2, retry4 +done4: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_64) + + +LEAF(pmix_atomic_cmpset_acq_64) + .set noreorder +retry5: + lld $3, 0($4) + bne $3, $5, done5 + or $2, $6, 0 + scd $2, 0($4) + beqz $2, retry5 +done5: + sync + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_acq_64) + + +LEAF(pmix_atomic_cmpset_rel_64) + .set noreorder + sync +retry6: + lld $3, 0($4) + bne $3, $5, done6 + or $2, $6, 0 + scd $2, 0($4) + beqz $2, retry6 +done6: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_rel_64) +#endif /* __mips64 */ + + .section .note.GNU-stack,"",@progbits diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-mips64el.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-mips64el.s new file mode 100644 index 0000000000..27d4ae3d87 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-mips64el.s @@ -0,0 +1,195 @@ + +#ifdef __linux__ +#include +#else +#include +#endif +#include + + .text + + .align 3 +LEAF(pmix_atomic_mb) +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + j ra +END(pmix_atomic_mb) + + + .align 3 +LEAF(pmix_atomic_rmb) +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + j ra +END(pmix_atomic_rmb) + + +LEAF(pmix_atomic_wmb) +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + j ra +END(pmix_atomic_wmb) + + +LEAF(pmix_atomic_cmpset_32) + .set noreorder +retry1: +#ifdef __linux__ + .set mips2 +#endif + ll $3, 0($4) +#ifdef __linux__ + .set mips0 +#endif + bne $3, $5, done1 + or $2, $6, 0 +#ifdef __linux__ + .set mips2 +#endif + sc $2, 0($4) +#ifdef __linux__ + .set mips0 +#endif + beqz $2, retry1 +done1: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_32) + + +LEAF(pmix_atomic_cmpset_acq_32) + .set noreorder +retry2: +#ifdef __linux__ + .set mips2 +#endif + ll $3, 0($4) +#ifdef __linux__ + .set mips0 +#endif + bne $3, $5, done2 + or $2, $6, 0 +#ifdef __linux__ + .set mips2 +#endif + sc $2, 0($4) +#ifdef __linux__ + .set mips0 +#endif + beqz $2, retry2 +done2: +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_acq_32) + + +LEAF(pmix_atomic_cmpset_rel_32) + .set noreorder +#ifdef __linux__ + .set mips2 +#endif + sync +#ifdef __linux__ + .set mips0 +#endif +retry3: +#ifdef __linux__ + .set mips2 +#endif + ll $3, 0($4) +#ifdef __linux__ + .set mips0 +#endif + bne $3, $5, done3 + or $2, $6, 0 +#ifdef __linux__ + .set mips2 +#endif + sc $2, 0($4) +#ifdef __linux__ + .set mips0 +#endif + beqz $2, retry3 +done3: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_rel_32) + +#ifdef __mips64 +LEAF(pmix_atomic_cmpset_64) + .set noreorder +retry4: + lld $3, 0($4) + bne $3, $5, done4 + or $2, $6, 0 + scd $2, 0($4) + beqz $2, retry4 +done4: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_64) + + +LEAF(pmix_atomic_cmpset_acq_64) + .set noreorder +retry5: + lld $3, 0($4) + bne $3, $5, done5 + or $2, $6, 0 + scd $2, 0($4) + beqz $2, retry5 +done5: + sync + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_acq_64) + + +LEAF(pmix_atomic_cmpset_rel_64) + .set noreorder + sync +retry6: + lld $3, 0($4) + bne $3, $5, done6 + or $2, $6, 0 + scd $2, 0($4) + beqz $2, retry6 +done6: + xor $3,$3,$5 + j ra + sltu $2,$3,1 + .set reorder +END(pmix_atomic_cmpset_rel_64) +#endif /* __mips64 */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-64-osx.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-64-osx.s new file mode 100644 index 0000000000..ebe9d8ad2b --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-64-osx.s @@ -0,0 +1,165 @@ + .text + + .align 2 + .globl _pmix_atomic_mb +_pmix_atomic_mb: + sync + blr + + + .globl _pmix_atomic_rmb +_pmix_atomic_rmb: + lwsync + blr + + + .globl _pmix_atomic_wmb +_pmix_atomic_wmb: + eieio + blr + + + .globl _pmix_atomic_cmpset_32 +_pmix_atomic_cmpset_32: + L1: lwarx r0, 0, r3 + cmpw 0, r0, r4 + bne- L2 + stwcx. r5, 0, r3 + bne- L1 + L2: + xor r3,r0,r4 + subfic r5,r3,0 + adde r3,r5,r3 + blr + + + .globl _pmix_atomic_cmpset_acq_32 +_pmix_atomic_cmpset_acq_32: + L3: lwarx r0, 0, r3 + cmpw 0, r0, r4 + bne- L4 + stwcx. r5, 0, r3 + bne- L3 + sync + L4: + xor r3,r0,r4 + subfic r5,r3,0 + adde r3,r5,r3 + lwsync + blr + + + .globl _pmix_atomic_cmpset_rel_32 +_pmix_atomic_cmpset_rel_32: + eieio + L5: lwarx r0, 0, r3 + cmpw 0, r0, r4 + bne- L6 + stwcx. r5, 0, r3 + bne- L5 + sync + L6: + xor r3,r0,r4 + subfic r5,r3,0 + adde r3,r5,r3 + blr + + .globl _pmix_atomic_cmpset_64 +_pmix_atomic_cmpset_64: + stw r4,-32(r1) + stw r5,-28(r1) + stw r6,-24(r1) + stw r7,-20(r1) + ld r5,-32(r1) + ld r7,-24(r1) + L7: ldarx r9, 0, r3 + cmpd 0, r9, r5 + bne- L8 + stdcx. r7, 0, r3 + bne- L7 + L8: + xor r3,r5,r9 + subfic r5,r3,0 + adde r3,r5,r3 + blr + + + .globl _pmix_atomic_cmpset_acq_64 +_pmix_atomic_cmpset_acq_64: + stw r4,-32(r1) + stw r5,-28(r1) + stw r6,-24(r1) + stw r7,-20(r1) + ld r5,-32(r1) + ld r7,-24(r1) + + L9: ldarx r9, 0, r3 + cmpd 0, r9, r5 + bne- L10 + stdcx. r7, 0, r3 + bne- L9 + L10: + xor r3,r5,r9 + subfic r5,r3,0 + adde r3,r5,r3 + blr + lwsync + blr + + + .globl _pmix_atomic_cmpset_rel_64 +_pmix_atomic_cmpset_rel_64: + stw r4,-32(r1) + stw r5,-28(r1) + stw r6,-24(r1) + stw r7,-20(r1) + ld r5,-32(r1) + ld r7,-24(r1) + + eieio + L11: ldarx r9, 0, r3 + cmpd 0, r9, r5 + bne- L12 + stdcx. r7, 0, r3 + bne- L11 + L12: + xor r3,r5,r9 + subfic r5,r3,0 + adde r3,r5,r3 + blr + lwsync + blr + + + .globl _pmix_atomic_add_32 +_pmix_atomic_add_32: + L13: lwarx r0, 0, r3 + add r0, r4, r0 + stwcx. r0, 0, r3 + bne- L13 + mr r3,r0 + blr + + + .globl _pmix_atomic_sub_32 +_pmix_atomic_sub_32: + L14: lwarx r0,0,r3 + subf r0,r4,r0 + stwcx. r0,0,r3 + bne- L14 + mr r3,r0 + blr + + .globl _pmix_sys_timer_get_cycles +_pmix_sys_timer_get_cycles: + L15: + mftbu r0 + mftb r11 + mftbu r2 + cmpw cr7,r2,r0 + bne+ cr7,L15 + li r4,0 + li r9,0 + or r3,r2,r9 + or r4,r4,r11 + blr diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-aix.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-aix.s new file mode 100644 index 0000000000..7cc2ba0b9d --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-aix.s @@ -0,0 +1,156 @@ + .machine "ppc" + .toc + .csect .text[PR] + + .align 2 + .globl pmix_atomic_mb + .globl .pmix_atomic_mb + .csect [DS],3 +pmix_atomic_mb: + .long .pmix_atomic_mb, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_mb: + sync + blr + + + .globl pmix_atomic_rmb + .globl .pmix_atomic_rmb + .csect [DS],3 +pmix_atomic_rmb: + .long .pmix_atomic_rmb, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_rmb: + lwsync + blr + + + .globl pmix_atomic_wmb + .globl .pmix_atomic_wmb + .csect [DS],3 +pmix_atomic_wmb: + .long .pmix_atomic_wmb, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_wmb: + eieio + blr + + + .globl pmix_atomic_cmpset_32 + .globl .pmix_atomic_cmpset_32 + .csect [DS],3 +pmix_atomic_cmpset_32: + .long .pmix_atomic_cmpset_32, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_cmpset_32: + L1: lwarx 0, 0, 3 + cmpw 0, 0, 4 + bne- L2 + stwcx. 5, 0, 3 + bne- L1 + L2: + xor 3,0,4 + subfic 5,3,0 + adde 3,5,3 + blr + + + .globl pmix_atomic_cmpset_acq_32 + .globl .pmix_atomic_cmpset_acq_32 + .csect [DS],3 +pmix_atomic_cmpset_acq_32: + .long .pmix_atomic_cmpset_acq_32, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_cmpset_acq_32: + L3: lwarx 0, 0, 3 + cmpw 0, 0, 4 + bne- L4 + stwcx. 5, 0, 3 + bne- L3 + sync + L4: + xor 3,0,4 + subfic 5,3,0 + adde 3,5,3 + lwsync + blr + + + .globl pmix_atomic_cmpset_rel_32 + .globl .pmix_atomic_cmpset_rel_32 + .csect [DS],3 +pmix_atomic_cmpset_rel_32: + .long .pmix_atomic_cmpset_rel_32, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_cmpset_rel_32: + eieio + L5: lwarx 0, 0, 3 + cmpw 0, 0, 4 + bne- L6 + stwcx. 5, 0, 3 + bne- L5 + sync + L6: + xor 3,0,4 + subfic 5,3,0 + adde 3,5,3 + blr + + + + .globl pmix_atomic_add_32 + .globl .pmix_atomic_add_32 + .csect [DS],3 +pmix_atomic_add_32: + .long .pmix_atomic_add_32, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_add_32: + L13: lwarx 0, 0, 3 + add 0, 4, 0 + stwcx. 0, 0, 3 + bne- L13 + mr 3,0 + blr + + + .globl pmix_atomic_sub_32 + .globl .pmix_atomic_sub_32 + .csect [DS],3 +pmix_atomic_sub_32: + .long .pmix_atomic_sub_32, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_sub_32: + L14: lwarx 0,0,3 + subf 0,4,0 + stwcx. 0,0,3 + bne- L14 + mr 3,0 + blr + + .globl pmix_sys_timer_get_cycles + .globl .pmix_sys_timer_get_cycles + .csect [DS],3 +pmix_sys_timer_get_cycles: + .long .pmix_sys_timer_get_cycles, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_sys_timer_get_cycles: + L15: + mftbu 0 + mftb 11 + mftbu 2 + cmpw 7,2,0 + bne+ 7,L15 + li 4,0 + li 9,0 + or 3,2,9 + or 4,4,11 + blr diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-linux-nongas.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-linux-nongas.s new file mode 100644 index 0000000000..37b36c22b0 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-linux-nongas.s @@ -0,0 +1,118 @@ + .text + + .align 2 + .globl pmix_atomic_mb + .type pmix_atomic_mb, @function +pmix_atomic_mb: + sync + blr + .size pmix_atomic_mb, .-pmix_atomic_mb + + + .globl pmix_atomic_rmb + .type pmix_atomic_rmb, @function +pmix_atomic_rmb: + lwsync + blr + .size pmix_atomic_rmb, .-pmix_atomic_rmb + + + .globl pmix_atomic_wmb + .type pmix_atomic_wmb, @function +pmix_atomic_wmb: + eieio + blr + .size pmix_atomic_wmb, .-pmix_atomic_wmb + + + .globl pmix_atomic_cmpset_32 + .type pmix_atomic_cmpset_32, @function +pmix_atomic_cmpset_32: + .L1: lwarx 0, 0, 3 + cmpw 0, 0, 4 + bne- .L2 + stwcx. 5, 0, 3 + bne- .L1 + .L2: + xor 3,0,4 + subfic 5,3,0 + adde 3,5,3 + blr + .size pmix_atomic_cmpset_32, .-pmix_atomic_cmpset_32 + + + .globl pmix_atomic_cmpset_acq_32 + .type pmix_atomic_cmpset_acq_32, @function +pmix_atomic_cmpset_acq_32: + .L3: lwarx 0, 0, 3 + cmpw 0, 0, 4 + bne- .L4 + stwcx. 5, 0, 3 + bne- .L3 + sync + .L4: + xor 3,0,4 + subfic 5,3,0 + adde 3,5,3 + lwsync + blr + .size pmix_atomic_cmpset_acq_32, .-pmix_atomic_cmpset_acq_32 + + + .globl pmix_atomic_cmpset_rel_32 + .type pmix_atomic_cmpset_rel_32, @function +pmix_atomic_cmpset_rel_32: + eieio + .L5: lwarx 0, 0, 3 + cmpw 0, 0, 4 + bne- .L6 + stwcx. 5, 0, 3 + bne- .L5 + sync + .L6: + xor 3,0,4 + subfic 5,3,0 + adde 3,5,3 + blr + .size pmix_atomic_cmpset_rel_32, .-pmix_atomic_cmpset_rel_32 + + + + .globl pmix_atomic_add_32 + .type pmix_atomic_add_32, @function +pmix_atomic_add_32: + .L13: lwarx 0, 0, 3 + add 0, 4, 0 + stwcx. 0, 0, 3 + bne- .L13 + mr 3,0 + blr + .size pmix_atomic_add_32, .-pmix_atomic_add_32 + + + .globl pmix_atomic_sub_32 + .type pmix_atomic_sub_32, @function +pmix_atomic_sub_32: + .L14: lwarx 0,0,3 + subf 0,4,0 + stwcx. 0,0,3 + bne- .L14 + mr 3,0 + blr + .size pmix_atomic_sub_32, .-pmix_atomic_sub_32 + + .globl pmix_sys_timer_get_cycles + .type pmix_sys_timer_get_cycles, @function +pmix_sys_timer_get_cycles: + .L15: + mftbu 0 + mftb 11 + mftbu 2 + cmpw 7,2,0 + bne+ 7,.L15 + li 4,0 + li 9,0 + or 3,2,9 + or 4,4,11 + blr + .size pmix_sys_timer_get_cycles, .-pmix_sys_timer_get_cycles diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-linux.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-linux.s new file mode 100644 index 0000000000..afecd0a305 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-linux.s @@ -0,0 +1,120 @@ + .text + + .align 2 + .globl pmix_atomic_mb + .type pmix_atomic_mb, @function +pmix_atomic_mb: + sync + blr + .size pmix_atomic_mb, .-pmix_atomic_mb + + + .globl pmix_atomic_rmb + .type pmix_atomic_rmb, @function +pmix_atomic_rmb: + lwsync + blr + .size pmix_atomic_rmb, .-pmix_atomic_rmb + + + .globl pmix_atomic_wmb + .type pmix_atomic_wmb, @function +pmix_atomic_wmb: + eieio + blr + .size pmix_atomic_wmb, .-pmix_atomic_wmb + + + .globl pmix_atomic_cmpset_32 + .type pmix_atomic_cmpset_32, @function +pmix_atomic_cmpset_32: + .L1: lwarx 0, 0, 3 + cmpw 0, 0, 4 + bne- .L2 + stwcx. 5, 0, 3 + bne- .L1 + .L2: + xor 3,0,4 + subfic 5,3,0 + adde 3,5,3 + blr + .size pmix_atomic_cmpset_32, .-pmix_atomic_cmpset_32 + + + .globl pmix_atomic_cmpset_acq_32 + .type pmix_atomic_cmpset_acq_32, @function +pmix_atomic_cmpset_acq_32: + .L3: lwarx 0, 0, 3 + cmpw 0, 0, 4 + bne- .L4 + stwcx. 5, 0, 3 + bne- .L3 + sync + .L4: + xor 3,0,4 + subfic 5,3,0 + adde 3,5,3 + lwsync + blr + .size pmix_atomic_cmpset_acq_32, .-pmix_atomic_cmpset_acq_32 + + + .globl pmix_atomic_cmpset_rel_32 + .type pmix_atomic_cmpset_rel_32, @function +pmix_atomic_cmpset_rel_32: + eieio + .L5: lwarx 0, 0, 3 + cmpw 0, 0, 4 + bne- .L6 + stwcx. 5, 0, 3 + bne- .L5 + sync + .L6: + xor 3,0,4 + subfic 5,3,0 + adde 3,5,3 + blr + .size pmix_atomic_cmpset_rel_32, .-pmix_atomic_cmpset_rel_32 + + + + .globl pmix_atomic_add_32 + .type pmix_atomic_add_32, @function +pmix_atomic_add_32: + .L13: lwarx 0, 0, 3 + add 0, 4, 0 + stwcx. 0, 0, 3 + bne- .L13 + mr 3,0 + blr + .size pmix_atomic_add_32, .-pmix_atomic_add_32 + + + .globl pmix_atomic_sub_32 + .type pmix_atomic_sub_32, @function +pmix_atomic_sub_32: + .L14: lwarx 0,0,3 + subf 0,4,0 + stwcx. 0,0,3 + bne- .L14 + mr 3,0 + blr + .size pmix_atomic_sub_32, .-pmix_atomic_sub_32 + + .globl pmix_sys_timer_get_cycles + .type pmix_sys_timer_get_cycles, @function +pmix_sys_timer_get_cycles: + .L15: + mftbu 0 + mftb 11 + mftbu 2 + cmpw 7,2,0 + bne+ 7,.L15 + li 4,0 + li 9,0 + or 3,2,9 + or 4,4,11 + blr + .size pmix_sys_timer_get_cycles, .-pmix_sys_timer_get_cycles + + .section .note.GNU-stack,"",@progbits diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-osx.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-osx.s new file mode 100644 index 0000000000..7d2dceb2a8 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc32-osx.s @@ -0,0 +1,100 @@ + .text + + .align 2 + .globl _pmix_atomic_mb +_pmix_atomic_mb: + sync + blr + + + .globl _pmix_atomic_rmb +_pmix_atomic_rmb: + lwsync + blr + + + .globl _pmix_atomic_wmb +_pmix_atomic_wmb: + eieio + blr + + + .globl _pmix_atomic_cmpset_32 +_pmix_atomic_cmpset_32: + L1: lwarx r0, 0, r3 + cmpw 0, r0, r4 + bne- L2 + stwcx. r5, 0, r3 + bne- L1 + L2: + xor r3,r0,r4 + subfic r5,r3,0 + adde r3,r5,r3 + blr + + + .globl _pmix_atomic_cmpset_acq_32 +_pmix_atomic_cmpset_acq_32: + L3: lwarx r0, 0, r3 + cmpw 0, r0, r4 + bne- L4 + stwcx. r5, 0, r3 + bne- L3 + sync + L4: + xor r3,r0,r4 + subfic r5,r3,0 + adde r3,r5,r3 + lwsync + blr + + + .globl _pmix_atomic_cmpset_rel_32 +_pmix_atomic_cmpset_rel_32: + eieio + L5: lwarx r0, 0, r3 + cmpw 0, r0, r4 + bne- L6 + stwcx. r5, 0, r3 + bne- L5 + sync + L6: + xor r3,r0,r4 + subfic r5,r3,0 + adde r3,r5,r3 + blr + + + + .globl _pmix_atomic_add_32 +_pmix_atomic_add_32: + L13: lwarx r0, 0, r3 + add r0, r4, r0 + stwcx. r0, 0, r3 + bne- L13 + mr r3,r0 + blr + + + .globl _pmix_atomic_sub_32 +_pmix_atomic_sub_32: + L14: lwarx r0,0,r3 + subf r0,r4,r0 + stwcx. r0,0,r3 + bne- L14 + mr r3,r0 + blr + + .globl _pmix_sys_timer_get_cycles +_pmix_sys_timer_get_cycles: + L15: + mftbu r0 + mftb r11 + mftbu r2 + cmpw cr7,r2,r0 + bne+ cr7,L15 + li r4,0 + li r9,0 + or r3,r2,r9 + or r4,r4,r11 + blr diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc64-aix.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc64-aix.s new file mode 100644 index 0000000000..7e3995e351 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc64-aix.s @@ -0,0 +1,230 @@ + .machine "ppc64" + .toc + .csect .text[PR] + + .align 2 + .globl pmix_atomic_mb + .globl .pmix_atomic_mb + .csect [DS],3 +pmix_atomic_mb: + .llong .pmix_atomic_mb, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_mb: + sync + blr + + + .globl pmix_atomic_rmb + .globl .pmix_atomic_rmb + .csect [DS],3 +pmix_atomic_rmb: + .llong .pmix_atomic_rmb, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_rmb: + lwsync + blr + + + .globl pmix_atomic_wmb + .globl .pmix_atomic_wmb + .csect [DS],3 +pmix_atomic_wmb: + .llong .pmix_atomic_wmb, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_wmb: + eieio + blr + + + .globl pmix_atomic_cmpset_32 + .globl .pmix_atomic_cmpset_32 + .csect [DS],3 +pmix_atomic_cmpset_32: + .llong .pmix_atomic_cmpset_32, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_cmpset_32: + L1: lwarx 0, 0, 3 + cmpw 0, 0, 4 + bne- L2 + stwcx. 5, 0, 3 + bne- L1 + L2: + cmpw 7,0,4 + mfcr 3 + rlwinm 3,3,31,1 + blr + + + .globl pmix_atomic_cmpset_acq_32 + .globl .pmix_atomic_cmpset_acq_32 + .csect [DS],3 +pmix_atomic_cmpset_acq_32: + .llong .pmix_atomic_cmpset_acq_32, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_cmpset_acq_32: + mflr 0 + std 29,-24(1) + std 0,16(1) + stdu 1,-144(1) + bl .pmix_atomic_cmpset_32 + mr 29,3 + bl .pmix_atomic_rmb + mr 3,29 + addi 1,1,144 + ld 0,16(1) + mtlr 0 + ld 29,-24(1) + blr + + + .globl pmix_atomic_cmpset_rel_32 + .globl .pmix_atomic_cmpset_rel_32 + .csect [DS],3 +pmix_atomic_cmpset_rel_32: + .llong .pmix_atomic_cmpset_rel_32, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_cmpset_rel_32: + mflr 0 + std 27,-40(1) + std 28,-32(1) + std 29,-24(1) + std 0,16(1) + stdu 1,-160(1) + mr 29,3 + mr 28,4 + mr 27,5 + bl .pmix_atomic_wmb + mr 3,29 + mr 4,28 + mr 5,27 + bl .pmix_atomic_cmpset_32 + addi 1,1,160 + ld 0,16(1) + mtlr 0 + ld 27,-40(1) + ld 28,-32(1) + ld 29,-24(1) + blr + + + .globl pmix_atomic_cmpset_64 + .globl .pmix_atomic_cmpset_64 + .csect [DS],3 +pmix_atomic_cmpset_64: + .llong .pmix_atomic_cmpset_64, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_cmpset_64: + L3: ldarx 0, 0, 3 + cmpd 0, 0, 4 + bne- L4 + stdcx. 5, 0, 3 + bne- L3 + L4: + xor 3,4,0 + subfic 5,3,0 + adde 3,5,3 + blr + + + .globl pmix_atomic_cmpset_acq_64 + .globl .pmix_atomic_cmpset_acq_64 + .csect [DS],3 +pmix_atomic_cmpset_acq_64: + .llong .pmix_atomic_cmpset_acq_64, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_cmpset_acq_64: + L7: ldarx 0, 0, 3 + cmpd 0, 0, 4 + bne- L8 + stdcx. 5, 0, 3 + bne- L7 + L8: + lwsync + xor 3,4,0 + subfic 5,3,0 + adde 3,5,3 + blr + + + .globl pmix_atomic_cmpset_rel_64 + .globl .pmix_atomic_cmpset_rel_64 + .csect [DS],3 +pmix_atomic_cmpset_rel_64: + .llong .pmix_atomic_cmpset_rel_64, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_cmpset_rel_64: + eieio + L9: ldarx 0, 0, 3 + cmpd 0, 0, 4 + bne- L10 + stdcx. 5, 0, 3 + bne- L9 + L10: + xor 3,4,0 + subfic 5,3,0 + adde 3,5,3 + blr + + + .globl pmix_atomic_add_32 + .globl .pmix_atomic_add_32 + .csect [DS],3 +pmix_atomic_add_32: + .llong .pmix_atomic_add_32, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_add_32: + L5: lwarx 0, 0, 3 + add 0, 4, 0 + stwcx. 0, 0, 3 + bne- L5 + + mr 3,0 + blr + + + .globl pmix_atomic_sub_32 + .globl .pmix_atomic_sub_32 + .csect [DS],3 +pmix_atomic_sub_32: + .llong .pmix_atomic_sub_32, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_atomic_sub_32: + L6: lwarx 0,0,3 + subf 0,4,0 + stwcx. 0,0,3 + bne- L6 + + mr 3,0 + blr + + .globl pmix_sys_timer_get_cycles + .globl .pmix_sys_timer_get_cycles + .csect [DS],3 +pmix_sys_timer_get_cycles: + .llong .pmix_sys_timer_get_cycles, TOC[tc0], 0 + .csect [PR] + .align 2 +.pmix_sys_timer_get_cycles: + L11: + mftbu 2 + rldicl 2,2,0,32 + mftb 0 + rldicl 9,0,0,32 + mftbu 0 + rldicl 0,0,0,32 + cmpw 7,0,2 + bne 7,L11 + sldi 3,0,32 + or 3,3,9 + blr diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc64-linux-nongas.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc64-linux-nongas.s new file mode 100644 index 0000000000..1bb4731ae3 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc64-linux-nongas.s @@ -0,0 +1,180 @@ + .text + + .align 2 + .globl .pmix_atomic_mb + .type .pmix_atomic_mb, @function +.pmix_atomic_mb: + sync + blr + .size .pmix_atomic_mb, .-.pmix_atomic_mb + + + .globl .pmix_atomic_rmb + .type .pmix_atomic_rmb, @function +.pmix_atomic_rmb: + lwsync + blr + .size .pmix_atomic_rmb, .-.pmix_atomic_rmb + + + .globl .pmix_atomic_wmb + .type .pmix_atomic_wmb, @function +.pmix_atomic_wmb: + eieio + blr + .size .pmix_atomic_wmb, .-.pmix_atomic_wmb + + + .globl .pmix_atomic_cmpset_32 + .type .pmix_atomic_cmpset_32, @function +.pmix_atomic_cmpset_32: + .L1: lwarx 0, 0, 3 + cmpw 0, 0, 4 + bne- .L2 + stwcx. 5, 0, 3 + bne- .L1 + .L2: + cmpw 7,0,4 + mfcr 3 + rlwinm 3,3,31,1 + blr + .size .pmix_atomic_cmpset_32, .-.pmix_atomic_cmpset_32 + + + .globl .pmix_atomic_cmpset_acq_32 + .type .pmix_atomic_cmpset_acq_32, @function +.pmix_atomic_cmpset_acq_32: + mflr 0 + std 29,-24(1) + std 0,16(1) + stdu 1,-144(1) + bl .pmix_atomic_cmpset_32 + mr 29,3 + bl .pmix_atomic_rmb + mr 3,29 + addi 1,1,144 + ld 0,16(1) + mtlr 0 + ld 29,-24(1) + blr + .size .pmix_atomic_cmpset_acq_32, .-.pmix_atomic_cmpset_acq_32 + + + .globl .pmix_atomic_cmpset_rel_32 + .type .pmix_atomic_cmpset_rel_32, @function +.pmix_atomic_cmpset_rel_32: + mflr 0 + std 27,-40(1) + std 28,-32(1) + std 29,-24(1) + std 0,16(1) + stdu 1,-160(1) + mr 29,3 + mr 28,4 + mr 27,5 + bl .pmix_atomic_wmb + mr 3,29 + mr 4,28 + mr 5,27 + bl .pmix_atomic_cmpset_32 + addi 1,1,160 + ld 0,16(1) + mtlr 0 + ld 27,-40(1) + ld 28,-32(1) + ld 29,-24(1) + blr + .size .pmix_atomic_cmpset_rel_32, .-.pmix_atomic_cmpset_rel_32 + + + .globl .pmix_atomic_cmpset_64 + .type .pmix_atomic_cmpset_64, @function +.pmix_atomic_cmpset_64: + .L3: ldarx 0, 0, 3 + cmpd 0, 0, 4 + bne- .L4 + stdcx. 5, 0, 3 + bne- .L3 + .L4: + xor 3,4,0 + subfic 5,3,0 + adde 3,5,3 + blr + .size .pmix_atomic_cmpset_64, .-.pmix_atomic_cmpset_64 + + + .globl .pmix_atomic_cmpset_acq_64 + .type .pmix_atomic_cmpset_acq_64, @function +.pmix_atomic_cmpset_acq_64: + .L7: ldarx 0, 0, 3 + cmpd 0, 0, 4 + bne- .L8 + stdcx. 5, 0, 3 + bne- .L7 + .L8: + lwsync + xor 3,4,0 + subfic 5,3,0 + adde 3,5,3 + blr + .size .pmix_atomic_cmpset_acq_64, .-.pmix_atomic_cmpset_acq_64 + + + .globl .pmix_atomic_cmpset_rel_64 + .type .pmix_atomic_cmpset_rel_64, @function +.pmix_atomic_cmpset_rel_64: + eieio + .L9: ldarx 0, 0, 3 + cmpd 0, 0, 4 + bne- .L10 + stdcx. 5, 0, 3 + bne- .L9 + .L10: + xor 3,4,0 + subfic 5,3,0 + adde 3,5,3 + blr + .size .pmix_atomic_cmpset_rel_64, .-.pmix_atomic_cmpset_rel_64 + + + .globl .pmix_atomic_add_32 + .type .pmix_atomic_add_32, @function +.pmix_atomic_add_32: + .L5: lwarx 0, 0, 3 + add 0, 4, 0 + stwcx. 0, 0, 3 + bne- .L5 + + mr 3,0 + blr + .size .pmix_atomic_add_32, .-.pmix_atomic_add_32 + + + .globl .pmix_atomic_sub_32 + .type .pmix_atomic_sub_32, @function +.pmix_atomic_sub_32: + .L6: lwarx 0,0,3 + subf 0,4,0 + stwcx. 0,0,3 + bne- .L6 + + mr 3,0 + blr + .size .pmix_atomic_sub_32, .-.pmix_atomic_sub_32 + + .globl .pmix_sys_timer_get_cycles + .type .pmix_sys_timer_get_cycles, @function +.pmix_sys_timer_get_cycles: + .L11: + mftbu 2 + rldicl 2,2,0,32 + mftb 0 + rldicl 9,0,0,32 + mftbu 0 + rldicl 0,0,0,32 + cmpw 7,0,2 + bne 7,.L11 + sldi 3,0,32 + or 3,3,9 + blr + .size .pmix_sys_timer_get_cycles, .-.pmix_sys_timer_get_cycles diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc64-linux.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc64-linux.s new file mode 100644 index 0000000000..300d0aa0d7 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc64-linux.s @@ -0,0 +1,182 @@ + .text + + .align 2 + .globl .pmix_atomic_mb + .type .pmix_atomic_mb, @function +.pmix_atomic_mb: + sync + blr + .size .pmix_atomic_mb, .-.pmix_atomic_mb + + + .globl .pmix_atomic_rmb + .type .pmix_atomic_rmb, @function +.pmix_atomic_rmb: + lwsync + blr + .size .pmix_atomic_rmb, .-.pmix_atomic_rmb + + + .globl .pmix_atomic_wmb + .type .pmix_atomic_wmb, @function +.pmix_atomic_wmb: + eieio + blr + .size .pmix_atomic_wmb, .-.pmix_atomic_wmb + + + .globl .pmix_atomic_cmpset_32 + .type .pmix_atomic_cmpset_32, @function +.pmix_atomic_cmpset_32: + .L1: lwarx 0, 0, 3 + cmpw 0, 0, 4 + bne- .L2 + stwcx. 5, 0, 3 + bne- .L1 + .L2: + cmpw 7,0,4 + mfcr 3 + rlwinm 3,3,31,1 + blr + .size .pmix_atomic_cmpset_32, .-.pmix_atomic_cmpset_32 + + + .globl .pmix_atomic_cmpset_acq_32 + .type .pmix_atomic_cmpset_acq_32, @function +.pmix_atomic_cmpset_acq_32: + mflr 0 + std 29,-24(1) + std 0,16(1) + stdu 1,-144(1) + bl .pmix_atomic_cmpset_32 + mr 29,3 + bl .pmix_atomic_rmb + mr 3,29 + addi 1,1,144 + ld 0,16(1) + mtlr 0 + ld 29,-24(1) + blr + .size .pmix_atomic_cmpset_acq_32, .-.pmix_atomic_cmpset_acq_32 + + + .globl .pmix_atomic_cmpset_rel_32 + .type .pmix_atomic_cmpset_rel_32, @function +.pmix_atomic_cmpset_rel_32: + mflr 0 + std 27,-40(1) + std 28,-32(1) + std 29,-24(1) + std 0,16(1) + stdu 1,-160(1) + mr 29,3 + mr 28,4 + mr 27,5 + bl .pmix_atomic_wmb + mr 3,29 + mr 4,28 + mr 5,27 + bl .pmix_atomic_cmpset_32 + addi 1,1,160 + ld 0,16(1) + mtlr 0 + ld 27,-40(1) + ld 28,-32(1) + ld 29,-24(1) + blr + .size .pmix_atomic_cmpset_rel_32, .-.pmix_atomic_cmpset_rel_32 + + + .globl .pmix_atomic_cmpset_64 + .type .pmix_atomic_cmpset_64, @function +.pmix_atomic_cmpset_64: + .L3: ldarx 0, 0, 3 + cmpd 0, 0, 4 + bne- .L4 + stdcx. 5, 0, 3 + bne- .L3 + .L4: + xor 3,4,0 + subfic 5,3,0 + adde 3,5,3 + blr + .size .pmix_atomic_cmpset_64, .-.pmix_atomic_cmpset_64 + + + .globl .pmix_atomic_cmpset_acq_64 + .type .pmix_atomic_cmpset_acq_64, @function +.pmix_atomic_cmpset_acq_64: + .L7: ldarx 0, 0, 3 + cmpd 0, 0, 4 + bne- .L8 + stdcx. 5, 0, 3 + bne- .L7 + .L8: + lwsync + xor 3,4,0 + subfic 5,3,0 + adde 3,5,3 + blr + .size .pmix_atomic_cmpset_acq_64, .-.pmix_atomic_cmpset_acq_64 + + + .globl .pmix_atomic_cmpset_rel_64 + .type .pmix_atomic_cmpset_rel_64, @function +.pmix_atomic_cmpset_rel_64: + eieio + .L9: ldarx 0, 0, 3 + cmpd 0, 0, 4 + bne- .L10 + stdcx. 5, 0, 3 + bne- .L9 + .L10: + xor 3,4,0 + subfic 5,3,0 + adde 3,5,3 + blr + .size .pmix_atomic_cmpset_rel_64, .-.pmix_atomic_cmpset_rel_64 + + + .globl .pmix_atomic_add_32 + .type .pmix_atomic_add_32, @function +.pmix_atomic_add_32: + .L5: lwarx 0, 0, 3 + add 0, 4, 0 + stwcx. 0, 0, 3 + bne- .L5 + + mr 3,0 + blr + .size .pmix_atomic_add_32, .-.pmix_atomic_add_32 + + + .globl .pmix_atomic_sub_32 + .type .pmix_atomic_sub_32, @function +.pmix_atomic_sub_32: + .L6: lwarx 0,0,3 + subf 0,4,0 + stwcx. 0,0,3 + bne- .L6 + + mr 3,0 + blr + .size .pmix_atomic_sub_32, .-.pmix_atomic_sub_32 + + .globl .pmix_sys_timer_get_cycles + .type .pmix_sys_timer_get_cycles, @function +.pmix_sys_timer_get_cycles: + .L11: + mftbu 2 + rldicl 2,2,0,32 + mftb 0 + rldicl 9,0,0,32 + mftbu 0 + rldicl 0,0,0,32 + cmpw 7,0,2 + bne 7,.L11 + sldi 3,0,32 + or 3,3,9 + blr + .size .pmix_sys_timer_get_cycles, .-.pmix_sys_timer_get_cycles + + .section .note.GNU-stack,"",@progbits diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc64-osx.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc64-osx.s new file mode 100644 index 0000000000..3a29e67e01 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-powerpc64-osx.s @@ -0,0 +1,156 @@ + .text + + .align 2 + .globl _pmix_atomic_mb +_pmix_atomic_mb: + sync + blr + + + .globl _pmix_atomic_rmb +_pmix_atomic_rmb: + lwsync + blr + + + .globl _pmix_atomic_wmb +_pmix_atomic_wmb: + eieio + blr + + + .globl _pmix_atomic_cmpset_32 +_pmix_atomic_cmpset_32: + L1: lwarx r0, 0, r3 + cmpw 0, r0, r4 + bne- L2 + stwcx. r5, 0, r3 + bne- L1 + L2: + cmpw cr7,r0,r4 + mfcr r3 + rlwinm r3,r3,31,1 + blr + + + .globl _pmix_atomic_cmpset_acq_32 +_pmix_atomic_cmpset_acq_32: + mflr r0 + std r29,-24(r1) + std r0,16(r1) + stdu r1,-144(r1) + bl _pmix_atomic_cmpset_32 + mr r29,r3 + bl _pmix_atomic_rmb + mr r3,r29 + addi r1,r1,144 + ld r0,16(r1) + mtlr r0 + ld r29,-24(r1) + blr + + + .globl _pmix_atomic_cmpset_rel_32 +_pmix_atomic_cmpset_rel_32: + mflr r0 + std r27,-40(r1) + std r28,-32(r1) + std r29,-24(r1) + std r0,16(r1) + stdu r1,-160(r1) + mr r29,r3 + mr r28,r4 + mr r27,r5 + bl _pmix_atomic_wmb + mr r3,r29 + mr r4,r28 + mr r5,r27 + bl _pmix_atomic_cmpset_32 + addi r1,r1,160 + ld r0,16(r1) + mtlr r0 + ld r27,-40(r1) + ld r28,-32(r1) + ld r29,-24(r1) + blr + + + .globl _pmix_atomic_cmpset_64 +_pmix_atomic_cmpset_64: + L3: ldarx r0, 0, r3 + cmpd 0, r0, r4 + bne- L4 + stdcx. r5, 0, r3 + bne- L3 + L4: + xor r3,r4,r0 + subfic r5,r3,0 + adde r3,r5,r3 + blr + + + .globl _pmix_atomic_cmpset_acq_64 +_pmix_atomic_cmpset_acq_64: + L7: ldarx r0, 0, r3 + cmpd 0, r0, r4 + bne- L8 + stdcx. r5, 0, r3 + bne- L7 + L8: + lwsync + xor r3,r4,r0 + subfic r5,r3,0 + adde r3,r5,r3 + blr + + + .globl _pmix_atomic_cmpset_rel_64 +_pmix_atomic_cmpset_rel_64: + eieio + L9: ldarx r0, 0, r3 + cmpd 0, r0, r4 + bne- L10 + stdcx. r5, 0, r3 + bne- L9 + L10: + xor r3,r4,r0 + subfic r5,r3,0 + adde r3,r5,r3 + blr + + + .globl _pmix_atomic_add_32 +_pmix_atomic_add_32: + L5: lwarx r0, 0, r3 + add r0, r4, r0 + stwcx. r0, 0, r3 + bne- L5 + + mr r3,r0 + blr + + + .globl _pmix_atomic_sub_32 +_pmix_atomic_sub_32: + L6: lwarx r0,0,r3 + subf r0,r4,r0 + stwcx. r0,0,r3 + bne- L6 + + mr r3,r0 + blr + + .globl _pmix_sys_timer_get_cycles +_pmix_sys_timer_get_cycles: + L11: + mftbu r2 + rldicl r2,r2,0,32 + mftb r0 + rldicl r9,r0,0,32 + mftbu r0 + rldicl r0,r0,0,32 + cmpw cr7,r0,r2 + bne cr7,L11 + sldi r3,r0,32 + or r3,r3,r9 + blr diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-sparcv9-32-solaris.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-sparcv9-32-solaris.s new file mode 100644 index 0000000000..3fb48494f6 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-sparcv9-32-solaris.s @@ -0,0 +1,190 @@ + .text + + .align 4 + + + .globl pmix_atomic_mb + .type pmix_atomic_mb, #function +pmix_atomic_mb: + !#PROLOGUE# 0 + !#PROLOGUE# 1 + membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad + retl + nop + .size pmix_atomic_mb, .-pmix_atomic_mb + + + .globl pmix_atomic_rmb + .type pmix_atomic_rmb, #function +pmix_atomic_rmb: + !#PROLOGUE# 0 + !#PROLOGUE# 1 + membar #LoadLoad + retl + nop + .size pmix_atomic_rmb, .-pmix_atomic_rmb + + + .globl pmix_atomic_wmb + .type pmix_atomic_wmb, #function +pmix_atomic_wmb: + !#PROLOGUE# 0 + !#PROLOGUE# 1 + membar #StoreStore + retl + nop + .size pmix_atomic_wmb, .-pmix_atomic_wmb + + + .globl pmix_atomic_cmpset_32 + .type pmix_atomic_cmpset_32, #function +pmix_atomic_cmpset_32: + !#PROLOGUE# 0 + !#PROLOGUE# 1 + casa [%o0] 0x80, %o1, %o2 + xor %o2, %o1, %o2 + subcc %g0, %o2, %g0 + retl + subx %g0, -1, %o0 + .size pmix_atomic_cmpset_32, .-pmix_atomic_cmpset_32 + + + .globl pmix_atomic_cmpset_acq_32 + .type pmix_atomic_cmpset_acq_32, #function +pmix_atomic_cmpset_acq_32: + !#PROLOGUE# 0 + !#PROLOGUE# 1 + casa [%o0] 0x80, %o1, %o2 + xor %o2, %o1, %o2 + subcc %g0, %o2, %g0 + subx %g0, -1, %o0 + membar #LoadLoad + retl + sra %o0, 0, %o0 + .size pmix_atomic_cmpset_acq_32, .-pmix_atomic_cmpset_acq_32 + + + .globl pmix_atomic_cmpset_rel_32 + .type pmix_atomic_cmpset_rel_32, #function +pmix_atomic_cmpset_rel_32: + !#PROLOGUE# 0 + !#PROLOGUE# 1 + membar #StoreStore + casa [%o0] 0x80, %o1, %o2 + xor %o2, %o1, %o2 + subcc %g0, %o2, %g0 + retl + subx %g0, -1, %o0 + .size pmix_atomic_cmpset_rel_32, .-pmix_atomic_cmpset_rel_32 + + + .globl pmix_atomic_cmpset_64 + .type pmix_atomic_cmpset_64, #function +pmix_atomic_cmpset_64: + !#PROLOGUE# 0 + save %sp, -128, %sp + !#PROLOGUE# 1 + mov %i3, %o4 + mov %i4, %o5 + st %i1, [%fp-32] + st %i2, [%fp-28] + std %o4, [%fp-24] + ldx [%fp-24], %g1 + ldx [%fp-32], %g2 + casxa [%i0] 0x80, %g2, %g1 + stx %g1, [%fp-24] + + ld [%fp-24], %i5 + ld [%fp-32], %g1 + cmp %i5, %g1 + bne .L12 + mov 0, %i0 + ld [%fp-20], %i2 + ld [%fp-28], %i1 + cmp %i2, %i1 + be,a .L12 + mov 1, %i0 +.L12: + ret + restore + .size pmix_atomic_cmpset_64, .-pmix_atomic_cmpset_64 + + + .globl pmix_atomic_cmpset_acq_64 + .type pmix_atomic_cmpset_acq_64, #function +pmix_atomic_cmpset_acq_64: + !#PROLOGUE# 0 + save %sp, -128, %sp + !#PROLOGUE# 1 + mov %i1, %o4 + mov %i2, %o5 + mov %i3, %o2 + mov %i4, %o3 + std %o4, [%fp-32] + std %o2, [%fp-24] + ldx [%fp-24], %g1 + ldx [%fp-32], %g2 + casxa [%i0] 0x80, %g2, %g1 + stx %g1, [%fp-24] + + ld [%fp-24], %i5 + ld [%fp-32], %g1 + cmp %i5, %g1 + bne .L16 + mov 0, %i0 + ld [%fp-20], %i2 + ld [%fp-28], %i1 + cmp %i2, %i1 + be,a .L16 + mov 1, %i0 +.L16: + membar #LoadLoad + ret + restore + .size pmix_atomic_cmpset_acq_64, .-pmix_atomic_cmpset_acq_64 + + + .globl pmix_atomic_cmpset_rel_64 + .type pmix_atomic_cmpset_rel_64, #function +pmix_atomic_cmpset_rel_64: + !#PROLOGUE# 0 + save %sp, -128, %sp + !#PROLOGUE# 1 + mov %i1, %o4 + mov %i2, %o5 + mov %i3, %o2 + mov %i4, %o3 + membar #StoreStore + std %o4, [%fp-32] + std %o2, [%fp-24] + ldx [%fp-24], %g1 + ldx [%fp-32], %g2 + casxa [%i0] 0x80, %g2, %g1 + stx %g1, [%fp-24] + + ld [%fp-24], %i5 + ld [%fp-32], %g1 + cmp %i5, %g1 + bne .L21 + mov 0, %i0 + ld [%fp-20], %i2 + ld [%fp-28], %i1 + cmp %i2, %i1 + be,a .L21 + mov 1, %i0 +.L21: + ret + restore + .size pmix_atomic_cmpset_rel_64, .-pmix_atomic_cmpset_rel_64 + + + .globl pmix_sys_timer_get_cycles + .type pmix_sys_timer_get_cycles, #function +pmix_sys_timer_get_cycles: + save %sp,-96,%sp + rd %tick,%o0 + srlx %o0,32,%o1 + or %g0,%o1,%i0 + ret ! Result = %i0 + restore %o0,0,%o1 + .size pmix_sys_timer_get_cycles, .-pmix_sys_timer_get_cycles diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-sparcv9-64-solaris.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-sparcv9-64-solaris.s new file mode 100644 index 0000000000..7aae1cb8ed --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-sparcv9-64-solaris.s @@ -0,0 +1,130 @@ + .text + + .align 4 + + + .globl pmix_atomic_mb + .type pmix_atomic_mb, #function +pmix_atomic_mb: + !#PROLOGUE# 0 + !#PROLOGUE# 1 + membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad + retl + nop + .size pmix_atomic_mb, .-pmix_atomic_mb + + + .globl pmix_atomic_rmb + .type pmix_atomic_rmb, #function +pmix_atomic_rmb: + !#PROLOGUE# 0 + !#PROLOGUE# 1 + membar #LoadLoad + retl + nop + .size pmix_atomic_rmb, .-pmix_atomic_rmb + + + .globl pmix_atomic_wmb + .type pmix_atomic_wmb, #function +pmix_atomic_wmb: + !#PROLOGUE# 0 + !#PROLOGUE# 1 + membar #StoreStore + retl + nop + .size pmix_atomic_wmb, .-pmix_atomic_wmb + + + .globl pmix_atomic_cmpset_32 + .type pmix_atomic_cmpset_32, #function +pmix_atomic_cmpset_32: + !#PROLOGUE# 0 + !#PROLOGUE# 1 + casa [%o0] 0x80, %o1, %o2 + xor %o2, %o1, %o2 + subcc %g0, %o2, %g0 + retl + subx %g0, -1, %o0 + .size pmix_atomic_cmpset_32, .-pmix_atomic_cmpset_32 + + + .globl pmix_atomic_cmpset_acq_32 + .type pmix_atomic_cmpset_acq_32, #function +pmix_atomic_cmpset_acq_32: + !#PROLOGUE# 0 + !#PROLOGUE# 1 + casa [%o0] 0x80, %o1, %o2 + xor %o2, %o1, %o2 + subcc %g0, %o2, %g0 + subx %g0, -1, %o0 + membar #LoadLoad + retl + sra %o0, 0, %o0 + .size pmix_atomic_cmpset_acq_32, .-pmix_atomic_cmpset_acq_32 + + + .globl pmix_atomic_cmpset_rel_32 + .type pmix_atomic_cmpset_rel_32, #function +pmix_atomic_cmpset_rel_32: + !#PROLOGUE# 0 + !#PROLOGUE# 1 + membar #StoreStore + casa [%o0] 0x80, %o1, %o2 + xor %o2, %o1, %o2 + subcc %g0, %o2, %g0 + retl + subx %g0, -1, %o0 + .size pmix_atomic_cmpset_rel_32, .-pmix_atomic_cmpset_rel_32 + + + .globl pmix_atomic_cmpset_64 + .type pmix_atomic_cmpset_64, #function +pmix_atomic_cmpset_64: + !#PROLOGUE# 0 + !#PROLOGUE# 1 + casxa [%o0] 0x80, %o1, %o2 + mov 0, %o0 + xor %o2, %o1, %o2 + retl + movre %o2, 1, %o0 + .size pmix_atomic_cmpset_64, .-pmix_atomic_cmpset_64 + + + .globl pmix_atomic_cmpset_acq_64 + .type pmix_atomic_cmpset_acq_64, #function +pmix_atomic_cmpset_acq_64: + !#PROLOGUE# 0 + !#PROLOGUE# 1 + casxa [%o0] 0x80, %o1, %o2 + mov 0, %o0 + xor %o2, %o1, %o2 + movre %o2, 1, %o0 + membar #LoadLoad + retl + sra %o0, 0, %o0 + .size pmix_atomic_cmpset_acq_64, .-pmix_atomic_cmpset_acq_64 + + + .globl pmix_atomic_cmpset_rel_64 + .type pmix_atomic_cmpset_rel_64, #function +pmix_atomic_cmpset_rel_64: + !#PROLOGUE# 0 + !#PROLOGUE# 1 + membar #StoreStore + casxa [%o0] 0x80, %o1, %o2 + mov 0, %o0 + xor %o2, %o1, %o2 + retl + movre %o2, 1, %o0 + .size pmix_atomic_cmpset_rel_64, .-pmix_atomic_cmpset_rel_64 + + + .globl pmix_sys_timer_get_cycles + .type pmix_sys_timer_get_cycles, #function +pmix_sys_timer_get_cycles: + save %sp,-176,%sp + rd %tick,%o0 + ret ! Result = %i0 + restore %o0,0,%o0 + .size pmix_sys_timer_get_cycles, .-pmix_sys_timer_get_cycles diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-x86_64-linux-nongas.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-x86_64-linux-nongas.s new file mode 100644 index 0000000000..85d19d9b1e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-x86_64-linux-nongas.s @@ -0,0 +1,63 @@ + .text + + .globl pmix_atomic_mb + .type pmix_atomic_mb, @function +pmix_atomic_mb: + pushq %rbp + movq %rsp, %rbp + leave + ret + .size pmix_atomic_mb, .-pmix_atomic_mb + + + .globl pmix_atomic_rmb + .type pmix_atomic_rmb, @function +pmix_atomic_rmb: + pushq %rbp + movq %rsp, %rbp + leave + ret + .size pmix_atomic_rmb, .-pmix_atomic_rmb + + + .globl pmix_atomic_wmb + .type pmix_atomic_wmb, @function +pmix_atomic_wmb: + pushq %rbp + movq %rsp, %rbp + leave + ret + .size pmix_atomic_wmb, .-pmix_atomic_wmb + + + .globl pmix_atomic_cmpset_32 + .type pmix_atomic_cmpset_32, @function +pmix_atomic_cmpset_32: + movl %esi, %eax + lock; cmpxchgl %edx,(%rdi) + sete %dl + movzbl %dl, %eax + ret + .size pmix_atomic_cmpset_32, .-pmix_atomic_cmpset_32 + + + .globl pmix_atomic_cmpset_64 + .type pmix_atomic_cmpset_64, @function +pmix_atomic_cmpset_64: + movq %rsi, %rax + lock; cmpxchgq %rdx,(%rdi) + sete %dl + movzbl %dl, %eax + ret + .size pmix_atomic_cmpset_64, .-pmix_atomic_cmpset_64 + + + .globl pmix_sys_timer_get_cycles + .type pmix_sys_timer_get_cycles, @function +pmix_sys_timer_get_cycles: + rdtsc + salq $32, %rdx + mov %eax, %eax + orq %rdx, %rax + ret + .size pmix_sys_timer_get_cycles, .-pmix_sys_timer_get_cycles diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-x86_64-linux.s b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-x86_64-linux.s new file mode 100644 index 0000000000..f60867c1ab --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/asm/generated/atomic-x86_64-linux.s @@ -0,0 +1,65 @@ + .text + + .globl pmix_atomic_mb + .type pmix_atomic_mb, @function +pmix_atomic_mb: + pushq %rbp + movq %rsp, %rbp + leave + ret + .size pmix_atomic_mb, .-pmix_atomic_mb + + + .globl pmix_atomic_rmb + .type pmix_atomic_rmb, @function +pmix_atomic_rmb: + pushq %rbp + movq %rsp, %rbp + leave + ret + .size pmix_atomic_rmb, .-pmix_atomic_rmb + + + .globl pmix_atomic_wmb + .type pmix_atomic_wmb, @function +pmix_atomic_wmb: + pushq %rbp + movq %rsp, %rbp + leave + ret + .size pmix_atomic_wmb, .-pmix_atomic_wmb + + + .globl pmix_atomic_cmpset_32 + .type pmix_atomic_cmpset_32, @function +pmix_atomic_cmpset_32: + movl %esi, %eax + lock; cmpxchgl %edx,(%rdi) + sete %dl + movzbl %dl, %eax + ret + .size pmix_atomic_cmpset_32, .-pmix_atomic_cmpset_32 + + + .globl pmix_atomic_cmpset_64 + .type pmix_atomic_cmpset_64, @function +pmix_atomic_cmpset_64: + movq %rsi, %rax + lock; cmpxchgq %rdx,(%rdi) + sete %dl + movzbl %dl, %eax + ret + .size pmix_atomic_cmpset_64, .-pmix_atomic_cmpset_64 + + + .globl pmix_sys_timer_get_cycles + .type pmix_sys_timer_get_cycles, @function +pmix_sys_timer_get_cycles: + rdtsc + salq $32, %rdx + mov %eax, %eax + orq %rdx, %rax + ret + .size pmix_sys_timer_get_cycles, .-pmix_sys_timer_get_cycles + + .section .note.GNU-stack,"",@progbits diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/Makefile.include new file mode 100644 index 0000000000..9f677e5e44 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/Makefile.include @@ -0,0 +1,44 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2011 Sandia National Laboratories. All rights reserved. +# Copyright (c) 2016 Los A.includeos National Security, LLC. All rights +# reserved. +# Copyright (c) 2017 Research Organization for Information Science +# and Technology (RIST). All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# This makefile.include does not stand on its own - it is included from src/Makefile.am + +headers += \ + atomics/sys/architecture.h \ + atomics/sys/atomic.h \ + atomics/sys/atomic_impl.h \ + atomics/sys/timer.h \ + atomics/sys/cma.h + +include atomics/sys/x86_64/Makefile.include +include atomics/sys/arm/Makefile.include +include atomics/sys/arm64/Makefile.include +include atomics/sys/ia32/Makefile.include +include atomics/sys/ia64/Makefile.include +include atomics/sys/mips/Makefile.include +include atomics/sys/powerpc/Makefile.include +include atomics/sys/sparcv9/Makefile.include +include atomics/sys/sync_builtin/Makefile.include +include atomics/sys/gcc_builtin/Makefile.include diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/architecture.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/architecture.h new file mode 100644 index 0000000000..244c966a16 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/architecture.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2011 Sandia National Laboratories. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2016 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2017 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/* + * List of supported architectures + */ + +#ifndef PMIX_SYS_ARCHITECTURE_H +#define PMIX_SYS_ARCHITECTURE_H + +/* Architectures */ +#define PMIX_UNSUPPORTED 0000 +#define PMIX_IA32 0010 +#define PMIX_IA64 0020 +#define PMIX_X86_64 0030 +#define PMIX_POWERPC32 0050 +#define PMIX_POWERPC64 0051 +#define PMIX_SPARC 0060 +#define PMIX_SPARCV9_32 0061 +#define PMIX_SPARCV9_64 0062 +#define PMIX_MIPS 0070 +#define PMIX_ARM 0100 +#define PMIX_ARM64 0101 +#define PMIX_S390 0110 +#define PMIX_S390X 0111 +#define PMIX_BUILTIN_SYNC 0200 +#define PMIX_BUILTIN_GCC 0202 +#define PMIX_BUILTIN_NO 0203 + +/* Formats */ +#define PMIX_DEFAULT 1000 /* standard for given architecture */ +#define PMIX_DARWIN 1001 /* Darwin / OS X on PowerPC */ +#define PMIX_PPC_LINUX 1002 /* Linux on PowerPC */ +#define PMIX_AIX 1003 /* AIX on Power / PowerPC */ + +#endif /* #ifndef PMIX_SYS_ARCHITECTURE_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm/Makefile.include new file mode 100644 index 0000000000..e25774e7fc --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm/Makefile.include @@ -0,0 +1,24 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2008 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# This makefile.am does not stand on its own - it is included from src/atomics/sys/include/Makefile.include + +headers += \ + atomics/sys/arm/atomic.h \ + atomics/sys/arm/timer.h diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm/atomic.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm/atomic.h new file mode 100644 index 0000000000..1ee246252a --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm/atomic.h @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2010 IBM Corporation. All rights reserved. + * Copyright (c) 2010 ARM ltd. All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/* + * ARMv5 and earlier lack robust atomic operations and therefore this file uses + * Linux kernel support where needed. The kernel also provides memory barriers + * and this file uses them for ARMv5 and earlier processors, which lack the + * memory barrier instruction. These kernel functions are available on kernel + * versions 2.6.15 and greater; using them will result in undefined behavior on + * older kernels. + * See Documentation/arm/kernel_user_helpers.txt in the kernel tree for details + */ + +#ifndef PMIX_SYS_ARCH_ATOMIC_H +#define PMIX_SYS_ARCH_ATOMIC_H 1 + +#if (PMIX_ASM_ARM_VERSION >= 7) + +#define PMIX_HAVE_ATOMIC_MEM_BARRIER 1 +/* use the DMB instruction if available... */ + +#define PMIXMB() __asm__ __volatile__ ("dmb" : : : "memory") +#define PMIXRMB() __asm__ __volatile__ ("dmb" : : : "memory") +#define PMIXWMB() __asm__ __volatile__ ("dmb" : : : "memory") + +#elif (PMIX_ASM_ARM_VERSION == 6) + +#define PMIX_HAVE_ATOMIC_MEM_BARRIER 1 +/* ...or the v6-specific equivalent... */ + +#define PMIXMB() __asm__ __volatile__ ("mcr p15, 0, r0, c7, c10, 5" : : : "memory") +#define PMIXRMB() MB() +#define PMIXWMB() MB() + +#else + +#define PMIX_HAVE_ATOMIC_MEM_BARRIER 1 +/* ...otherwise use the Linux kernel-provided barrier */ + +#define PMIXMB() (*((void (*)(void))(0xffff0fa0)))() +#define PMIXRMB() MB() +#define PMIXWMB() MB() + +#endif + +/********************************************************************** + * + * Memory Barriers + * + *********************************************************************/ + +#if (PMIX_HAVE_ATOMIC_MEM_BARRIER == 1) + +static inline +void pmix_atomic_mb(void) +{ + PMIXMB(); +} + + +static inline +void pmix_atomic_rmb(void) +{ + PMIXRMB(); +} + + +static inline +void pmix_atomic_wmb(void) +{ + PMIXWMB(); +} + +static inline +void pmix_atomic_isync(void) +{ +} + +#endif + + +/********************************************************************** + * + * Atomic math operations + * + *********************************************************************/ + +#if (PMIX_GCC_INLINE_ASSEMBLY && (PMIX_ASM_ARM_VERSION >= 6)) + +#define PMIX_HAVE_ATOMIC_CMPSET_32 1 +#define PMIX_HAVE_ATOMIC_MATH_32 1 +static inline int pmix_atomic_cmpset_32(volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + int32_t ret, tmp; + + __asm__ __volatile__ ( + "1: ldrex %0, [%2] \n" + " cmp %0, %3 \n" + " bne 2f \n" + " strex %1, %4, [%2] \n" + " cmp %1, #0 \n" + " bne 1b \n" + "2: \n" + + : "=&r" (ret), "=&r" (tmp) + : "r" (addr), "r" (oldval), "r" (newval) + : "cc", "memory"); + + return (ret == oldval); +} + +/* these two functions aren't inlined in the non-gcc case because then + there would be two function calls (since neither cmpset_32 nor + atomic_?mb can be inlined). Instead, we "inline" them by hand in + the assembly, meaning there is one function call overhead instead + of two */ +static inline int pmix_atomic_cmpset_acq_32(volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + int rc; + + rc = pmix_atomic_cmpset_32(addr, oldval, newval); + pmix_atomic_rmb(); + + return rc; +} + + +static inline int pmix_atomic_cmpset_rel_32(volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + pmix_atomic_wmb(); + return pmix_atomic_cmpset_32(addr, oldval, newval); +} + +#if (PMIX_ASM_SUPPORT_64BIT == 1) + +#define PMIX_HAVE_ATOMIC_CMPSET_64 1 +static inline int pmix_atomic_cmpset_64(volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + int64_t ret; + int tmp; + + + __asm__ __volatile__ ( + "1: ldrexd %0, %H0, [%2] \n" + " cmp %0, %3 \n" + " it eq \n" + " cmpeq %H0, %H3 \n" + " bne 2f \n" + " strexd %1, %4, %H4, [%2] \n" + " cmp %1, #0 \n" + " bne 1b \n" + "2: \n" + + : "=&r" (ret), "=&r" (tmp) + : "r" (addr), "r" (oldval), "r" (newval) + : "cc", "memory"); + + return (ret == oldval); +} + +/* these two functions aren't inlined in the non-gcc case because then + there would be two function calls (since neither cmpset_64 nor + atomic_?mb can be inlined). Instead, we "inline" them by hand in + the assembly, meaning there is one function call overhead instead + of two */ +static inline int pmix_atomic_cmpset_acq_64(volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + int rc; + + rc = pmix_atomic_cmpset_64(addr, oldval, newval); + pmix_atomic_rmb(); + + return rc; +} + + +static inline int pmix_atomic_cmpset_rel_64(volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + pmix_atomic_wmb(); + return pmix_atomic_cmpset_64(addr, oldval, newval); +} + +#endif + + +#define PMIX_HAVE_ATOMIC_ADD_32 1 +static inline int32_t pmix_atomic_add_32(volatile int32_t* v, int inc) +{ + int32_t t; + int tmp; + + __asm__ __volatile__( + "1: ldrex %0, [%2] \n" + " add %0, %0, %3 \n" + " strex %1, %0, [%2] \n" + " cmp %1, #0 \n" + " bne 1b \n" + + : "=&r" (t), "=&r" (tmp) + : "r" (v), "r" (inc) + : "cc", "memory"); + + + return t; +} + +#define PMIX_HAVE_ATOMIC_SUB_32 1 +static inline int32_t pmix_atomic_sub_32(volatile int32_t* v, int dec) +{ + int32_t t; + int tmp; + + __asm__ __volatile__( + "1: ldrex %0, [%2] \n" + " sub %0, %0, %3 \n" + " strex %1, %0, [%2] \n" + " cmp %1, #0 \n" + " bne 1b \n" + + : "=&r" (t), "=&r" (tmp) + : "r" (v), "r" (dec) + : "cc", "memory"); + + return t; +} + +#else /* PMIX_ASM_ARM_VERSION <=5 or no GCC inline assembly */ + +#define PMIX_HAVE_ATOMIC_CMPSET_32 1 +#define __kuser_cmpxchg (*((int (*)(int, int, volatile int*))(0xffff0fc0))) +static inline int pmix_atomic_cmpset_32(volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + return !(__kuser_cmpxchg(oldval, newval, addr)); +} + +static inline int pmix_atomic_cmpset_acq_32(volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + /* kernel function includes all necessary memory barriers */ + return pmix_atomic_cmpset_32(addr, oldval, newval); +} + +static inline int pmix_atomic_cmpset_rel_32(volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + /* kernel function includes all necessary memory barriers */ + return pmix_atomic_cmpset_32(addr, oldval, newval); +} + +#endif + +#endif /* ! PMIX_SYS_ARCH_ATOMIC_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm/timer.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm/timer.h new file mode 100644 index 0000000000..65532ac8a7 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm/timer.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2008 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_SYS_ARCH_TIMER_H +#define PMIX_SYS_ARCH_TIMER_H 1 + +#include + +typedef uint64_t pmix_timer_t; + +static inline pmix_timer_t +pmix_sys_timer_get_cycles(void) +{ + pmix_timer_t ret; + struct tms accurate_clock; + + times(&accurate_clock); + ret = accurate_clock.tms_utime + accurate_clock.tms_stime; + + return ret; +} + +#define PMIX_HAVE_SYS_TIMER_GET_CYCLES 1 + +#endif /* ! PMIX_SYS_ARCH_TIMER_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm64/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm64/Makefile.include new file mode 100644 index 0000000000..980c5fed3b --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm64/Makefile.include @@ -0,0 +1,24 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2008 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# This makefile.am does not stand on its own - it is included from pmix/include/Makefile.am + +headers += \ + atomics/sys/arm64/atomic.h \ + atomics/sys/arm64/timer.h diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm64/atomic.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm64/atomic.h new file mode 100644 index 0000000000..c48c9143d3 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm64/atomic.h @@ -0,0 +1,302 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2010 IBM Corporation. All rights reserved. + * Copyright (c) 2010 ARM ltd. All rights reserved. + * Copyright (c) 2016 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#if !defined(PMIX_SYS_ARCH_ATOMIC_H) + +#define PMIX_SYS_ARCH_ATOMIC_H 1 + +#if PMIX_GCC_INLINE_ASSEMBLY + +#define PMIX_HAVE_ATOMIC_MEM_BARRIER 1 +#define PMIX_HAVE_ATOMIC_LLSC_32 1 +#define PMIX_HAVE_ATOMIC_CMPSET_32 1 +#define PMIX_HAVE_ATOMIC_SWAP_32 1 +#define PMIX_HAVE_ATOMIC_MATH_32 1 +#define PMIX_HAVE_ATOMIC_CMPSET_64 1 +#define PMIX_HAVE_ATOMIC_SWAP_64 1 +#define PMIX_HAVE_ATOMIC_LLSC_64 1 +#define PMIX_HAVE_ATOMIC_ADD_32 1 +#define PMIX_HAVE_ATOMIC_SUB_32 1 +#define PMIX_HAVE_ATOMIC_ADD_64 1 +#define PMIX_HAVE_ATOMIC_SUB_64 1 + +#define PMIXMB() __asm__ __volatile__ ("dmb sy" : : : "memory") +#define PMIXRMB() __asm__ __volatile__ ("dmb ld" : : : "memory") +#define PMIXWMB() __asm__ __volatile__ ("dmb st" : : : "memory") + +/********************************************************************** + * + * Memory Barriers + * + *********************************************************************/ + +static inline void pmix_atomic_mb (void) +{ + PMIXMB(); +} + +static inline void pmix_atomic_rmb (void) +{ + PMIXRMB(); +} + +static inline void pmix_atomic_wmb (void) +{ + PMIXWMB(); +} + +static inline void pmix_atomic_isync (void) +{ + __asm__ __volatile__ ("isb"); +} + +/********************************************************************** + * + * Atomic math operations + * + *********************************************************************/ + +static inline int pmix_atomic_cmpset_32(volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + int32_t ret, tmp; + + __asm__ __volatile__ ("1: ldaxr %w0, [%2] \n" + " cmp %w0, %w3 \n" + " bne 2f \n" + " stxr %w1, %w4, [%2] \n" + " cbnz %w1, 1b \n" + "2: \n" + : "=&r" (ret), "=&r" (tmp) + : "r" (addr), "r" (oldval), "r" (newval) + : "cc", "memory"); + + return (ret == oldval); +} + +static inline int32_t pmix_atomic_swap_32(volatile int32_t *addr, int32_t newval) +{ + int32_t ret, tmp; + + __asm__ __volatile__ ("1: ldaxr %w0, [%2] \n" + " stlxr %w1, %w3, [%2] \n" + " cbnz %w1, 1b \n" + : "=&r" (ret), "=&r" (tmp) + : "r" (addr), "r" (newval) + : "cc", "memory"); + + return ret; +} + +/* these two functions aren't inlined in the non-gcc case because then + there would be two function calls (since neither cmpset_32 nor + atomic_?mb can be inlined). Instead, we "inline" them by hand in + the assembly, meaning there is one function call overhead instead + of two */ +static inline int pmix_atomic_cmpset_acq_32(volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + int32_t ret, tmp; + + __asm__ __volatile__ ("1: ldaxr %w0, [%2] \n" + " cmp %w0, %w3 \n" + " bne 2f \n" + " stxr %w1, %w4, [%2] \n" + " cbnz %w1, 1b \n" + "2: \n" + : "=&r" (ret), "=&r" (tmp) + : "r" (addr), "r" (oldval), "r" (newval) + : "cc", "memory"); + + return (ret == oldval); +} + + +static inline int pmix_atomic_cmpset_rel_32(volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + int32_t ret, tmp; + + __asm__ __volatile__ ("1: ldxr %w0, [%2] \n" + " cmp %w0, %w3 \n" + " bne 2f \n" + " stlxr %w1, %w4, [%2] \n" + " cbnz %w1, 1b \n" + "2: \n" + : "=&r" (ret), "=&r" (tmp) + : "r" (addr), "r" (oldval), "r" (newval) + : "cc", "memory"); + + return (ret == oldval); +} + +static inline int32_t pmix_atomic_ll_32 (volatile int32_t *addr) +{ + int32_t ret; + + __asm__ __volatile__ ("ldaxr %w0, [%1] \n" + : "=&r" (ret) + : "r" (addr)); + + return ret; +} + +static inline int pmix_atomic_sc_32 (volatile int32_t *addr, int32_t newval) +{ + int ret; + + __asm__ __volatile__ ("stlxr %w0, %w2, [%1] \n" + : "=&r" (ret) + : "r" (addr), "r" (newval) + : "cc", "memory"); + + return ret == 0; +} + +static inline int pmix_atomic_cmpset_64(volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + int64_t ret; + int tmp; + + __asm__ __volatile__ ("1: ldaxr %0, [%2] \n" + " cmp %0, %3 \n" + " bne 2f \n" + " stxr %w1, %4, [%2] \n" + " cbnz %w1, 1b \n" + "2: \n" + : "=&r" (ret), "=&r" (tmp) + : "r" (addr), "r" (oldval), "r" (newval) + : "cc", "memory"); + + return (ret == oldval); +} + +static inline int64_t pmix_atomic_swap_64 (volatile int64_t *addr, int64_t newval) +{ + int64_t ret; + int tmp; + + __asm__ __volatile__ ("1: ldaxr %0, [%2] \n" + " stlxr %w1, %3, [%2] \n" + " cbnz %w1, 1b \n" + : "=&r" (ret), "=&r" (tmp) + : "r" (addr), "r" (newval) + : "cc", "memory"); + + return ret; +} + +/* these two functions aren't inlined in the non-gcc case because then + there would be two function calls (since neither cmpset_64 nor + atomic_?mb can be inlined). Instead, we "inline" them by hand in + the assembly, meaning there is one function call overhead instead + of two */ +static inline int pmix_atomic_cmpset_acq_64(volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + int64_t ret; + int tmp; + + __asm__ __volatile__ ("1: ldaxr %0, [%2] \n" + " cmp %0, %3 \n" + " bne 2f \n" + " stxr %w1, %4, [%2] \n" + " cbnz %w1, 1b \n" + "2: \n" + : "=&r" (ret), "=&r" (tmp) + : "r" (addr), "r" (oldval), "r" (newval) + : "cc", "memory"); + + return (ret == oldval); +} + + +static inline int pmix_atomic_cmpset_rel_64(volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + int64_t ret; + int tmp; + + __asm__ __volatile__ ("1: ldxr %0, [%2] \n" + " cmp %0, %3 \n" + " bne 2f \n" + " stlxr %w1, %4, [%2] \n" + " cbnz %w1, 1b \n" + "2: \n" + : "=&r" (ret), "=&r" (tmp) + : "r" (addr), "r" (oldval), "r" (newval) + : "cc", "memory"); + + return (ret == oldval); +} + +static inline int64_t pmix_atomic_ll_64 (volatile int64_t *addr) +{ + int64_t ret; + + __asm__ __volatile__ ("ldaxr %0, [%1] \n" + : "=&r" (ret) + : "r" (addr)); + + return ret; +} + +static inline int pmix_atomic_sc_64 (volatile int64_t *addr, int64_t newval) +{ + int ret; + + __asm__ __volatile__ ("stlxr %w0, %2, [%1] \n" + : "=&r" (ret) + : "r" (addr), "r" (newval) + : "cc", "memory"); + + return ret == 0; +} + +#define PMIX_ASM_MAKE_ATOMIC(type, bits, name, inst, reg) \ + static inline type pmix_atomic_ ## name ## _ ## bits (volatile type *addr, type value) \ + { \ + type newval; \ + int32_t tmp; \ + \ + __asm__ __volatile__("1: ldxr %" reg "0, [%2] \n" \ + " " inst " %" reg "0, %" reg "0, %" reg "3 \n" \ + " stxr %w1, %" reg "0, [%2] \n" \ + " cbnz %w1, 1b \n" \ + : "=&r" (newval), "=&r" (tmp) \ + : "r" (addr), "r" (value) \ + : "cc", "memory"); \ + \ + return newval; \ + } + +PMIX_ASM_MAKE_ATOMIC(int32_t, 32, add, "add", "w") +PMIX_ASM_MAKE_ATOMIC(int32_t, 32, sub, "sub", "w") +PMIX_ASM_MAKE_ATOMIC(int64_t, 64, add, "add", "") +PMIX_ASM_MAKE_ATOMIC(int64_t, 64, sub, "sub", "") + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + +#endif /* ! PMIX_SYS_ARCH_ATOMIC_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm64/timer.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm64/timer.h new file mode 100644 index 0000000000..bacc4b919e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/arm64/timer.h @@ -0,0 +1,46 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2008 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2016 Broadcom Limited. All rights reserved. + * Copyright (c) 2016 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_SYS_ARCH_TIMER_H +#define PMIX_SYS_ARCH_TIMER_H 1 + +#include + +typedef uint64_t pmix_timer_t; + +static inline pmix_timer_t +pmix_sys_timer_get_cycles(void) +{ + pmix_timer_t ret; + + __asm__ __volatile__ ("isb" ::: "memory"); + __asm__ __volatile__ ("mrs %0, CNTVCT_EL0" : "=r" (ret)); + + return ret; +} + + +static inline pmix_timer_t +pmix_sys_timer_freq(void) +{ + pmix_timer_t freq; + __asm__ __volatile__ ("mrs %0, CNTFRQ_EL0" : "=r" (freq)); + return (pmix_timer_t)(freq); +} + +#define PMIX_HAVE_SYS_TIMER_GET_CYCLES 1 + +#endif /* ! PMIX_SYS_ARCH_TIMER_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/atomic.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/atomic.h new file mode 100644 index 0000000000..e18d2cb1a4 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/atomic.h @@ -0,0 +1,623 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright (c) 2011 Sandia National Laboratories. All rights reserved. + * Copyright (c) 2011-2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2017 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/** @file + * + * Atomic operations. + * + * This API is patterned after the FreeBSD kernel atomic interface + * (which is influenced by Intel's ia64 architecture). The + * FreeBSD interface is documented at + * + * http://www.freebsd.org/cgi/man.cgi?query=atomic&sektion=9 + * + * Only the necessary subset of functions are implemented here. + * + * The following #defines will be true / false based on + * assembly support: + * + * - \c PMIX_HAVE_ATOMIC_MEM_BARRIER atomic memory barriers + * - \c PMIX_HAVE_ATOMIC_SPINLOCKS atomic spinlocks + * - \c PMIX_HAVE_ATOMIC_MATH_32 if 32 bit add/sub/cmpset can be done "atomicly" + * - \c PMIX_HAVE_ATOMIC_MATH_64 if 64 bit add/sub/cmpset can be done "atomicly" + * + * Note that for the Atomic math, atomic add/sub may be implemented as + * C code using pmix_atomic_cmpset. The appearance of atomic + * operation will be upheld in these cases. + */ + +#ifndef PMIX_SYS_ATOMIC_H +#define PMIX_SYS_ATOMIC_H 1 + +#include "pmix_config.h" + +#include "src/atomics/sys/architecture.h" +#include "src/include/pmix_stdint.h" + +/* do some quick #define cleanup in cases where we are doing + testing... */ +#ifdef PMIX_DISABLE_INLINE_ASM +#undef PMIX_C_GCC_INLINE_ASSEMBLY +#define PMIX_C_GCC_INLINE_ASSEMBLY 0 +#undef PMIX_C_DEC_INLINE_ASSEMBLY +#define PMIX_C_DEC_INLINE_ASSEMBLY 0 +#undef PMIX_C_XLC_INLINE_ASSEMBLY +#define PMIX_C_XLC_INLINE_ASSEMBLY 0 +#endif + +/* define PMIX_{GCC,DEC,XLC}_INLINE_ASSEMBLY based on the + PMIX_C_{GCC,DEC,XLC}_INLINE_ASSEMBLY defines and whether we + are in C or C++ */ +#if defined(c_plusplus) || defined(__cplusplus) +/* We no longer support inline assembly for C++ as PMIX is a C-only interface */ +#define PMIX_GCC_INLINE_ASSEMBLY 0 +#define PMIX_DEC_INLINE_ASSEMBLY 0 +#define PMIX_XLC_INLINE_ASSEMBLY 0 +#else +#define PMIX_GCC_INLINE_ASSEMBLY PMIX_C_GCC_INLINE_ASSEMBLY +#define PMIX_DEC_INLINE_ASSEMBLY PMIX_C_DEC_INLINE_ASSEMBLY +#define PMIX_XLC_INLINE_ASSEMBLY PMIX_C_XLC_INLINE_ASSEMBLY +#endif + + +BEGIN_C_DECLS +/********************************************************************** + * + * Data structures for atomic ops + * + *********************************************************************/ +/** + * 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 pmix_atomic_lock_t { + union { + volatile int32_t 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 pmix_atomic_lock_t pmix_atomic_lock_t; + +/********************************************************************** + * + * Set or unset these macros in the architecture-specific atomic.h + * files if we need to specify them as inline or non-inline + * + *********************************************************************/ +#if !PMIX_GCC_INLINE_ASSEMBLY +#define PMIX_HAVE_INLINE_ATOMIC_MEM_BARRIER 0 +#define PMIX_HAVE_INLINE_ATOMIC_CMPSET_32 0 +#define PMIX_HAVE_INLINE_ATOMIC_CMPSET_64 0 +#define PMIX_HAVE_INLINE_ATOMIC_ADD_32 0 +#define PMIX_HAVE_INLINE_ATOMIC_SUB_32 0 +#define PMIX_HAVE_INLINE_ATOMIC_ADD_64 0 +#define PMIX_HAVE_INLINE_ATOMIC_SUB_64 0 +#define PMIX_HAVE_INLINE_ATOMIC_SWAP_32 0 +#define PMIX_HAVE_INLINE_ATOMIC_SWAP_64 0 +#else +#define PMIX_HAVE_INLINE_ATOMIC_MEM_BARRIER 1 +#define PMIX_HAVE_INLINE_ATOMIC_CMPSET_32 1 +#define PMIX_HAVE_INLINE_ATOMIC_CMPSET_64 1 +#define PMIX_HAVE_INLINE_ATOMIC_ADD_32 1 +#define PMIX_HAVE_INLINE_ATOMIC_SUB_32 1 +#define PMIX_HAVE_INLINE_ATOMIC_ADD_64 1 +#define PMIX_HAVE_INLINE_ATOMIC_SUB_64 1 +#define PMIX_HAVE_INLINE_ATOMIC_SWAP_32 1 +#define PMIX_HAVE_INLINE_ATOMIC_SWAP_64 1 +#endif + +/** + * Enumeration of lock states + */ +enum { + PMIX_ATOMIC_UNLOCKED = 0, + PMIX_ATOMIC_LOCKED = 1 +}; + +/********************************************************************** + * + * Load the appropriate architecture files and set some reasonable + * default values for our support + * + *********************************************************************/ +#if defined(DOXYGEN) +/* don't include system-level gorp when generating doxygen files */ +#elif PMIX_ASSEMBLY_BUILTIN == PMIX_BUILTIN_SYNC +#include "src/atomics/sys/sync_builtin/atomic.h" +#elif PMIX_ASSEMBLY_BUILTIN == PMIX_BUILTIN_GCC +#include "src/atomics/sys/gcc_builtin/atomic.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_X86_64 +#include "src/atomics/sys/x86_64/atomic.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_ARM +#include "src/atomics/sys/arm/atomic.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_ARM64 +#include "src/atomics/sys/arm64/atomic.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_IA32 +#include "src/atomics/sys/ia32/atomic.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_IA64 +#include "src/atomics/sys/ia64/atomic.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_MIPS +#include "src/atomics/sys/mips/atomic.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_POWERPC32 +#include "src/atomics/sys/powerpc/atomic.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_POWERPC64 +#include "src/atomics/sys/powerpc/atomic.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_SPARC +#include "src/atomics/sys/sparc/atomic.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_SPARCV9_32 +#include "src/atomics/sys/sparcv9/atomic.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_SPARCV9_64 +#include "src/atomics/sys/sparcv9/atomic.h" +#endif + +#ifndef DOXYGEN +/* compare and set operations can't really be emulated from software, + so if these defines aren't already set, they should be set to 0 + now */ +#ifndef PMIX_HAVE_ATOMIC_CMPSET_32 +#define PMIX_HAVE_ATOMIC_CMPSET_32 0 +#endif +#ifndef PMIX_HAVE_ATOMIC_CMPSET_64 +#define PMIX_HAVE_ATOMIC_CMPSET_64 0 +#endif +#ifndef PMIX_HAVE_ATOMIC_CMPSET_128 +#define PMIX_HAVE_ATOMIC_CMPSET_128 0 +#endif +#ifndef PMIX_HAVE_ATOMIC_LLSC_32 +#define PMIX_HAVE_ATOMIC_LLSC_32 0 +#endif +#ifndef PMIX_HAVE_ATOMIC_LLSC_64 +#define PMIX_HAVE_ATOMIC_LLSC_64 0 +#endif +#endif /* DOXYGEN */ + +/********************************************************************** + * + * Memory Barriers - defined here if running doxygen or have barriers + * but can't inline + * + *********************************************************************/ +#if !defined(PMIX_HAVE_ATOMIC_MEM_BARRIER) && !defined(DOXYGEN) +/* no way to emulate in C code */ +#define PMIX_HAVE_ATOMIC_MEM_BARRIER 0 +#endif + +#if defined(DOXYGEN) || PMIX_HAVE_ATOMIC_MEM_BARRIER +/** + * Memory barrier + * + * Will use system-specific features to instruct the processor and + * memory controller that all writes and reads that have been posted + * before the call to \c pmix_atomic_mb() must appear to have + * completed before the next read or write. + * + * \note This can have some expensive side effects, including flushing + * the pipeline, preventing the cpu from reordering instructions, and + * generally grinding the memory controller's performance. Use only + * if you need *both* read and write barriers. + */ + +#if PMIX_HAVE_INLINE_ATOMIC_MEM_BARRIER +static inline +#endif +void pmix_atomic_mb(void); + +/** + * Read memory barrier + * + * Use system-specific features to instruct the processor and memory + * conrtoller that all reads that have been posted before the call to + * \c pmix_atomic_rmb() must appear to have been completed before the + * next read. Nothing is said about the ordering of writes when using + * \c pmix_atomic_rmb(). + */ + +#if PMIX_HAVE_INLINE_ATOMIC_MEM_BARRIER +static inline +#endif +void pmix_atomic_rmb(void); + +/** + * Write memory barrier. + * + * Use system-specific features to instruct the processor and memory + * conrtoller that all writes that have been posted before the call to + * \c pmix_atomic_wmb() must appear to have been completed before the + * next write. Nothing is said about the ordering of reads when using + * \c pmix_atomic_wmb(). + */ + +#if PMIX_HAVE_INLINE_ATOMIC_MEM_BARRIER +static inline +#endif +void pmix_atomic_wmb(void); + +#endif /* defined(DOXYGEN) || PMIX_HAVE_ATOMIC_MEM_BARRIER */ + + +/********************************************************************** + * + * Atomic spinlocks - always inlined, if have atomic cmpset + * + *********************************************************************/ + +#if !defined(PMIX_HAVE_ATOMIC_SPINLOCKS) && !defined(DOXYGEN) +/* 0 is more like "pending" - we'll fix up at the end after all + the static inline functions are declared */ +#define PMIX_HAVE_ATOMIC_SPINLOCKS 0 +#endif + +#if defined(DOXYGEN) || PMIX_HAVE_ATOMIC_SPINLOCKS || (PMIX_HAVE_ATOMIC_CMPSET_32 || PMIX_HAVE_ATOMIC_CMPSET_64) + +/** + * Initialize a lock to value + * + * @param lock Address of the lock + * @param value Initial value to set lock to + */ +#if PMIX_HAVE_ATOMIC_SPINLOCKS == 0 +static inline +#endif +void pmix_atomic_init(pmix_atomic_lock_t* lock, int32_t value); + + +/** + * Try to acquire a lock. + * + * @param lock Address of the lock. + * @return 0 if the lock was acquired, 1 otherwise. + */ +#if PMIX_HAVE_ATOMIC_SPINLOCKS == 0 +static inline +#endif +int pmix_atomic_trylock(pmix_atomic_lock_t *lock); + + +/** + * Acquire a lock by spinning. + * + * @param lock Address of the lock. + */ +#if PMIX_HAVE_ATOMIC_SPINLOCKS == 0 +static inline +#endif +void pmix_atomic_lock(pmix_atomic_lock_t *lock); + + +/** + * Release a lock. + * + * @param lock Address of the lock. + */ +#if PMIX_HAVE_ATOMIC_SPINLOCKS == 0 +static inline +#endif +void pmix_atomic_unlock(pmix_atomic_lock_t *lock); + + +#if PMIX_HAVE_ATOMIC_SPINLOCKS == 0 +#undef PMIX_HAVE_ATOMIC_SPINLOCKS +#define PMIX_HAVE_ATOMIC_SPINLOCKS (PMIX_HAVE_ATOMIC_CMPSET_32 || PMIX_HAVE_ATOMIC_CMPSET_64) +#define PMIX_NEED_INLINE_ATOMIC_SPINLOCKS 1 +#endif + +#endif /* PMIX_HAVE_ATOMIC_SPINLOCKS */ + + +/********************************************************************** + * + * Atomic math operations + * + *********************************************************************/ +#if !defined(PMIX_HAVE_ATOMIC_CMPSET_32) && !defined(DOXYGEN) +#define PMIX_HAVE_ATOMIC_CMPSET_32 0 +#endif +#if defined(DOXYGEN) || PMIX_HAVE_ATOMIC_CMPSET_32 + +#if PMIX_HAVE_INLINE_ATOMIC_CMPSET_32 +static inline +#endif +int pmix_atomic_cmpset_32(volatile int32_t *addr, int32_t oldval, + int32_t newval); + +#if PMIX_HAVE_INLINE_ATOMIC_CMPSET_32 +static inline +#endif +int pmix_atomic_cmpset_acq_32(volatile int32_t *addr, int32_t oldval, + int32_t newval); + +#if PMIX_HAVE_INLINE_ATOMIC_CMPSET_32 +static inline +#endif +int pmix_atomic_cmpset_rel_32(volatile int32_t *addr, int32_t oldval, + int32_t newval); +#endif + + +#if !defined(PMIX_HAVE_ATOMIC_CMPSET_64) && !defined(DOXYGEN) +#define PMIX_HAVE_ATOMIC_CMPSET_64 0 +#endif +#if defined(DOXYGEN) || PMIX_HAVE_ATOMIC_CMPSET_64 + +#if PMIX_HAVE_INLINE_ATOMIC_CMPSET_64 +static inline +#endif +int pmix_atomic_cmpset_64(volatile int64_t *addr, int64_t oldval, + int64_t newval); + +#if PMIX_HAVE_INLINE_ATOMIC_CMPSET_64 +static inline +#endif +int pmix_atomic_cmpset_acq_64(volatile int64_t *addr, int64_t oldval, + int64_t newval); + +#if PMIX_HAVE_INLINE_ATOMIC_CMPSET_64 +static inline +#endif +int pmix_atomic_cmpset_rel_64(volatile int64_t *addr, int64_t oldval, + int64_t newval); + +#endif + +#if !defined(PMIX_HAVE_ATOMIC_MATH_32) && !defined(DOXYGEN) + /* define to 0 for these tests. WIll fix up later. */ + #define PMIX_HAVE_ATOMIC_MATH_32 0 +#endif + +#if defined(DOXYGEN) || PMIX_HAVE_ATOMIC_MATH_32 || PMIX_HAVE_ATOMIC_CMPSET_32 + +/* PMIX_HAVE_INLINE_ATOMIC_*_32 will be 1 if /atomic.h provides + a static inline version of it (in assembly). If we have to fall + back on cmpset 32, that too will be inline. */ +#if PMIX_HAVE_INLINE_ATOMIC_ADD_32 || (!defined(PMIX_HAVE_ATOMIC_ADD_32) && PMIX_HAVE_ATOMIC_CMPSET_32) +static inline +#endif +int32_t pmix_atomic_add_32(volatile int32_t *addr, int delta); + +/* PMIX_HAVE_INLINE_ATOMIC_*_32 will be 1 if /atomic.h provides + a static inline version of it (in assembly). If we have to fall + back to cmpset 32, that too will be inline. */ +#if PMIX_HAVE_INLINE_ATOMIC_SUB_32 || (!defined(PMIX_HAVE_ATOMIC_ADD_32) && PMIX_HAVE_ATOMIC_CMPSET_32) +static inline +#endif +int32_t pmix_atomic_sub_32(volatile int32_t *addr, int delta); + +#endif /* PMIX_HAVE_ATOMIC_MATH_32 */ + +#if ! PMIX_HAVE_ATOMIC_MATH_32 +/* fix up the value of pmix_have_atomic_math_32 to allow for C versions */ +#undef PMIX_HAVE_ATOMIC_MATH_32 +#define PMIX_HAVE_ATOMIC_MATH_32 PMIX_HAVE_ATOMIC_CMPSET_32 +#endif + +#ifndef PMIX_HAVE_ATOMIC_MATH_64 +/* define to 0 for these tests. WIll fix up later. */ +#define PMIX_HAVE_ATOMIC_MATH_64 0 +#endif + +#if defined(DOXYGEN) || PMIX_HAVE_ATOMIC_MATH_64 || PMIX_HAVE_ATOMIC_CMPSET_64 + +/* PMIX_HAVE_INLINE_ATOMIC_*_64 will be 1 if /atomic.h provides + a static inline version of it (in assembly). If we have to fall + back to cmpset 64, that too will be inline */ +#if PMIX_HAVE_INLINE_ATOMIC_ADD_64 || (!defined(PMIX_HAVE_ATOMIC_ADD_64) && PMIX_HAVE_ATOMIC_CMPSET_64) +static inline +#endif +int64_t pmix_atomic_add_64(volatile int64_t *addr, int64_t delta); + +/* PMIX_HAVE_INLINE_ATOMIC_*_64 will be 1 if /atomic.h provides + a static inline version of it (in assembly). If we have to fall + back to cmpset 64, that too will be inline */ +#if PMIX_HAVE_INLINE_ATOMIC_SUB_64 || (!defined(PMIX_HAVE_ATOMIC_ADD_64) && PMIX_HAVE_ATOMIC_CMPSET_64) +static inline +#endif +int64_t pmix_atomic_sub_64(volatile int64_t *addr, int64_t delta); + +#endif /* PMIX_HAVE_ATOMIC_MATH_32 */ + +#if ! PMIX_HAVE_ATOMIC_MATH_64 +/* fix up the value of pmix_have_atomic_math_64 to allow for C versions */ +#undef PMIX_HAVE_ATOMIC_MATH_64 +#define PMIX_HAVE_ATOMIC_MATH_64 PMIX_HAVE_ATOMIC_CMPSET_64 +#endif + +/* provide a size_t add/subtract. When in debug mode, make it an + * inline function so that we don't have any casts in the + * interface and can catch type errors. When not in debug mode, + * just make it a macro, so that there's no performance penalty + */ +#if defined(DOXYGEN) || PMIX_ENABLE_DEBUG +static inline size_t +pmix_atomic_add_size_t(volatile size_t *addr, int delta) +{ +#if SIZEOF_SIZE_T == 4 + return (size_t) pmix_atomic_add_32((int32_t*) addr, delta); +#elif SIZEOF_SIZE_T == 8 + return (size_t) pmix_atomic_add_64((int64_t*) addr, delta); +#else +#error "Unknown size_t size" +#endif +} +static inline size_t +pmix_atomic_sub_size_t(volatile size_t *addr, int delta) +{ +#if SIZEOF_SIZE_T == 4 + return (size_t) pmix_atomic_sub_32((int32_t*) addr, delta); +#elif SIZEOF_SIZE_T == 8 + return (size_t) pmix_atomic_sub_64((int64_t*) addr, delta); +#else +#error "Unknown size_t size" +#endif +} +#else +#if SIZEOF_SIZE_T == 4 +#define pmix_atomic_add_size_t(addr, delta) ((size_t) pmix_atomic_add_32((int32_t*) addr, delta)) +#define pmix_atomic_sub_size_t(addr, delta) ((size_t) pmix_atomic_sub_32((int32_t*) addr, delta)) +#elif SIZEOF_SIZE_T ==8 +#define pmix_atomic_add_size_t(addr, delta) ((size_t) pmix_atomic_add_64((int64_t*) addr, delta)) +#define pmix_atomic_sub_size_t(addr, delta) ((size_t) pmix_atomic_sub_64((int64_t*) addr, delta)) +#else +#error "Unknown size_t size" +#endif +#endif + +#if defined(DOXYGEN) || (PMIX_HAVE_ATOMIC_CMPSET_32 || PMIX_HAVE_ATOMIC_CMPSET_64) +/* these are always done with inline functions, so always mark as + static inline */ +static inline int pmix_atomic_cmpset_xx(volatile void* addr, int64_t oldval, + int64_t newval, size_t length); +static inline int pmix_atomic_cmpset_acq_xx(volatile void* addr, + int64_t oldval, int64_t newval, + size_t length); +static inline int pmix_atomic_cmpset_rel_xx(volatile void* addr, + int64_t oldval, int64_t newval, + size_t length); + +static inline int pmix_atomic_cmpset_ptr(volatile void* addr, + void* oldval, + void* newval); +static inline int pmix_atomic_cmpset_acq_ptr(volatile void* addr, + void* oldval, + void* newval); +static inline int pmix_atomic_cmpset_rel_ptr(volatile void* addr, + void* oldval, + void* newval); + +/** + * Atomic compare and set of pointer with relaxed semantics. This + * macro detect at compile time the type of the first argument and + * choose the correct function to be called. + * + * \note This macro should only be used for integer types. + * + * @param addr Address of . + * @param oldval Comparison value . + * @param newval New value to set if comparision is true . + * + * See pmix_atomic_cmpset_* for pseudo-code. + */ +#define pmix_atomic_cmpset( ADDR, OLDVAL, NEWVAL ) \ + pmix_atomic_cmpset_xx( (volatile void*)(ADDR), (intptr_t)(OLDVAL), \ + (intptr_t)(NEWVAL), sizeof(*(ADDR)) ) + +/** + * Atomic compare and set of pointer with acquire semantics. This + * macro detect at compile time the type of the first argument + * and choose the correct function to be called. + * + * \note This macro should only be used for integer types. + * + * @param addr Address of . + * @param oldval Comparison value . + * @param newval New value to set if comparision is true . + * + * See pmix_atomic_cmpset_acq_* for pseudo-code. + */ +#define pmix_atomic_cmpset_acq( ADDR, OLDVAL, NEWVAL ) \ + pmix_atomic_cmpset_acq_xx( (volatile void*)(ADDR), (int64_t)(OLDVAL), \ + (int64_t)(NEWVAL), sizeof(*(ADDR)) ) + + +/** + * Atomic compare and set of pointer with release semantics. This + * macro detect at compile time the type of the first argument + * and choose the correct function to b + * + * \note This macro should only be used for integer types. + * + * @param addr Address of . + * @param oldval Comparison value . + * @param newval New value to set if comparision is true . + * + * See pmix_atomic_cmpsetrel_* for pseudo-code. + */ +#define pmix_atomic_cmpset_rel( ADDR, OLDVAL, NEWVAL ) \ + pmix_atomic_cmpset_rel_xx( (volatile void*)(ADDR), (int64_t)(OLDVAL), \ + (int64_t)(NEWVAL), sizeof(*(ADDR)) ) + +#endif /* (PMIX_HAVE_ATOMIC_CMPSET_32 || PMIX_HAVE_ATOMIC_CMPSET_64) */ + +#if defined(DOXYGEN) || (PMIX_HAVE_ATOMIC_MATH_32 || PMIX_HAVE_ATOMIC_MATH_64) + +static inline void pmix_atomic_add_xx(volatile void* addr, + int32_t value, size_t length); +static inline void pmix_atomic_sub_xx(volatile void* addr, + int32_t value, size_t length); +#if SIZEOF_VOID_P == 4 && PMIX_HAVE_ATOMIC_CMPSET_32 +static inline int32_t pmix_atomic_add_ptr( volatile void* addr, void* delta ); +static inline int32_t pmix_atomic_sub_ptr( volatile void* addr, void* delta ); +#elif SIZEOF_VOID_P == 8 && PMIX_HAVE_ATOMIC_CMPSET_64 +static inline int64_t pmix_atomic_add_ptr( volatile void* addr, void* delta ); +static inline int64_t pmix_atomic_sub_ptr( volatile void* addr, void* delta ); +#else +#error Atomic arithmetic on pointers not supported +#endif + +/** + * Atomically increment the content depending on the type. This + * macro detect at compile time the type of the first argument + * and choose the correct function to be called. + * + * \note This macro should only be used for integer types. + * + * @param addr Address of + * @param delta Value to add (converted to ). + */ +#define pmix_atomic_add( ADDR, VALUE ) \ + pmix_atomic_add_xx( (volatile void*)(ADDR), (int32_t)(VALUE), \ + sizeof(*(ADDR)) ) + +/** + * Atomically decrement the content depending on the type. This + * macro detect at compile time the type of the first argument + * and choose the correct function to be called. + * + * \note This macro should only be used for integer types. + * + * @param addr Address of + * @param delta Value to substract (converted to ). + */ +#define pmix_atomic_sub( ADDR, VALUE ) \ + pmix_atomic_sub_xx( (volatile void*)(ADDR), (int32_t)(VALUE), \ + sizeof(*(ADDR)) ) + +#endif /* PMIX_HAVE_ATOMIC_MATH_32 || PMIX_HAVE_ATOMIC_MATH_64 */ + + +/* + * Include inline implementations of everything not defined directly + * in assembly + */ +#include "src/atomics/sys/atomic_impl.h" + +END_C_DECLS + +#endif /* PMIX_SYS_ATOMIC_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/atomic_impl.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/atomic_impl.h new file mode 100644 index 0000000000..62213e3a50 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/atomic_impl.h @@ -0,0 +1,439 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2014 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2010-2014 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2012-2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/* Inline C implementation of the functions defined in atomic.h */ + +#include + +/********************************************************************** + * + * Atomic math operations + * + * All the architectures provide a compare_and_set atomic operations. If + * they dont provide atomic additions and/or substractions then we can + * define these operations using the atomic compare_and_set. + * + * Some architectures do not provide support for the 64 bits + * atomic operations. Until we find a better solution let's just + * undefine all those functions if there is no 64 bit cmpset + * + *********************************************************************/ +#if PMIX_HAVE_ATOMIC_CMPSET_32 + +#if !defined(PMIX_HAVE_ATOMIC_SWAP_32) +#define PMIX_HAVE_ATOMIC_SWAP_32 1 +static inline int32_t pmix_atomic_swap_32(volatile int32_t *addr, + int32_t newval) +{ + int32_t old; + do { + old = *addr; + } while (0 == pmix_atomic_cmpset_32(addr, old, newval)); + + return old; +} +#endif /* PMIX_HAVE_ATOMIC_SWAP_32 */ + +#if !defined(PMIX_HAVE_ATOMIC_ADD_32) +#define PMIX_HAVE_ATOMIC_ADD_32 1 +static inline int32_t +pmix_atomic_add_32(volatile int32_t *addr, int delta) +{ + int32_t oldval; + + do { + oldval = *addr; + } while (0 == pmix_atomic_cmpset_32(addr, oldval, oldval + delta)); + return (oldval + delta); +} +#endif /* PMIX_HAVE_ATOMIC_ADD_32 */ + + +#if !defined(PMIX_HAVE_ATOMIC_SUB_32) +#define PMIX_HAVE_ATOMIC_SUB_32 1 +static inline int32_t +pmix_atomic_sub_32(volatile int32_t *addr, int delta) +{ + int32_t oldval; + + do { + oldval = *addr; + } while (0 == pmix_atomic_cmpset_32(addr, oldval, oldval - delta)); + return (oldval - delta); +} +#endif /* PMIX_HAVE_ATOMIC_SUB_32 */ + +#endif /* PMIX_HAVE_ATOMIC_CMPSET_32 */ + + +#if PMIX_HAVE_ATOMIC_CMPSET_64 + +#if !defined(PMIX_HAVE_ATOMIC_SWAP_64) +#define PMIX_HAVE_ATOMIC_SWAP_64 1 +static inline int64_t pmix_atomic_swap_64(volatile int64_t *addr, + int64_t newval) +{ + int64_t old; + do { + old = *addr; + } while (0 == pmix_atomic_cmpset_64(addr, old, newval)); + return old; +} +#endif /* PMIX_HAVE_ATOMIC_SWAP_32 */ + +#if !defined(PMIX_HAVE_ATOMIC_ADD_64) +#define PMIX_HAVE_ATOMIC_ADD_64 1 +static inline int64_t +pmix_atomic_add_64(volatile int64_t *addr, int64_t delta) +{ + int64_t oldval; + + do { + oldval = *addr; + } while (0 == pmix_atomic_cmpset_64(addr, oldval, oldval + delta)); + return (oldval + delta); +} +#endif /* PMIX_HAVE_ATOMIC_ADD_64 */ + + +#if !defined(PMIX_HAVE_ATOMIC_SUB_64) +#define PMIX_HAVE_ATOMIC_SUB_64 1 +static inline int64_t +pmix_atomic_sub_64(volatile int64_t *addr, int64_t delta) +{ + int64_t oldval; + + do { + oldval = *addr; + } while (0 == pmix_atomic_cmpset_64(addr, oldval, oldval - delta)); + return (oldval - delta); +} +#endif /* PMIX_HAVE_ATOMIC_SUB_64 */ + +#else + +#if !defined(PMIX_HAVE_ATOMIC_ADD_64) +#define PMIX_HAVE_ATOMIC_ADD_64 0 +#endif + +#if !defined(PMIX_HAVE_ATOMIC_SUB_64) +#define PMIX_HAVE_ATOMIC_SUB_64 0 +#endif + +#endif /* PMIX_HAVE_ATOMIC_CMPSET_64 */ + + +#if (PMIX_HAVE_ATOMIC_CMPSET_32 || PMIX_HAVE_ATOMIC_CMPSET_64) + +static inline int +pmix_atomic_cmpset_xx(volatile void* addr, int64_t oldval, + int64_t newval, size_t length) +{ + switch( length ) { +#if PMIX_HAVE_ATOMIC_CMPSET_32 + case 4: + return pmix_atomic_cmpset_32( (volatile int32_t*)addr, + (int32_t)oldval, (int32_t)newval ); +#endif /* PMIX_HAVE_ATOMIC_CMPSET_32 */ + +#if PMIX_HAVE_ATOMIC_CMPSET_64 + case 8: + return pmix_atomic_cmpset_64( (volatile int64_t*)addr, + (int64_t)oldval, (int64_t)newval ); +#endif /* PMIX_HAVE_ATOMIC_CMPSET_64 */ + } + abort(); + /* This should never happen, so deliberately abort (hopefully + leaving a corefile for analysis) */ +} + + +static inline int +pmix_atomic_cmpset_acq_xx(volatile void* addr, int64_t oldval, + int64_t newval, size_t length) +{ + switch( length ) { +#if PMIX_HAVE_ATOMIC_CMPSET_32 + case 4: + return pmix_atomic_cmpset_acq_32( (volatile int32_t*)addr, + (int32_t)oldval, (int32_t)newval ); +#endif /* PMIX_HAVE_ATOMIC_CMPSET_32 */ + +#if PMIX_HAVE_ATOMIC_CMPSET_64 + case 8: + return pmix_atomic_cmpset_acq_64( (volatile int64_t*)addr, + (int64_t)oldval, (int64_t)newval ); +#endif /* PMIX_HAVE_ATOMIC_CMPSET_64 */ + } + /* This should never happen, so deliberately abort (hopefully + leaving a corefile for analysis) */ + abort(); +} + + +static inline int +pmix_atomic_cmpset_rel_xx(volatile void* addr, int64_t oldval, + int64_t newval, size_t length) +{ + switch( length ) { +#if PMIX_HAVE_ATOMIC_CMPSET_32 + case 4: + return pmix_atomic_cmpset_rel_32( (volatile int32_t*)addr, + (int32_t)oldval, (int32_t)newval ); +#endif /* PMIX_HAVE_ATOMIC_CMPSET_32 */ + +#if PMIX_HAVE_ATOMIC_CMPSET_64 + case 8: + return pmix_atomic_cmpset_rel_64( (volatile int64_t*)addr, + (int64_t)oldval, (int64_t)newval ); +#endif /* PMIX_HAVE_ATOMIC_CMPSET_64 */ + } + /* This should never happen, so deliberately abort (hopefully + leaving a corefile for analysis) */ + abort(); +} + + +static inline int +pmix_atomic_cmpset_ptr(volatile void* addr, + void* oldval, + void* newval) +{ +#if SIZEOF_VOID_P == 4 && PMIX_HAVE_ATOMIC_CMPSET_32 + return pmix_atomic_cmpset_32((int32_t*) addr, (unsigned long) oldval, + (unsigned long) newval); +#elif SIZEOF_VOID_P == 8 && PMIX_HAVE_ATOMIC_CMPSET_64 + return pmix_atomic_cmpset_64((int64_t*) addr, (unsigned long) oldval, + (unsigned long) newval); +#else + abort(); +#endif +} + + +static inline int +pmix_atomic_cmpset_acq_ptr(volatile void* addr, + void* oldval, + void* newval) +{ +#if SIZEOF_VOID_P == 4 && PMIX_HAVE_ATOMIC_CMPSET_32 + return pmix_atomic_cmpset_acq_32((int32_t*) addr, (unsigned long) oldval, + (unsigned long) newval); +#elif SIZEOF_VOID_P == 8 && PMIX_HAVE_ATOMIC_CMPSET_64 + return pmix_atomic_cmpset_acq_64((int64_t*) addr, (unsigned long) oldval, + (unsigned long) newval); +#else + abort(); +#endif +} + + +static inline int pmix_atomic_cmpset_rel_ptr(volatile void* addr, + void* oldval, + void* newval) +{ +#if SIZEOF_VOID_P == 4 && PMIX_HAVE_ATOMIC_CMPSET_32 + return pmix_atomic_cmpset_rel_32((int32_t*) addr, (unsigned long) oldval, + (unsigned long) newval); +#elif SIZEOF_VOID_P == 8 && PMIX_HAVE_ATOMIC_CMPSET_64 + return pmix_atomic_cmpset_rel_64((int64_t*) addr, (unsigned long) oldval, + (unsigned long) newval); +#else + abort(); +#endif +} + +#endif /* (PMIX_HAVE_ATOMIC_CMPSET_32 || PMIX_HAVE_ATOMIC_CMPSET_64) */ + +#if (PMIX_HAVE_ATOMIC_SWAP_32 || PMIX_HAVE_ATOMIC_SWAP_64) + +#if SIZEOF_VOID_P == 4 && PMIX_HAVE_ATOMIC_SWAP_32 +#define pmix_atomic_swap_ptr(addr, value) (void *) pmix_atomic_swap_32((int32_t *) addr, (int32_t) value) +#elif SIZEOF_VOID_P == 8 && PMIX_HAVE_ATOMIC_SWAP_64 +#define pmix_atomic_swap_ptr(addr, value) (void *) pmix_atomic_swap_64((int64_t *) addr, (int64_t) value) +#endif + +#endif /* (PMIX_HAVE_ATOMIC_SWAP_32 || PMIX_HAVE_ATOMIC_SWAP_64) */ + +#if (PMIX_HAVE_ATOMIC_LLSC_32 || PMIX_HAVE_ATOMIC_LLSC_64) + +#if SIZEOF_VOID_P == 4 && PMIX_HAVE_ATOMIC_LLSC_32 + +#define pmix_atomic_ll_ptr(addr) (void *) pmix_atomic_ll_32((int32_t *) addr) +#define pmix_atomic_sc_ptr(addr, newval) pmix_atomic_sc_32((int32_t *) addr, (int32_t) newval) + +#define PMIX_HAVE_ATOMIC_LLSC_PTR 1 + +#elif SIZEOF_VOID_P == 8 && PMIX_HAVE_ATOMIC_LLSC_64 + +#define pmix_atomic_ll_ptr(addr) (void *) pmix_atomic_ll_64((int64_t *) addr) +#define pmix_atomic_sc_ptr(addr, newval) pmix_atomic_sc_64((int64_t *) addr, (int64_t) newval) + +#define PMIX_HAVE_ATOMIC_LLSC_PTR 1 + +#endif + +#endif /* (PMIX_HAVE_ATOMIC_LLSC_32 || PMIX_HAVE_ATOMIC_LLSC_64)*/ + +#if !defined(PMIX_HAVE_ATOMIC_LLSC_PTR) +#define PMIX_HAVE_ATOMIC_LLSC_PTR 0 +#endif + +#if PMIX_HAVE_ATOMIC_MATH_32 || PMIX_HAVE_ATOMIC_MATH_64 + + +static inline void +pmix_atomic_add_xx(volatile void* addr, int32_t value, size_t length) +{ + switch( length ) { +#if PMIX_HAVE_ATOMIC_ADD_32 + case 4: + pmix_atomic_add_32( (volatile int32_t*)addr, (int32_t)value ); + break; +#endif /* PMIX_HAVE_ATOMIC_CMPSET_32 */ + +#if PMIX_HAVE_ATOMIC_ADD_64 + case 8: + pmix_atomic_add_64( (volatile int64_t*)addr, (int64_t)value ); + break; +#endif /* PMIX_HAVE_ATOMIC_ADD_64 */ + default: + /* This should never happen, so deliberately abort (hopefully + leaving a corefile for analysis) */ + abort(); + } +} + + +static inline void +pmix_atomic_sub_xx(volatile void* addr, int32_t value, size_t length) +{ + switch( length ) { +#if PMIX_HAVE_ATOMIC_SUB_32 + case 4: + pmix_atomic_sub_32( (volatile int32_t*)addr, (int32_t)value ); + break; +#endif /* PMIX_HAVE_ATOMIC_SUB_32 */ + +#if PMIX_HAVE_ATOMIC_SUB_64 + case 8: + pmix_atomic_sub_64( (volatile int64_t*)addr, (int64_t)value ); + break; +#endif /* PMIX_HAVE_ATOMIC_SUB_64 */ + default: + /* This should never happen, so deliberately abort (hopefully + leaving a corefile for analysis) */ + abort(); + } +} + +#if SIZEOF_VOID_P == 4 && PMIX_HAVE_ATOMIC_ADD_32 +static inline int32_t pmix_atomic_add_ptr( volatile void* addr, + void* delta ) +{ + return pmix_atomic_add_32((int32_t*) addr, (unsigned long) delta); +} +#elif SIZEOF_VOID_P == 8 && PMIX_HAVE_ATOMIC_ADD_64 +static inline int64_t pmix_atomic_add_ptr( volatile void* addr, + void* delta ) +{ + return pmix_atomic_add_64((int64_t*) addr, (unsigned long) delta); +} +#else +static inline int32_t pmix_atomic_add_ptr( volatile void* addr, + void* delta ) +{ + abort(); + return 0; +} +#endif + +#if SIZEOF_VOID_P == 4 && PMIX_HAVE_ATOMIC_SUB_32 +static inline int32_t pmix_atomic_sub_ptr( volatile void* addr, + void* delta ) +{ + return pmix_atomic_sub_32((int32_t*) addr, (unsigned long) delta); +} +#elif SIZEOF_VOID_P == 8 && PMIX_HAVE_ATOMIC_SUB_32 +static inline int64_t pmix_atomic_sub_ptr( volatile void* addr, + void* delta ) +{ + return pmix_atomic_sub_64((int64_t*) addr, (unsigned long) delta); +} +#else +static inline int32_t pmix_atomic_sub_ptr( volatile void* addr, + void* delta ) +{ + abort(); + return 0; +} +#endif + +#endif /* PMIX_HAVE_ATOMIC_MATH_32 || PMIX_HAVE_ATOMIC_MATH_64 */ + +/********************************************************************** + * + * Atomic spinlocks + * + *********************************************************************/ +#ifdef PMIX_NEED_INLINE_ATOMIC_SPINLOCKS + +/* + * Lock initialization function. It set the lock to UNLOCKED. + */ +static inline void +pmix_atomic_init( pmix_atomic_lock_t* lock, int32_t value ) +{ + lock->u.lock = value; +} + + +static inline int +pmix_atomic_trylock(pmix_atomic_lock_t *lock) +{ + int ret = pmix_atomic_cmpset_acq_32( &(lock->u.lock), + PMIX_ATOMIC_UNLOCKED, PMIX_ATOMIC_LOCKED); + return (ret == 0) ? 1 : 0; +} + + +static inline void +pmix_atomic_lock(pmix_atomic_lock_t *lock) +{ + while( !pmix_atomic_cmpset_acq_32( &(lock->u.lock), + PMIX_ATOMIC_UNLOCKED, PMIX_ATOMIC_LOCKED) ) { + while (lock->u.lock == PMIX_ATOMIC_LOCKED) { + /* spin */ ; + } + } +} + + +static inline void +pmix_atomic_unlock(pmix_atomic_lock_t *lock) +{ + pmix_atomic_wmb(); + lock->u.lock=PMIX_ATOMIC_UNLOCKED; +} + +#endif /* PMIX_HAVE_ATOMIC_SPINLOCKS */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/cma.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/cma.h new file mode 100644 index 0000000000..df5bdb79d3 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/cma.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2011-2012 IBM Corporation. All rights reserved. + * Copyright (c) 2016 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2017 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + */ + +/** @file + * + * Cross Memory Attach syscall definitions. + * + * These are only needed temporarily until these new syscalls + * are incorporated into glibc + */ + +#ifndef PMIX_SYS_CMA_H +#define PMIX_SYS_CMA_H 1 + +#if !defined(PMIX_ASSEMBLY_ARCH) +/* need pmix_config.h for the assembly architecture */ +#include "pmix_config.h" +#endif + +#include "src/atomics/sys/architecture.h" + +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef __linux__ + +/* Cross Memory Attach is so far only supported under linux */ + +#if PMIX_ASSEMBLY_ARCH == PMIX_X86_64 +#define __NR_process_vm_readv 310 +#define __NR_process_vm_writev 311 +#elif PMIX_ASSEMBLY_ARCH == PMIX_IA32 +#define __NR_process_vm_readv 347 +#define __NR_process_vm_writev 348 +#elif PMIX_ASSEMBLY_ARCH == PMIX_IA64 +#define __NR_process_vm_readv 1332 +#define __NR_process_vm_writev 1333 +#elif PMIX_ASSEMBLY_ARCH == PMIX_POWERPC32 +#define __NR_process_vm_readv 351 +#define __NR_process_vm_writev 352 +#elif PMIX_ASSEMBLY_ARCH == PMIX_POWERPC64 +#define __NR_process_vm_readv 351 +#define __NR_process_vm_writev 352 +#elif PMIX_ASSEMBLY_ARCH == PMIX_ARM + +#define __NR_process_vm_readv 376 +#define __NR_process_vm_writev 377 + +#elif PMIX_ASSEMBLY_ARCH == PMIX_ARM64 + +/* ARM64 uses the asm-generic syscall numbers */ + +#define __NR_process_vm_readv 270 +#define __NR_process_vm_writev 271 + +#elif PMIX_ASSEMBLY_ARCH == PMIX_MIPS + +#if _MIPS_SIM == _MIPS_SIM_ABI64 + +#define __NR_process_vm_readv 5304 +#define __NR_process_vm_writev 5305 + +#elif _MIPS_SIM == _MIPS_SIM_NABI32 + +#define __NR_process_vm_readv 6309 +#define __NR_process_vm_writev 6310 + +#else + +#error "Unsupported MIPS architecture for process_vm_readv and process_vm_writev syscalls" + +#endif + +#elif PMIX_ASSEMBLY_ARCH == PMIX_S390 + +#define __NR_process_vm_readv 340 +#define __NR_process_vm_writev 341 + +#elif PMIX_ASSEMBLY_ARCH == PMIX_S390X + +#define __NR_process_vm_readv 340 +#define __NR_process_vm_writev 341 + +#else +#error "Unsupported architecture for process_vm_readv and process_vm_writev syscalls" +#endif + + +static inline ssize_t +process_vm_readv(pid_t pid, + const struct iovec *lvec, + unsigned long liovcnt, + const struct iovec *rvec, + unsigned long riovcnt, + unsigned long flags) +{ + return syscall(__NR_process_vm_readv, pid, lvec, liovcnt, rvec, riovcnt, flags); +} + +static inline ssize_t +process_vm_writev(pid_t pid, + const struct iovec *lvec, + unsigned long liovcnt, + const struct iovec *rvec, + unsigned long riovcnt, + unsigned long flags) +{ + return syscall(__NR_process_vm_writev, pid, lvec, liovcnt, rvec, riovcnt, flags); +} + +#endif /* __linux__ */ + +#endif /* PMIX_SYS_CMA_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/gcc_builtin/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/gcc_builtin/Makefile.include new file mode 100644 index 0000000000..a1476e748f --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/gcc_builtin/Makefile.include @@ -0,0 +1,26 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2009 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2011 Sandia National Laboratories. All rights reserved. +# Copyright (c) 2016 Los Alamos National Security, LLC. All rights +# reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# This makefile.am does not stand on its own - it is included from pmix/include/Makefile.am + +headers += \ + atomics/sys/gcc_builtin/atomic.h diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/gcc_builtin/atomic.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/gcc_builtin/atomic.h new file mode 100644 index 0000000000..b4d2536600 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/gcc_builtin/atomic.h @@ -0,0 +1,229 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2013 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2011 Sandia National Laboratories. All rights reserved. + * Copyright (c) 2014-2016 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2016 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_SYS_ARCH_ATOMIC_H +#define PMIX_SYS_ARCH_ATOMIC_H 1 + +#include + +/********************************************************************** + * + * Memory Barriers + * + *********************************************************************/ +#define PMIX_HAVE_ATOMIC_MEM_BARRIER 1 + +#define PMIX_HAVE_ATOMIC_MATH_32 1 +#define PMIX_HAVE_ATOMIC_CMPSET_32 1 +#define PMIX_HAVE_ATOMIC_ADD_32 1 +#define PMIX_HAVE_ATOMIC_SUB_32 1 +#define PMIX_HAVE_ATOMIC_SWAP_32 1 +#define PMIX_HAVE_ATOMIC_MATH_64 1 +#define PMIX_HAVE_ATOMIC_CMPSET_64 1 +#define PMIX_HAVE_ATOMIC_ADD_64 1 +#define PMIX_HAVE_ATOMIC_SUB_64 1 +#define PMIX_HAVE_ATOMIC_SWAP_64 1 + + +static inline void pmix_atomic_mb(void) +{ + __atomic_thread_fence (__ATOMIC_SEQ_CST); +} + +static inline void pmix_atomic_rmb(void) +{ + __atomic_thread_fence (__ATOMIC_ACQUIRE); +} + +static inline void pmix_atomic_wmb(void) +{ + __atomic_thread_fence (__ATOMIC_RELEASE); +} + +#define PMIXMB() pmix_atomic_mb() + +/********************************************************************** + * + * Atomic math operations + * + *********************************************************************/ + +/* + * Suppress numerous (spurious ?) warnings from Oracle Studio compilers + * see https://community.oracle.com/thread/3968347 + */ +#if defined(__SUNPRO_C) || defined(__SUNPRO_CC) +#pragma error_messages(off, E_ARG_INCOMPATIBLE_WITH_ARG_L) +#endif + +static inline int pmix_atomic_cmpset_acq_32( volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + return __atomic_compare_exchange_n (addr, &oldval, newval, false, + __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); +} + + +static inline int pmix_atomic_cmpset_rel_32( volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + return __atomic_compare_exchange_n (addr, &oldval, newval, false, + __ATOMIC_RELEASE, __ATOMIC_RELAXED); +} + +static inline int pmix_atomic_cmpset_32( volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + return __atomic_compare_exchange_n (addr, &oldval, newval, false, + __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); +} + +static inline int32_t pmix_atomic_swap_32 (volatile int32_t *addr, int32_t newval) +{ + int32_t oldval; + __atomic_exchange (addr, &newval, &oldval, __ATOMIC_RELAXED); + return oldval; +} + +static inline int32_t pmix_atomic_add_32(volatile int32_t *addr, int32_t delta) +{ + return __atomic_add_fetch (addr, delta, __ATOMIC_RELAXED); +} + +static inline int32_t pmix_atomic_sub_32(volatile int32_t *addr, int32_t delta) +{ + return __atomic_sub_fetch (addr, delta, __ATOMIC_RELAXED); +} + +static inline int pmix_atomic_cmpset_acq_64( volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + return __atomic_compare_exchange_n (addr, &oldval, newval, false, + __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); +} + +static inline int pmix_atomic_cmpset_rel_64( volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + return __atomic_compare_exchange_n (addr, &oldval, newval, false, + __ATOMIC_RELEASE, __ATOMIC_RELAXED); +} + + +static inline int pmix_atomic_cmpset_64( volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + return __atomic_compare_exchange_n (addr, &oldval, newval, false, + __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); +} + +static inline int64_t pmix_atomic_swap_64 (volatile int64_t *addr, int64_t newval) +{ + int64_t oldval; + __atomic_exchange (addr, &newval, &oldval, __ATOMIC_RELAXED); + return oldval; +} + +static inline int64_t pmix_atomic_add_64(volatile int64_t *addr, int64_t delta) +{ + return __atomic_add_fetch (addr, delta, __ATOMIC_RELAXED); +} + +static inline int64_t pmix_atomic_sub_64(volatile int64_t *addr, int64_t delta) +{ + return __atomic_sub_fetch (addr, delta, __ATOMIC_RELAXED); +} + +#if PMIX_HAVE_GCC_BUILTIN_CSWAP_INT128 + +#define PMIX_HAVE_ATOMIC_CMPSET_128 1 + +static inline int pmix_atomic_cmpset_128 (volatile pmix_int128_t *addr, + pmix_int128_t oldval, pmix_int128_t newval) +{ + return __atomic_compare_exchange_n (addr, &oldval, newval, false, + __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); +} + +#elif defined(PMIX_HAVE_SYNC_BUILTIN_CSWAP_INT128) && PMIX_HAVE_SYNC_BUILTIN_CSWAP_INT128 + +#define PMIX_HAVE_ATOMIC_CMPSET_128 1 + +/* __atomic version is not lock-free so use legacy __sync version */ + +static inline int pmix_atomic_cmpset_128 (volatile pmix_int128_t *addr, + pmix_int128_t oldval, pmix_int128_t newval) +{ + return __sync_bool_compare_and_swap (addr, oldval, newval); +} + +#endif + +#if defined(__HLE__) + +#include + +#define PMIX_HAVE_ATOMIC_SPINLOCKS 1 + +static inline void pmix_atomic_init (pmix_atomic_lock_t* lock, int32_t value) +{ + lock->u.lock = value; +} + +static inline int pmix_atomic_trylock(pmix_atomic_lock_t *lock) +{ + int ret = __atomic_exchange_n (&lock->u.lock, PMIX_ATOMIC_LOCKED, + __ATOMIC_ACQUIRE | __ATOMIC_HLE_ACQUIRE); + if (PMIX_ATOMIC_LOCKED == ret) { + /* abort the transaction */ + _mm_pause (); + return 1; + } + + return 0; +} + +static inline void pmix_atomic_lock (pmix_atomic_lock_t *lock) +{ + while (PMIX_ATOMIC_LOCKED == __atomic_exchange_n (&lock->u.lock, PMIX_ATOMIC_LOCKED, + __ATOMIC_ACQUIRE | __ATOMIC_HLE_ACQUIRE)) { + /* abort the transaction */ + _mm_pause (); + } +} + +static inline void pmix_atomic_unlock (pmix_atomic_lock_t *lock) +{ + __atomic_store_n (&lock->u.lock, PMIX_ATOMIC_UNLOCKED, + __ATOMIC_RELEASE | __ATOMIC_HLE_RELEASE); +} + +#endif + +#if defined(__SUNPRO_C) || defined(__SUNPRO_CC) +#pragma error_messages(default, E_ARG_INCOMPATIBLE_WITH_ARG_L) +#endif + +#endif /* ! PMIX_SYS_ARCH_ATOMIC_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia32/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia32/Makefile.include new file mode 100644 index 0000000000..799a43d7e9 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia32/Makefile.include @@ -0,0 +1,24 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# This makefile.am does not stand on its own - it is included from pmix/include/Makefile.am + +headers += \ + atomics/sys/ia32/atomic.h \ + atomics/sys/ia32/timer.h diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia32/atomic.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia32/atomic.h new file mode 100644 index 0000000000..85693ad996 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia32/atomic.h @@ -0,0 +1,223 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2010 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2007-2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * Copyright (c) 2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_SYS_ARCH_ATOMIC_H +#define PMIX_SYS_ARCH_ATOMIC_H 1 + +/* + * On ia32, we use cmpxchg. + */ + +#define PMIXSMPLOCK "lock; " +#define PMIXMB() __asm__ __volatile__("": : :"memory") + + +/********************************************************************** + * + * Define constants for IA32 + * + *********************************************************************/ +#define PMIX_HAVE_ATOMIC_MEM_BARRIER 1 + +#define PMIX_HAVE_ATOMIC_CMPSET_32 1 + +#define PMIX_HAVE_ATOMIC_MATH_32 1 +#define PMIX_HAVE_ATOMIC_ADD_32 1 +#define PMIX_HAVE_ATOMIC_SUB_32 1 + +#define PMIX_HAVE_ATOMIC_CMPSET_64 1 + +#undef PMIX_HAVE_INLINE_ATOMIC_CMPSET_64 +#define PMIX_HAVE_INLINE_ATOMIC_CMPSET_64 0 + +/********************************************************************** + * + * Memory Barriers + * + *********************************************************************/ +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline void pmix_atomic_mb(void) +{ + PMIXMB(); +} + + +static inline void pmix_atomic_rmb(void) +{ + PMIXMB(); +} + + +static inline void pmix_atomic_wmb(void) +{ + PMIXMB(); +} + +static inline void pmix_atomic_isync(void) +{ +} + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + + +/********************************************************************** + * + * Atomic math operations + * + *********************************************************************/ +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline int pmix_atomic_cmpset_32(volatile int32_t *addr, + int32_t oldval, + int32_t newval) +{ + unsigned char ret; + __asm__ __volatile__ ( + PMIXSMPLOCK "cmpxchgl %3,%2 \n\t" + "sete %0 \n\t" + : "=qm" (ret), "+a" (oldval), "+m" (*addr) + : "q"(newval) + : "memory", "cc"); + + return (int)ret; +} + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + +#define pmix_atomic_cmpset_acq_32 pmix_atomic_cmpset_32 +#define pmix_atomic_cmpset_rel_32 pmix_atomic_cmpset_32 + +#if PMIX_GCC_INLINE_ASSEMBLY + +#if 0 + +/* some versions of GCC won't let you use ebx period (even though they + should be able to save / restore for the life of the inline + assembly). For the beta, just use the non-inline version */ + +#ifndef ll_low /* GLIBC provides these somewhere, so protect */ +#define ll_low(x) *(((unsigned int*)&(x))+0) +#define ll_high(x) *(((unsigned int*)&(x))+1) +#endif + +/* On Linux the EBX register is used by the shared libraries + * to keep the global offset. In same time this register is + * required by the cmpxchg8b instruction (as an input parameter). + * This conflict force us to save the EBX before the cmpxchg8b + * and to restore it afterward. + */ +static inline int pmix_atomic_cmpset_64(volatile int64_t *addr, + int64_t oldval, + int64_t newval) +{ + /* + * Compare EDX:EAX with m64. If equal, set ZF and load ECX:EBX into + * m64. Else, clear ZF and load m64 into EDX:EAX. + */ + unsigned char ret; + + __asm__ __volatile__( + "push %%ebx \n\t" + "movl %4, %%ebx \n\t" + SMPLOCK "cmpxchg8b (%1) \n\t" + "sete %0 \n\t" + "pop %%ebx \n\t" + : "=qm"(ret) + : "D"(addr), "a"(ll_low(oldval)), "d"(ll_high(oldval)), + "r"(ll_low(newval)), "c"(ll_high(newval)) + : "cc", "memory", "ebx"); + return (int) ret; +} +#endif /* if 0 */ + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + +#define pmix_atomic_cmpset_acq_64 pmix_atomic_cmpset_64 +#define pmix_atomic_cmpset_rel_64 pmix_atomic_cmpset_64 + +#if PMIX_GCC_INLINE_ASSEMBLY + +#define PMIX_HAVE_ATOMIC_SWAP_32 1 + +static inline int32_t pmix_atomic_swap_32( volatile int32_t *addr, + int32_t newval) +{ + int32_t oldval; + + __asm__ __volatile__("xchg %1, %0" : + "=r" (oldval), "=m" (*addr) : + "0" (newval), "m" (*addr) : + "memory"); + return oldval; +} + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + + +#if PMIX_GCC_INLINE_ASSEMBLY + +/** + * atomic_add - add integer to atomic variable + * @i: integer value to add + * @v: pointer of type int + * + * Atomically adds @i to @v. + */ +static inline int32_t pmix_atomic_add_32(volatile int32_t* v, int i) +{ + int ret = i; + __asm__ __volatile__( + PMIXSMPLOCK "xaddl %1,%0" + :"+m" (*v), "+r" (ret) + : + :"memory", "cc" + ); + return (ret+i); +} + + +/** + * atomic_sub - subtract the atomic variable + * @i: integer value to subtract + * @v: pointer of type int + * + * Atomically subtracts @i from @v. + */ +static inline int32_t pmix_atomic_sub_32(volatile int32_t* v, int i) +{ + int ret = -i; + __asm__ __volatile__( + PMIXSMPLOCK "xaddl %1,%0" + :"+m" (*v), "+r" (ret) + : + :"memory", "cc" + ); + return (ret-i); +} + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + +#endif /* ! PMIX_SYS_ARCH_ATOMIC_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia32/timer.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia32/timer.h new file mode 100644 index 0000000000..5be92d4902 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia32/timer.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2014 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_SYS_ARCH_TIMER_H +#define PMIX_SYS_ARCH_TIMER_H 1 + + +typedef uint64_t pmix_timer_t; + +/* Using RDTSC(P) results in non-monotonic timers across cores */ +#undef PMIX_TIMER_MONOTONIC +#define PMIX_TIMER_MONOTONIC 0 + +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline pmix_timer_t +pmix_sys_timer_get_cycles(void) +{ + pmix_timer_t ret; + int tmp; + + __asm__ __volatile__( + "xchgl %%ebx, %1\n" + "cpuid\n" + "xchgl %%ebx, %1\n" + "rdtsc\n" + : "=A"(ret), "=r"(tmp) + :: "ecx"); + + return ret; +} + +#define PMIX_HAVE_SYS_TIMER_GET_CYCLES 1 + +#else + +pmix_timer_t pmix_sys_timer_get_cycles(void); + +#define PMIX_HAVE_SYS_TIMER_GET_CYCLES 1 + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + +#endif /* ! PMIX_SYS_ARCH_TIMER_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia64/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia64/Makefile.include new file mode 100644 index 0000000000..d1f4e5e4b6 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia64/Makefile.include @@ -0,0 +1,24 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# This makefile.am does not stand on its own - it is included from pmix/include/Makefile.am + +headers += \ + atomics/sys/ia64/atomic.h \ + atomics/sys/ia64/timer.h diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia64/atomic.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia64/atomic.h new file mode 100644 index 0000000000..ca8ce8dfdd --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia64/atomic.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_SYS_ARCH_ATOMIC_H +#define PMIX_SYS_ARCH_ATOMIC_H 1 + +/* + * On ia64, we use cmpxchg, which supports acquire/release semantics natively. + */ + + +#define PMIXMB() __asm__ __volatile__("mf": : :"memory") + + +/********************************************************************** + * + * Define constants for IA64 + * + *********************************************************************/ +#define PMIX_HAVE_ATOMIC_MEM_BARRIER 1 + +#define PMIX_HAVE_ATOMIC_CMPSET_32 1 +#define PMIX_HAVE_ATOMIC_CMPSET_64 1 + +/********************************************************************** + * + * Memory Barriers + * + *********************************************************************/ +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline void pmix_atomic_mb(void) +{ + PMIXMB(); +} + + +static inline void pmix_atomic_rmb(void) +{ + PMIXMB(); +} + + +static inline void pmix_atomic_wmb(void) +{ + PMIXMB(); +} + +static inline void pmix_atomic_isync(void) +{ +} + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + + +/********************************************************************** + * + * Atomic math operations + * + *********************************************************************/ +#if PMIX_GCC_INLINE_ASSEMBLY + +#define ia64_cmpxchg4_acq(ptr, new, old) \ +({ \ + __u64 ia64_intri_res; \ + ia64_intri_res; \ +}) + +static inline int pmix_atomic_cmpset_acq_32( volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + int64_t ret; + + __asm__ __volatile__ ("mov ar.ccv=%0;;" :: "rO"(oldval)); + __asm__ __volatile__ ("cmpxchg4.acq %0=[%1],%2,ar.ccv": + "=r"(ret) : "r"(addr), "r"(newval) : "memory"); + + return ((int32_t)ret == oldval); +} + + +static inline int pmix_atomic_cmpset_rel_32( volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + int64_t ret; + + __asm__ __volatile__ ("mov ar.ccv=%0;;" :: "rO"(oldval)); + __asm__ __volatile__ ("cmpxchg4.rel %0=[%1],%2,ar.ccv": + "=r"(ret) : "r"(addr), "r"(newval) : "memory"); + + return ((int32_t)ret == oldval); +} + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + + +#define pmix_atomic_cmpset_32 pmix_atomic_cmpset_acq_32 + +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline int pmix_atomic_cmpset_acq_64( volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + int64_t ret; + + __asm__ __volatile__ ("mov ar.ccv=%0;;" :: "rO"(oldval)); + __asm__ __volatile__ ("cmpxchg8.acq %0=[%1],%2,ar.ccv": + "=r"(ret) : "r"(addr), "r"(newval) : "memory"); + + return (ret == oldval); +} + + +static inline int pmix_atomic_cmpset_rel_64( volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + int64_t ret; + + __asm__ __volatile__ ("mov ar.ccv=%0;;" :: "rO"(oldval)); + __asm__ __volatile__ ("cmpxchg8.rel %0=[%1],%2,ar.ccv": + "=r"(ret) : "r"(addr), "r"(newval) : "memory"); + + return (ret == oldval); +} + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + +#define pmix_atomic_cmpset_64 pmix_atomic_cmpset_acq_64 + +#endif /* ! PMIX_SYS_ARCH_ATOMIC_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia64/timer.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia64/timer.h new file mode 100644 index 0000000000..5a33236592 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/ia64/timer.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_SYS_ARCH_TIMER_H +#define PMIX_SYS_ARCH_TIMER_H 1 + + +typedef uint64_t pmix_timer_t; + + +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline pmix_timer_t +pmix_sys_timer_get_cycles(void) +{ + pmix_timer_t ret; + + __asm__ __volatile__ ("mov %0=ar.itc" : "=r"(ret)); + + return ret; +} + +#define PMIX_HAVE_SYS_TIMER_GET_CYCLES 1 + +#else + +pmix_timer_t pmix_sys_timer_get_cycles(void); + +#define PMIX_HAVE_SYS_TIMER_GET_CYCLES 1 + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + +#endif /* ! PMIX_SYS_ARCH_TIMER_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/mips/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/mips/Makefile.include new file mode 100644 index 0000000000..f3916e581d --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/mips/Makefile.include @@ -0,0 +1,24 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2008 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# This makefile.am does not stand on its own - it is included from pmix/include/Makefile.am + +headers += \ + atomics/sys/mips/atomic.h \ + atomics/sys/mips/timer.h diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/mips/atomic.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/mips/atomic.h new file mode 100644 index 0000000000..2e0765d9e2 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/mips/atomic.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_SYS_ARCH_ATOMIC_H +#define PMIX_SYS_ARCH_ATOMIC_H 1 + + +/* BWB - FIX ME! */ +#ifdef __linux__ +#define PMIXMB() __asm__ __volatile__(".set mips2; sync; .set mips0": : :"memory") +#define PMIXRMB() __asm__ __volatile__(".set mips2; sync; .set mips0": : :"memory") +#define PMIXWMB() __asm__ __volatile__(".set mips2; sync; .set mips0": : :"memory") +#define PMIXSMP_SYNC ".set mips2; sync; .set mips0" +#else +#define PMIXMB() __asm__ __volatile__("sync": : :"memory") +#define PMIXRMB() __asm__ __volatile__("sync": : :"memory") +#define PMIXWMB() __asm__ __volatile__("sync": : :"memory") +#define PMIXSMP_SYNC "sync" +#endif + + +/********************************************************************** + * + * Define constants for MIPS + * + *********************************************************************/ +#define PMIX_HAVE_ATOMIC_MEM_BARRIER 1 + +#define PMIX_HAVE_ATOMIC_CMPSET_32 1 + +#ifdef __mips64 +#define PMIX_HAVE_ATOMIC_CMPSET_64 1 +#endif + +/********************************************************************** + * + * Memory Barriers + * + *********************************************************************/ +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline +void pmix_atomic_mb(void) +{ + PMIXMB(); +} + + +static inline +void pmix_atomic_rmb(void) +{ + PMIXRMB(); +} + + +static inline +void pmix_atomic_wmb(void) +{ + PMIXWMB(); +} + +static inline +void pmix_atomic_isync(void) +{ +} + +#endif + +/********************************************************************** + * + * Atomic math operations + * + *********************************************************************/ +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline int pmix_atomic_cmpset_32(volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + int32_t ret; + + __asm__ __volatile__ (".set noreorder \n" + ".set noat \n" + "1: \n" +#ifdef __linux__ + ".set mips2 \n\t" +#endif + "ll %0, %2 \n" /* load *addr into ret */ + "bne %0, %z3, 2f \n" /* done if oldval != ret */ + "or $1, %z4, 0 \n" /* tmp = newval (delay slot) */ + "sc $1, %2 \n" /* store tmp in *addr */ +#ifdef __linux__ + ".set mips0 \n\t" +#endif + /* note: ret will be 0 if failed, 1 if succeeded */ + "beqz $1, 1b \n" /* if 0 jump back to 1b */ + "nop \n" /* fill delay slots */ + "2: \n" + ".set reorder \n" + : "=&r"(ret), "=m"(*addr) + : "m"(*addr), "r"(oldval), "r"(newval) + : "cc", "memory"); + return (ret == oldval); +} + + +/* these two functions aren't inlined in the non-gcc case because then + there would be two function calls (since neither cmpset_32 nor + atomic_?mb can be inlined). Instead, we "inline" them by hand in + the assembly, meaning there is one function call overhead instead + of two */ +static inline int pmix_atomic_cmpset_acq_32(volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + int rc; + + rc = pmix_atomic_cmpset_32(addr, oldval, newval); + pmix_atomic_rmb(); + + return rc; +} + + +static inline int pmix_atomic_cmpset_rel_32(volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + pmix_atomic_wmb(); + return pmix_atomic_cmpset_32(addr, oldval, newval); +} + +#ifdef PMIX_HAVE_ATOMIC_CMPSET_64 +static inline int pmix_atomic_cmpset_64(volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + int64_t ret; + + __asm__ __volatile__ (".set noreorder \n" + ".set noat \n" + "1: \n\t" + "lld %0, %2 \n\t" /* load *addr into ret */ + "bne %0, %z3, 2f \n\t" /* done if oldval != ret */ + "or $1, %4, 0 \n\t" /* tmp = newval (delay slot) */ + "scd $1, %2 \n\t" /* store tmp in *addr */ + /* note: ret will be 0 if failed, 1 if succeeded */ + "beqz $1, 1b \n\t" /* if 0 jump back to 1b */ + "nop \n\t" /* fill delay slot */ + "2: \n\t" + ".set reorder \n" + : "=&r" (ret), "=m" (*addr) + : "m" (*addr), "r" (oldval), "r" (newval) + : "cc", "memory"); + + return (ret == oldval); +} + + +/* these two functions aren't inlined in the non-gcc case because then + there would be two function calls (since neither cmpset_64 nor + atomic_?mb can be inlined). Instead, we "inline" them by hand in + the assembly, meaning there is one function call overhead instead + of two */ +static inline int pmix_atomic_cmpset_acq_64(volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + int rc; + + rc = pmix_atomic_cmpset_64(addr, oldval, newval); + pmix_atomic_rmb(); + + return rc; +} + + +static inline int pmix_atomic_cmpset_rel_64(volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + pmix_atomic_wmb(); + return pmix_atomic_cmpset_64(addr, oldval, newval); +} +#endif /* PMIX_HAVE_ATOMIC_CMPSET_64 */ + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + +#endif /* ! PMIX_SYS_ARCH_ATOMIC_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/mips/timer.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/mips/timer.h new file mode 100644 index 0000000000..65532ac8a7 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/mips/timer.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2008 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_SYS_ARCH_TIMER_H +#define PMIX_SYS_ARCH_TIMER_H 1 + +#include + +typedef uint64_t pmix_timer_t; + +static inline pmix_timer_t +pmix_sys_timer_get_cycles(void) +{ + pmix_timer_t ret; + struct tms accurate_clock; + + times(&accurate_clock); + ret = accurate_clock.tms_utime + accurate_clock.tms_stime; + + return ret; +} + +#define PMIX_HAVE_SYS_TIMER_GET_CYCLES 1 + +#endif /* ! PMIX_SYS_ARCH_TIMER_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/powerpc/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/powerpc/Makefile.include new file mode 100644 index 0000000000..fee4119deb --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/powerpc/Makefile.include @@ -0,0 +1,24 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# This makefile.am does not stand on its own - it is included from pmix/include/Makefile.am + +headers += \ + atomics/sys/powerpc/atomic.h \ + atomics/sys/powerpc/timer.h diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/powerpc/atomic.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/powerpc/atomic.h new file mode 100644 index 0000000000..98fbccbbfc --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/powerpc/atomic.h @@ -0,0 +1,464 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2010 IBM Corporation. All rights reserved. + * Copyright (c) 2015-2016 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_SYS_ARCH_ATOMIC_H +#define PMIX_SYS_ARCH_ATOMIC_H 1 + +/* + * On powerpc ... + */ + +#define PMIXMB() __asm__ __volatile__ ("sync" : : : "memory") +#define PMIXRMB() __asm__ __volatile__ ("lwsync" : : : "memory") +#define PMIXWMB() __asm__ __volatile__ ("eieio" : : : "memory") +#define PMIXISYNC() __asm__ __volatile__ ("isync" : : : "memory") +#define PMIXSMP_SYNC "sync \n\t" +#define PMIXSMP_ISYNC "\n\tisync" + + +/********************************************************************** + * + * Define constants for PowerPC 32 + * + *********************************************************************/ +#define PMIX_HAVE_ATOMIC_MEM_BARRIER 1 + +#define PMIX_HAVE_ATOMIC_CMPSET_32 1 +#define PMIX_HAVE_ATOMIC_SWAP_32 1 +#define PMIX_HAVE_ATOMIC_LLSC_32 1 + +#define PMIX_HAVE_ATOMIC_MATH_32 1 +#define PMIX_HAVE_ATOMIC_ADD_32 1 +#define PMIX_HAVE_ATOMIC_SUB_32 1 + + +#if (PMIX_ASSEMBLY_ARCH == PMIX_POWERPC64) || PMIX_ASM_SUPPORT_64BIT +#define PMIX_HAVE_ATOMIC_CMPSET_64 1 +#define PMIX_HAVE_ATOMIC_SWAP_64 1 +#define PMIX_HAVE_ATOMIC_LLSC_64 1 +#define PMIX_HAVE_ATOMIC_MATH_64 1 +#define PMIX_HAVE_ATOMIC_ADD_64 1 +#define PMIX_HAVE_ATOMIC_SUB_64 1 +#endif + + +/********************************************************************** + * + * Memory Barriers + * + *********************************************************************/ +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline +void pmix_atomic_mb(void) +{ + PMIXMB(); +} + + +static inline +void pmix_atomic_rmb(void) +{ + PMIXRMB(); +} + + +static inline +void pmix_atomic_wmb(void) +{ + PMIXRMB(); +} + +static inline +void pmix_atomic_isync(void) +{ + PMIXISYNC(); +} + +#elif PMIX_XLC_INLINE_ASSEMBLY /* end PMIX_GCC_INLINE_ASSEMBLY */ + +/* Yeah, I don't know who thought this was a reasonable syntax for + * inline assembly. Do these because they are used so often and they + * are fairly simple (aka: there is a tech pub on IBM's web site + * containing the right hex for the instructions). + */ + +#undef PMIX_HAVE_INLINE_ATOMIC_MEM_BARRIER +#define PMIX_HAVE_INLINE_ATOMIC_MEM_BARRIER 0 + +#pragma mc_func pmix_atomic_mb { "7c0004ac" } /* sync */ +#pragma reg_killed_by pmix_atomic_mb /* none */ + +#pragma mc_func pmix_atomic_rmb { "7c2004ac" } /* lwsync */ +#pragma reg_killed_by pmix_atomic_rmb /* none */ + +#pragma mc_func pmix_atomic_wmb { "7c0006ac" } /* eieio */ +#pragma reg_killed_by pmix_atomic_wmb /* none */ + +#endif + +/********************************************************************** + * + * Atomic math operations + * + *********************************************************************/ +#if PMIX_GCC_INLINE_ASSEMBLY + +#ifdef __xlC__ +/* work-around bizzare xlc bug in which it sign-extends + a pointer to a 32-bit signed integer */ +#define PMIX_ASM_ADDR(a) ((uintptr_t)a) +#else +#define PMIX_ASM_ADDR(a) (a) +#endif + +#if defined(__PGI) +/* work-around for bug in PGI 16.5-16.7 where the compiler fails to + * correctly emit load instructions for 64-bit operands. without this + * it will emit lwz instead of ld to load the 64-bit operand. */ +#define PMIX_ASM_VALUE64(x) (void *)(intptr_t) (x) +#else +#define PMIX_ASM_VALUE64(x) x +#endif + + +static inline int pmix_atomic_cmpset_32(volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + int32_t ret; + + __asm__ __volatile__ ( + "1: lwarx %0, 0, %2 \n\t" + " cmpw 0, %0, %3 \n\t" + " bne- 2f \n\t" + " stwcx. %4, 0, %2 \n\t" + " bne- 1b \n\t" + "2:" + : "=&r" (ret), "=m" (*addr) + : "r" PMIX_ASM_ADDR(addr), "r" (oldval), "r" (newval), "m" (*addr) + : "cc", "memory"); + + return (ret == oldval); +} + +static inline int32_t pmix_atomic_ll_32 (volatile int32_t *addr) +{ + int32_t ret; + + __asm__ __volatile__ ("lwarx %0, 0, %1 \n\t" + : "=&r" (ret) + : "r" (addr) + ); + return ret; +} + +static inline int pmix_atomic_sc_32 (volatile int32_t *addr, int32_t newval) +{ + int32_t ret, foo; + + __asm__ __volatile__ (" stwcx. %4, 0, %3 \n\t" + " li %0,0 \n\t" + " bne- 1f \n\t" + " ori %0,%0,1 \n\t" + "1:" + : "=r" (ret), "=m" (*addr), "=r" (foo) + : "r" (addr), "r" (newval) + : "cc", "memory"); + return ret; +} + +/* these two functions aren't inlined in the non-gcc case because then + there would be two function calls (since neither cmpset_32 nor + atomic_?mb can be inlined). Instead, we "inline" them by hand in + the assembly, meaning there is one function call overhead instead + of two */ +static inline int pmix_atomic_cmpset_acq_32(volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + int rc; + + rc = pmix_atomic_cmpset_32(addr, oldval, newval); + pmix_atomic_rmb(); + + return rc; +} + + +static inline int pmix_atomic_cmpset_rel_32(volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + pmix_atomic_wmb(); + return pmix_atomic_cmpset_32(addr, oldval, newval); +} + +static inline int32_t pmix_atomic_swap_32(volatile int32_t *addr, int32_t newval) +{ + int32_t ret; + + __asm__ __volatile__ ("1: lwarx %0, 0, %2 \n\t" + " stwcx. %3, 0, %2 \n\t" + " bne- 1b \n\t" + : "=&r" (ret), "=m" (*addr) + : "r" (addr), "r" (newval) + : "cc", "memory"); + + return ret; +} + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + + +#if (PMIX_ASSEMBLY_ARCH == PMIX_POWERPC64) + +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline int64_t pmix_atomic_add_64 (volatile int64_t* v, int64_t inc) +{ + int64_t t; + + __asm__ __volatile__("1: ldarx %0, 0, %3 \n\t" + " add %0, %2, %0 \n\t" + " stdcx. %0, 0, %3 \n\t" + " bne- 1b \n\t" + : "=&r" (t), "=m" (*v) + : "r" (PMIX_ASM_VALUE64(inc)), "r" PMIX_ASM_ADDR(v), "m" (*v) + : "cc"); + + return t; +} + + +static inline int64_t pmix_atomic_sub_64 (volatile int64_t* v, int64_t dec) +{ + int64_t t; + + __asm__ __volatile__( + "1: ldarx %0,0,%3 \n\t" + " subf %0,%2,%0 \n\t" + " stdcx. %0,0,%3 \n\t" + " bne- 1b \n\t" + : "=&r" (t), "=m" (*v) + : "r" (PMIX_ASM_VALUE64(dec)), "r" PMIX_ASM_ADDR(v), "m" (*v) + : "cc"); + + return t; +} + +static inline int pmix_atomic_cmpset_64(volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + int64_t ret; + + __asm__ __volatile__ ( + "1: ldarx %0, 0, %2 \n\t" + " cmpd 0, %0, %3 \n\t" + " bne- 2f \n\t" + " stdcx. %4, 0, %2 \n\t" + " bne- 1b \n\t" + "2:" + : "=&r" (ret), "=m" (*addr) + : "r" (addr), "r" (PMIX_ASM_VALUE64(oldval)), "r" (PMIX_ASM_VALUE64(newval)), "m" (*addr) + : "cc", "memory"); + + return (ret == oldval); +} + +static inline int64_t pmix_atomic_ll_64(volatile int64_t *addr) +{ + int64_t ret; + + __asm__ __volatile__ ("ldarx %0, 0, %1 \n\t" + : "=&r" (ret) + : "r" (addr) + ); + return ret; +} + +static inline int pmix_atomic_sc_64(volatile int64_t *addr, int64_t newval) +{ + int32_t ret; + + __asm__ __volatile__ (" stdcx. %2, 0, %1 \n\t" + " li %0,0 \n\t" + " bne- 1f \n\t" + " ori %0,%0,1 \n\t" + "1:" + : "=r" (ret) + : "r" (addr), "r" (PMIX_ASM_VALUE64(newval)) + : "cc", "memory"); + return ret; +} + +/* these two functions aren't inlined in the non-gcc case because then + there would be two function calls (since neither cmpset_64 nor + atomic_?mb can be inlined). Instead, we "inline" them by hand in + the assembly, meaning there is one function call overhead instead + of two */ +static inline int pmix_atomic_cmpset_acq_64(volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + int rc; + + rc = pmix_atomic_cmpset_64(addr, oldval, newval); + pmix_atomic_rmb(); + + return rc; +} + + +static inline int pmix_atomic_cmpset_rel_64(volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + pmix_atomic_wmb(); + return pmix_atomic_cmpset_64(addr, oldval, newval); +} + +static inline int64_t pmix_atomic_swap_64(volatile int64_t *addr, int64_t newval) +{ + int64_t ret; + + __asm__ __volatile__ ("1: ldarx %0, 0, %2 \n\t" + " stdcx. %3, 0, %2 \n\t" + " bne- 1b \n\t" + : "=&r" (ret), "=m" (*addr) + : "r" (addr), "r" (PMIX_ASM_VALUE64(newval)) + : "cc", "memory"); + + return ret; +} + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + +#elif (PMIX_ASSEMBLY_ARCH == PMIX_POWERPC32) && PMIX_ASM_SUPPORT_64BIT + +#ifndef ll_low /* GLIBC provides these somewhere, so protect */ +#define ll_low(x) *(((unsigned int*)&(x))+0) +#define ll_high(x) *(((unsigned int*)&(x))+1) +#endif + +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline int pmix_atomic_cmpset_64(volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + int ret; + + /* + * We force oldval and newval into memory because PPC doesn't + * appear to have a way to do a move register with offset. Since + * this is 32-bit code, a 64 bit integer will be loaded into two + * registers (assuming no inlining, addr will be in r3, oldval + * will be in r4 and r5, and newval will be r6 and r7. We need + * to load the whole thing into one register. So we have the + * compiler push the values into memory and load the double word + * into registers. We use r4,r5 so that the main block of code + * is very similar to the pure 64 bit version. + */ + __asm__ __volatile__ ( + "ld r4,%2 \n\t" + "ld r5,%3 \n\t" + "1: ldarx r9, 0, %1 \n\t" + " cmpd 0, r9, r4 \n\t" + " bne- 2f \n\t" + " stdcx. r5, 0, %1 \n\t" + " bne- 1b \n\t" + "2: \n\t" + "xor r5,r4,r9 \n\t" + "subfic r9,r5,0 \n\t" + "adde %0,r9,r5 \n\t" + : "=&r" (ret) + : "r"PMIX_ASM_ADDR(addr), + "m"(oldval), "m"(newval) + : "r4", "r5", "r9", "cc", "memory"); + + return ret; +} + +/* these two functions aren't inlined in the non-gcc case because then + there would be two function calls (since neither cmpset_64 nor + atomic_?mb can be inlined). Instead, we "inline" them by hand in + the assembly, meaning there is one function call overhead instead + of two */ +static inline int pmix_atomic_cmpset_acq_64(volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + int rc; + + rc = pmix_atomic_cmpset_64(addr, oldval, newval); + pmix_atomic_rmb(); + + return rc; +} + + +static inline int pmix_atomic_cmpset_rel_64(volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + pmix_atomic_wmb(); + return pmix_atomic_cmpset_64(addr, oldval, newval); +} + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + +#endif /* PMIX_ASM_SUPPORT_64BIT */ + + +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline int32_t pmix_atomic_add_32(volatile int32_t* v, int inc) +{ + int32_t t; + + __asm__ __volatile__( + "1: lwarx %0, 0, %3 \n\t" + " add %0, %2, %0 \n\t" + " stwcx. %0, 0, %3 \n\t" + " bne- 1b \n\t" + : "=&r" (t), "=m" (*v) + : "r" (inc), "r" PMIX_ASM_ADDR(v), "m" (*v) + : "cc"); + + return t; +} + + +static inline int32_t pmix_atomic_sub_32(volatile int32_t* v, int dec) +{ + int32_t t; + + __asm__ __volatile__( + "1: lwarx %0,0,%3 \n\t" + " subf %0,%2,%0 \n\t" + " stwcx. %0,0,%3 \n\t" + " bne- 1b \n\t" + : "=&r" (t), "=m" (*v) + : "r" (dec), "r" PMIX_ASM_ADDR(v), "m" (*v) + : "cc"); + + return t; +} + + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + +#endif /* ! PMIX_SYS_ARCH_ATOMIC_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/powerpc/timer.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/powerpc/timer.h new file mode 100644 index 0000000000..dd8c3ffe1b --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/powerpc/timer.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_SYS_ARCH_TIMER_H +#define PMIX_SYS_ARCH_TIMER_H 1 + + +typedef uint64_t pmix_timer_t; + + +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline pmix_timer_t +pmix_sys_timer_get_cycles(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +#define PMIX_HAVE_SYS_TIMER_GET_CYCLES 1 + +#else + +pmix_timer_t pmix_sys_timer_get_cycles(void); + +#define PMIX_HAVE_SYS_TIMER_GET_CYCLES 1 + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + +#endif /* ! PMIX_SYS_ARCH_TIMER_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sparcv9/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sparcv9/Makefile.include new file mode 100644 index 0000000000..f2ad630bf6 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sparcv9/Makefile.include @@ -0,0 +1,24 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# This makefile.am does not stand on its own - it is included from pmix/include/Makefile.am + +headers += \ + atomics/sys/sparcv9/atomic.h \ + atomics/sys/sparcv9/timer.h diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sparcv9/atomic.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sparcv9/atomic.h new file mode 100644 index 0000000000..9d41bde0a4 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sparcv9/atomic.h @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserverd. + * Copyright (c) 2016 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_SYS_ARCH_ATOMIC_H +#define PMIX_SYS_ARCH_ATOMIC_H 1 + +/* + * On sparc v9, use casa and casxa (compare and swap) instructions. + */ + +#define PMIXASI_P "0x80" + +#define PMIXMEMBAR(type) __asm__ __volatile__ ("membar " type : : : "memory") + + +/********************************************************************** + * + * Define constants for Sparc v9 (Ultra Sparc) + * + *********************************************************************/ +#define PMIX_HAVE_ATOMIC_MEM_BARRIER 1 + +#define PMIX_HAVE_ATOMIC_CMPSET_32 1 + +#define PMIX_HAVE_ATOMIC_CMPSET_64 1 + + +/********************************************************************** + * + * Memory Barriers + * + *********************************************************************/ +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline void pmix_atomic_mb(void) +{ + PMIXMEMBAR("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad"); +} + + +static inline void pmix_atomic_rmb(void) +{ + PMIXMEMBAR("#LoadLoad"); +} + + +static inline void pmix_atomic_wmb(void) +{ + PMIXMEMBAR("#StoreStore"); +} + +static inline void pmix_atomic_isync(void) +{ +} + + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + + +/********************************************************************** + * + * Atomic math operations + * + *********************************************************************/ +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline int pmix_atomic_cmpset_32( volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + /* casa [reg(rs1)] %asi, reg(rs2), reg(rd) + * + * if (*(reg(rs1)) == reg(rs2) ) + * swap reg(rd), *(reg(rs1)) + * else + * reg(rd) = *(reg(rs1)) + */ + + int32_t ret = newval; + + __asm__ __volatile__("casa [%1] " PMIXASI_P ", %2, %0" + : "+r" (ret) + : "r" (addr), "r" (oldval)); + return (ret == oldval); +} + + +static inline int pmix_atomic_cmpset_acq_32( volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + int rc; + + rc = pmix_atomic_cmpset_32(addr, oldval, newval); + pmix_atomic_rmb(); + + return rc; +} + + +static inline int pmix_atomic_cmpset_rel_32( volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + pmix_atomic_wmb(); + return pmix_atomic_cmpset_32(addr, oldval, newval); +} + + +#if PMIX_ASSEMBLY_ARCH == PMIX_SPARCV9_64 + +static inline int pmix_atomic_cmpset_64( volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + /* casa [reg(rs1)] %asi, reg(rs2), reg(rd) + * + * if (*(reg(rs1)) == reg(rs1) ) + * swap reg(rd), *(reg(rs1)) + * else + * reg(rd) = *(reg(rs1)) + */ + int64_t ret = newval; + + __asm__ __volatile__("casxa [%1] " PMIXASI_P ", %2, %0" + : "+r" (ret) + : "r" (addr), "r" (oldval)); + return (ret == oldval); +} + +#else /* PMIX_ASSEMBLY_ARCH == PMIX_SPARCV9_64 */ + +static inline int pmix_atomic_cmpset_64( volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + /* casa [reg(rs1)] %asi, reg(rs2), reg(rd) + * + * if (*(reg(rs1)) == reg(rs1) ) + * swap reg(rd), *(reg(rs1)) + * else + * reg(rd) = *(reg(rs1)) + * + */ + long long ret = newval; + + __asm__ __volatile__( + "ldx %0, %%g1 \n\t" /* g1 = ret */ + "ldx %2, %%g2 \n\t" /* g2 = oldval */ + "casxa [%1] " PMIXASI_P ", %%g2, %%g1 \n\t" + "stx %%g1, %0 \n" + : "+m"(ret) + : "r"(addr), "m"(oldval) + : "%g1", "%g2" + ); + + return (ret == oldval); +} + +#endif /* PMIX_ASSEMBLY_ARCH == PMIX_SPARCV9_64 */ + +static inline int pmix_atomic_cmpset_acq_64( volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + int rc; + + rc = pmix_atomic_cmpset_64(addr, oldval, newval); + pmix_atomic_rmb(); + + return rc; +} + + +static inline int pmix_atomic_cmpset_rel_64( volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + pmix_atomic_wmb(); + return pmix_atomic_cmpset_64(addr, oldval, newval); +} + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + + +#endif /* ! PMIX_SYS_ARCH_ATOMIC_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sparcv9/timer.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sparcv9/timer.h new file mode 100644 index 0000000000..395ea98601 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sparcv9/timer.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_SYS_ARCH_TIMER_H +#define PMIX_SYS_ARCH_TIMER_H 1 + +typedef uint64_t pmix_timer_t; + +#if PMIX_GCC_INLINE_ASSEMBLY + + +#if PMIX_ASSEMBLY_ARCH == PMIX_SPARCV9_64 + +static inline pmix_timer_t +pmix_sys_timer_get_cycles(void) +{ + pmix_timer_t ret; + + __asm__ __volatile__("rd %%tick, %0" : "=r"(ret)); + + return ret; +} + +#else /* PMIX_SPARCV9_32 */ + +static inline pmix_timer_t +pmix_sys_timer_get_cycles(void) +{ + pmix_timer_t ret; + int a, b; + + __asm__ __volatile__("rd %%tick, %0 \n" + "srlx %0, 32, %1 " : + "=r"(a), "=r"(b) + ); + + ret = (0x00000000FFFFFFFF & a) | (((pmix_timer_t) b) << 32); + + return ret; +} + +#endif + +#define PMIX_HAVE_SYS_TIMER_GET_CYCLES 1 + +#else + +#define PMIX_HAVE_SYS_TIMER_GET_CYCLES 0 + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + +#endif /* ! PMIX_SYS_ARCH_TIMER_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sync_builtin/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sync_builtin/Makefile.include new file mode 100644 index 0000000000..a57977a81e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sync_builtin/Makefile.include @@ -0,0 +1,24 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2009 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2011 Sandia National Laboratories. All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# This makefile.am does not stand on its own - it is included from pmix/include/Makefile.am + +headers += \ + atomics/sys/sync_builtin/atomic.h diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sync_builtin/atomic.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sync_builtin/atomic.h new file mode 100644 index 0000000000..51a9a1409b --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/sync_builtin/atomic.h @@ -0,0 +1,137 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2013 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2011 Sandia National Laboratories. All rights reserved. + * Copyright (c) 2014-2016 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_SYS_ARCH_ATOMIC_H +#define PMIX_SYS_ARCH_ATOMIC_H 1 + +/********************************************************************** + * + * Memory Barriers + * + *********************************************************************/ +#define PMIX_HAVE_ATOMIC_MEM_BARRIER 1 + +static inline void pmix_atomic_mb(void) +{ + __sync_synchronize(); +} + +static inline void pmix_atomic_rmb(void) +{ + __sync_synchronize(); +} + +static inline void pmix_atomic_wmb(void) +{ + __sync_synchronize(); +} + +#define MB() pmix_atomic_mb() + +/********************************************************************** + * + * Atomic math operations + * + *********************************************************************/ + +#define PMIX_HAVE_ATOMIC_CMPSET_32 1 +static inline int pmix_atomic_cmpset_acq_32( volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + return __sync_bool_compare_and_swap(addr, oldval, newval); +} + + +static inline int pmix_atomic_cmpset_rel_32( volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + return __sync_bool_compare_and_swap(addr, oldval, newval);} + +static inline int pmix_atomic_cmpset_32( volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + return __sync_bool_compare_and_swap(addr, oldval, newval); +} + +#define PMIX_HAVE_ATOMIC_MATH_32 1 + +#define PMIX_HAVE_ATOMIC_ADD_32 1 +static inline int32_t pmix_atomic_add_32(volatile int32_t *addr, int32_t delta) +{ + return __sync_add_and_fetch(addr, delta); +} + +#define PMIX_HAVE_ATOMIC_SUB_32 1 +static inline int32_t pmix_atomic_sub_32(volatile int32_t *addr, int32_t delta) +{ + return __sync_sub_and_fetch(addr, delta); +} + +#if PMIX_ASM_SYNC_HAVE_64BIT + +#define PMIX_HAVE_ATOMIC_CMPSET_64 1 +static inline int pmix_atomic_cmpset_acq_64( volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + return __sync_bool_compare_and_swap(addr, oldval, newval); +} + +static inline int pmix_atomic_cmpset_rel_64( volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + return __sync_bool_compare_and_swap(addr, oldval, newval);} + + +static inline int pmix_atomic_cmpset_64( volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + return __sync_bool_compare_and_swap(addr, oldval, newval); +} + +#define PMIX_HAVE_ATOMIC_MATH_64 1 +#define PMIX_HAVE_ATOMIC_ADD_64 1 +static inline int64_t pmix_atomic_add_64(volatile int64_t *addr, int64_t delta) +{ + return __sync_add_and_fetch(addr, delta); +} + +#define PMIX_HAVE_ATOMIC_SUB_64 1 +static inline int64_t pmix_atomic_sub_64(volatile int64_t *addr, int64_t delta) +{ + return __sync_sub_and_fetch(addr, delta); +} + +#endif + +#if PMIX_HAVE_SYNC_BUILTIN_CSWAP_INT128 +static inline int pmix_atomic_cmpset_128 (volatile pmix_int128_t *addr, + pmix_int128_t oldval, pmix_int128_t newval) +{ + return __sync_bool_compare_and_swap(addr, oldval, newval); +} + +#define PMIX_HAVE_ATOMIC_CMPSET_128 1 + +#endif + +#endif /* ! PMIX_SYS_ARCH_ATOMIC_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/timer.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/timer.h new file mode 100644 index 0000000000..a364f61cc8 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/timer.h @@ -0,0 +1,131 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2014 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2016 Broadcom Limited. All rights reserved. + * Copyright (c) 2016 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/** @file + * + * Cycle counter reading instructions. Do not use directly - see the + * timer interface instead + */ + +#ifndef PMIX_SYS_TIMER_H +#define PMIX_SYS_TIMER_H 1 + +#include "pmix_config.h" + +#include "src/atomics/sys/architecture.h" + +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +/* do some quick #define cleanup in cases where we are doing + testing... */ +#ifdef PMIX_DISABLE_INLINE_ASM +#undef PMIX_C_GCC_INLINE_ASSEMBLY +#define PMIX_C_GCC_INLINE_ASSEMBLY 0 +#undef PMIX_CXX_GCC_INLINE_ASSEMBLY +#define PMIX_CXX_GCC_INLINE_ASSEMBLY 0 +#undef PMIX_C_DEC_INLINE_ASSEMBLY +#define PMIX_C_DEC_INLINE_ASSEMBLY 0 +#undef PMIX_CXX_DEC_INLINE_ASSEMBLY +#define PMIX_CXX_DEC_INLINE_ASSEMBLY 0 +#undef PMIX_C_XLC_INLINE_ASSEMBLY +#define PMIX_C_XLC_INLINE_ASSEMBLY 0 +#undef PMIX_CXX_XLC_INLINE_ASSEMBLY +#define PMIX_CXX_XLC_INLINE_ASSEMBLY 0 +#endif + +/* define PMIX_{GCC,DEC,XLC}_INLINE_ASSEMBLY based on the + PMIX_{C,CXX}_{GCC,DEC,XLC}_INLINE_ASSEMBLY defines and whether we + are in C or C++ */ +#if defined(c_plusplus) || defined(__cplusplus) +#define PMIX_GCC_INLINE_ASSEMBLY PMIX_CXX_GCC_INLINE_ASSEMBLY +#define PMIX_DEC_INLINE_ASSEMBLY PMIX_CXX_DEC_INLINE_ASSEMBLY +#define PMIX_XLC_INLINE_ASSEMBLY PMIX_CXX_XLC_INLINE_ASSEMBLY +#else +#define PMIX_GCC_INLINE_ASSEMBLY PMIX_C_GCC_INLINE_ASSEMBLY +#define PMIX_DEC_INLINE_ASSEMBLY PMIX_C_DEC_INLINE_ASSEMBLY +#define PMIX_XLC_INLINE_ASSEMBLY PMIX_C_XLC_INLINE_ASSEMBLY +#endif + +/********************************************************************** + * + * Load the appropriate architecture files and set some reasonable + * default values for our support + * + *********************************************************************/ + +/* By default we suppose all timers are monotonic per node. */ +#define PMIX_TIMER_MONOTONIC 1 + +BEGIN_C_DECLS + +/* If you update this list, you probably also want to update + src/mca/timer/linux/configure.m4. Or not. */ + +#if defined(DOXYGEN) +/* don't include system-level gorp when generating doxygen files */ +#elif PMIX_ASSEMBLY_ARCH == PMIX_X86_64 +#include "src/atomics/sys/x86_64/timer.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_ARM +#include "src/atomics/sys/arm/timer.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_ARM64 +#include "src/atomics/sys/arm64/timer.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_IA32 +#include "src/atomics/sys/ia32/timer.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_IA64 +#include "src/atomics/sys/ia64/timer.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_POWERPC32 +#include "src/atomics/sys/powerpc/timer.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_POWERPC64 +#include "src/atomics/sys/powerpc/timer.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_SPARCV9_32 +#include "src/atomics/sys/sparcv9/timer.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_SPARCV9_64 +#include "src/atomics/sys/sparcv9/timer.h" +#elif PMIX_ASSEMBLY_ARCH == PMIX_MIPS +#include "src/atomics/sys/mips/timer.h" +#endif + +#ifndef DOXYGEN +#ifndef PMIX_HAVE_SYS_TIMER_GET_CYCLES +#define PMIX_HAVE_SYS_TIMER_GET_CYCLES 0 + +typedef long pmix_timer_t; +#endif +#endif + +#ifndef PMIX_HAVE_SYS_TIMER_IS_MONOTONIC + +#define PMIX_HAVE_SYS_TIMER_IS_MONOTONIC 1 + +static inline bool pmix_sys_timer_is_monotonic (void) +{ + return PMIX_TIMER_MONOTONIC; +} + +#endif + +END_C_DECLS + +#endif /* PMIX_SYS_TIMER_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/x86_64/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/x86_64/Makefile.include new file mode 100644 index 0000000000..79a42b8e83 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/x86_64/Makefile.include @@ -0,0 +1,26 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2005 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2017 Research Organization for Information Science +# and Technology (RIST). All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# This makefile.am does not stand on its own - it is included from pmix/include/Makefile.am + +headers += \ + atomics/sys/x86_64/atomic.h \ + atomics/sys/x86_64/timer.h diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/x86_64/atomic.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/x86_64/atomic.h new file mode 100644 index 0000000000..aa71aae364 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/x86_64/atomic.h @@ -0,0 +1,281 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2010 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserverd. + * Copyright (c) 2012-2014 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2016-2017 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +#ifndef PMIX_SYS_ARCH_ATOMIC_H +#define PMIX_SYS_ARCH_ATOMIC_H 1 + +/* + * On x86_64, we use cmpxchg. + */ + + +#define PMIXSMPLOCK "lock; " +#define PMIXMB() __asm__ __volatile__("": : :"memory") + + +/********************************************************************** + * + * Define constants for AMD64 / x86_64 / EM64T / ... + * + *********************************************************************/ +#define PMIX_HAVE_ATOMIC_MEM_BARRIER 1 + +#define PMIX_HAVE_ATOMIC_CMPSET_32 1 + +#define PMIX_HAVE_ATOMIC_CMPSET_64 1 + +/********************************************************************** + * + * Memory Barriers + * + *********************************************************************/ +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline void pmix_atomic_mb(void) +{ + PMIXMB(); +} + + +static inline void pmix_atomic_rmb(void) +{ + PMIXMB(); +} + + +static inline void pmix_atomic_wmb(void) +{ + PMIXMB(); +} + +static inline void pmix_atomic_isync(void) +{ +} + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + + +/********************************************************************** + * + * Atomic math operations + * + *********************************************************************/ +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline int pmix_atomic_cmpset_32( volatile int32_t *addr, + int32_t oldval, int32_t newval) +{ + unsigned char ret; + __asm__ __volatile__ ( + PMIXSMPLOCK "cmpxchgl %3,%2 \n\t" + "sete %0 \n\t" + : "=qm" (ret), "+a" (oldval), "+m" (*addr) + : "q"(newval) + : "memory", "cc"); + + return (int)ret; +} + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + +#define pmix_atomic_cmpset_acq_32 pmix_atomic_cmpset_32 +#define pmix_atomic_cmpset_rel_32 pmix_atomic_cmpset_32 + +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline int pmix_atomic_cmpset_64( volatile int64_t *addr, + int64_t oldval, int64_t newval) +{ + unsigned char ret; + __asm__ __volatile__ ( + PMIXSMPLOCK "cmpxchgq %3,%2 \n\t" + "sete %0 \n\t" + : "=qm" (ret), "+a" (oldval), "+m" (*((volatile long*)addr)) + : "q"(newval) + : "memory", "cc" + ); + + return (int)ret; +} + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + +#define pmix_atomic_cmpset_acq_64 pmix_atomic_cmpset_64 +#define pmix_atomic_cmpset_rel_64 pmix_atomic_cmpset_64 + +#if PMIX_GCC_INLINE_ASSEMBLY && PMIX_HAVE_CMPXCHG16B && HAVE_PMIX_INT128_T + +static inline int pmix_atomic_cmpset_128 (volatile pmix_int128_t *addr, pmix_int128_t oldval, + pmix_int128_t newval) +{ + unsigned char ret; + + /* cmpxchg16b compares the value at the address with eax:edx (low:high). if the values are + * the same the contents of ebx:ecx are stores at the address. in all cases the value stored + * at the address is returned in eax:edx. */ + __asm__ __volatile__ (PMIXSMPLOCK "cmpxchg16b (%%rsi) \n\t" + "sete %0 \n\t" + : "=qm" (ret) + : "S" (addr), "b" (((int64_t *)&newval)[0]), "c" (((int64_t *)&newval)[1]), + "a" (((int64_t *)&oldval)[0]), "d" (((int64_t *)&oldval)[1]) + : "memory", "cc"); + + return (int) ret; +} + +#define PMIX_HAVE_ATOMIC_CMPSET_128 1 + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + + +#if PMIX_GCC_INLINE_ASSEMBLY + +#define PMIX_HAVE_ATOMIC_SWAP_32 1 + +#define PMIX_HAVE_ATOMIC_SWAP_64 1 + +static inline int32_t pmix_atomic_swap_32( volatile int32_t *addr, + int32_t newval) +{ + int32_t oldval; + + __asm__ __volatile__("xchg %1, %0" : + "=r" (oldval), "+m" (*addr) : + "0" (newval) : + "memory"); + return oldval; +} + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + +#if PMIX_GCC_INLINE_ASSEMBLY + +static inline int64_t pmix_atomic_swap_64( volatile int64_t *addr, + int64_t newval) +{ + int64_t oldval; + + __asm__ __volatile__("xchgq %1, %0" : + "=r" (oldval), "+m" (*addr) : + "0" (newval) : + "memory"); + return oldval; +} + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + + + +#if PMIX_GCC_INLINE_ASSEMBLY + +#define PMIX_HAVE_ATOMIC_MATH_32 1 +#define PMIX_HAVE_ATOMIC_MATH_64 1 + +#define PMIX_HAVE_ATOMIC_ADD_32 1 + +/** + * atomic_add - add integer to atomic variable + * @i: integer value to add + * @v: pointer of type int + * + * Atomically adds @i to @v. + */ +static inline int32_t pmix_atomic_add_32(volatile int32_t* v, int i) +{ + int ret = i; + __asm__ __volatile__( + PMIXSMPLOCK "xaddl %1,%0" + :"+m" (*v), "+r" (ret) + : + :"memory", "cc" + ); + return (ret+i); +} + +#define PMIX_HAVE_ATOMIC_ADD_64 1 + +/** + * atomic_add - add integer to atomic variable + * @i: integer value to add + * @v: pointer of type int + * + * Atomically adds @i to @v. + */ +static inline int64_t pmix_atomic_add_64(volatile int64_t* v, int64_t i) +{ + int64_t ret = i; + __asm__ __volatile__( + PMIXSMPLOCK "xaddq %1,%0" + :"+m" (*v), "+r" (ret) + : + :"memory", "cc" + ); + return (ret+i); +} + +#define PMIX_HAVE_ATOMIC_SUB_32 1 + +/** + * atomic_sub - subtract the atomic variable + * @i: integer value to subtract + * @v: pointer of type int + * + * Atomically subtracts @i from @v. + */ +static inline int32_t pmix_atomic_sub_32(volatile int32_t* v, int i) +{ + int ret = -i; + __asm__ __volatile__( + PMIXSMPLOCK "xaddl %1,%0" + :"+m" (*v), "+r" (ret) + : + :"memory", "cc" + ); + return (ret-i); +} + +#define PMIX_HAVE_ATOMIC_SUB_64 1 + +/** + * atomic_sub - subtract the atomic variable + * @i: integer value to subtract + * @v: pointer of type int + * + * Atomically subtracts @i from @v. + */ +static inline int64_t pmix_atomic_sub_64(volatile int64_t* v, int64_t i) +{ + int64_t ret = -i; + __asm__ __volatile__( + PMIXSMPLOCK "xaddq %1,%0" + :"+m" (*v), "+r" (ret) + : + :"memory", "cc" + ); + return (ret-i); +} + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + +#endif /* ! PMIX_SYS_ARCH_ATOMIC_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/x86_64/timer.h b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/x86_64/timer.h new file mode 100644 index 0000000000..0d6019c36f --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/atomics/sys/x86_64/timer.h @@ -0,0 +1,75 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2014 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2016 Los Alamos National Security, LLC. ALl rights + * reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_SYS_ARCH_TIMER_H +#define PMIX_SYS_ARCH_TIMER_H 1 + + +typedef uint64_t pmix_timer_t; + +/* Using RDTSC(P) results in non-monotonic timers across cores */ +#undef PMIX_TIMER_MONOTONIC +#define PMIX_TIMER_MONOTONIC 0 + +#if PMIX_GCC_INLINE_ASSEMBLY + +/* TODO: add AMD mfence version and dispatch at init */ +static inline pmix_timer_t +pmix_sys_timer_get_cycles(void) +{ + uint32_t l, h; + __asm__ __volatile__ ("lfence\n\t" + "rdtsc\n\t" + : "=a" (l), "=d" (h)); + return ((pmix_timer_t)l) | (((pmix_timer_t)h) << 32); +} + +static inline bool pmix_sys_timer_is_monotonic (void) +{ + int64_t tmp; + int32_t cpuid1, cpuid2; + const int32_t level = 0x80000007; + + /* cpuid clobbers ebx but it must be restored for -fPIC so save + * then restore ebx */ + __asm__ volatile ("xchg %%rbx, %2\n" + "cpuid\n" + "xchg %%rbx, %2\n": + "=a" (cpuid1), "=d" (cpuid2), "=r" (tmp) : + "a" (level) : + "ecx", "ebx"); + /* bit 8 of edx contains the invariant tsc flag */ + return !!(cpuid2 & (1 << 8)); +} + +#define PMIX_HAVE_SYS_TIMER_GET_CYCLES 1 +#define PMIX_HAVE_SYS_TIMER_IS_MONOTONIC 1 + +#else + +pmix_timer_t pmix_sys_timer_get_cycles(void); + +#define PMIX_HAVE_SYS_TIMER_GET_CYCLES 1 + +#endif /* PMIX_GCC_INLINE_ASSEMBLY */ + +#endif /* ! PMIX_SYS_ARCH_TIMER_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/open_close.c b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/open_close.c index 486d6f2554..f1861a11b5 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/open_close.c +++ b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/open_close.c @@ -75,10 +75,10 @@ static void pmix_buffer_destruct (pmix_buffer_t* buffer) } } -PMIX_CLASS_INSTANCE(pmix_buffer_t, - pmix_object_t, - pmix_buffer_construct, - pmix_buffer_destruct); +PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_buffer_t, + pmix_object_t, + pmix_buffer_construct, + pmix_buffer_destruct); static void pmix_bfrop_type_info_construct(pmix_bfrop_type_info_t *obj) @@ -97,9 +97,9 @@ static void pmix_bfrop_type_info_destruct(pmix_bfrop_type_info_t *obj) } } -PMIX_CLASS_INSTANCE(pmix_bfrop_type_info_t, pmix_object_t, - pmix_bfrop_type_info_construct, - pmix_bfrop_type_info_destruct); +PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_bfrop_type_info_t, pmix_object_t, + pmix_bfrop_type_info_construct, + pmix_bfrop_type_info_destruct); static void kvcon(pmix_kval_t *k) { @@ -115,18 +115,18 @@ static void kvdes(pmix_kval_t *k) PMIX_VALUE_RELEASE(k->value); } } -PMIX_CLASS_INSTANCE(pmix_kval_t, - pmix_list_item_t, - kvcon, kvdes); +PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_kval_t, + pmix_list_item_t, + kvcon, kvdes); static void rcon(pmix_regex_range_t *p) { p->start = 0; p->cnt = 0; } -PMIX_CLASS_INSTANCE(pmix_regex_range_t, - pmix_list_item_t, - rcon, NULL); +PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_regex_range_t, + pmix_list_item_t, + rcon, NULL); static void rvcon(pmix_regex_value_t *p) { @@ -145,9 +145,9 @@ static void rvdes(pmix_regex_value_t *p) } PMIX_LIST_DESTRUCT(&p->ranges); } -PMIX_CLASS_INSTANCE(pmix_regex_value_t, - pmix_list_item_t, - rvcon, rvdes); +PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_regex_value_t, + pmix_list_item_t, + rvcon, rvdes); pmix_status_t pmix_bfrop_open(void) { diff --git a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/pack.c b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/pack.c index 0a562a3a25..000be85c5b 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/pack.c +++ b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/pack.c @@ -560,6 +560,11 @@ static pmix_status_t pack_val(pmix_buffer_t *buffer, return ret; } break; + case PMIX_POINTER: + if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.ptr, 1, PMIX_POINTER))) { + return ret; + } + break; case PMIX_SCOPE: if (PMIX_SUCCESS != (ret = pmix_bfrop_pack_buffer(buffer, &p->data.scope, 1, PMIX_SCOPE))) { return ret; diff --git a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/unpack.c b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/unpack.c index 9eb10fecf0..53e73ac1c9 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/unpack.c +++ b/opal/mca/pmix/pmix2x/pmix/src/buffer_ops/unpack.c @@ -632,7 +632,7 @@ pmix_status_t pmix_bfrop_unpack_status(pmix_buffer_t *buffer, void *dest, break; case PMIX_PROC: /* this field is now a pointer, so we must allocate storage for it */ - PMIX_PROC_CREATE(val->data.proc, 1); + PMIX_PROC_CREATE(val->data.proc, m); if (NULL == val->data.proc) { return PMIX_ERR_NOMEM; } @@ -656,6 +656,11 @@ pmix_status_t pmix_bfrop_unpack_status(pmix_buffer_t *buffer, void *dest, return ret; } break; + case PMIX_POINTER: + if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.ptr, &m, PMIX_POINTER))) { + return ret; + } + break; case PMIX_SCOPE: if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_buffer(buffer, &val->data.scope, &m, PMIX_SCOPE))) { return ret; diff --git a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_pointer_array.c b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_pointer_array.c index a3b3f534a4..dfd3b9a2c1 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_pointer_array.c +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_pointer_array.c @@ -3,16 +3,14 @@ * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana * University Research and Technology * Corporation. All rights reserved. - * Copyright (c) 2004-2007 The University of Tennessee and The University + * Copyright (c) 2004-2017 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2013-2016 Intel, Inc. All rights reserved. - * Copyright (c) 2015 Research Organization for Information Science - * and Technology (RIST). All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -20,29 +18,23 @@ * $HEADER$ */ -#include +#include "pmix_config.h" +#include "pmix_common.h" #include #include #include -#if HAVE_STDBOOL_H -#include -#endif -#include #include "src/class/pmix_pointer_array.h" #include "src/util/output.h" -#include "include/pmix_common.h" - -enum { TABLE_INIT = 1, TABLE_GROW = 2 }; static void pmix_pointer_array_construct(pmix_pointer_array_t *); static void pmix_pointer_array_destruct(pmix_pointer_array_t *); -static bool grow_table(pmix_pointer_array_t *table, int soft, int hard); +static bool grow_table(pmix_pointer_array_t *table, int at_least); PMIX_CLASS_INSTANCE(pmix_pointer_array_t, pmix_object_t, - pmix_pointer_array_construct, - pmix_pointer_array_destruct); + pmix_pointer_array_construct, + pmix_pointer_array_destruct); /* * pmix_pointer_array constructor @@ -53,8 +45,9 @@ static void pmix_pointer_array_construct(pmix_pointer_array_t *array) array->number_free = 0; array->size = 0; array->max_size = INT_MAX; - array->block_size = 0; - array->addr = 0; + array->block_size = 8; + array->free_bits = NULL; + array->addr = NULL; } /* @@ -63,20 +56,122 @@ static void pmix_pointer_array_construct(pmix_pointer_array_t *array) static void pmix_pointer_array_destruct(pmix_pointer_array_t *array) { /* free table */ - if( NULL != array->addr) { + if( NULL != array->free_bits) { + free(array->free_bits); + array->free_bits = NULL; + } + if( NULL != array->addr ) { free(array->addr); array->addr = NULL; } array->size = 0; + } +#define TYPE_ELEM_COUNT(TYPE, CAP) (((CAP) + 8 * sizeof(TYPE) - 1) / (8 * sizeof(TYPE))) + +/** + * Translate an index position into the free bits array into 2 values, the + * index of the element and the index of the bit position. + */ +#define GET_BIT_POS(IDX, BIDX, PIDX) \ + do { \ + uint32_t __idx = (uint32_t)(IDX); \ + (BIDX) = (__idx / (8 * sizeof(uint64_t))); \ + (PIDX) = (__idx % (8 * sizeof(uint64_t))); \ + } while(0) + +/** + * A classical find first zero bit (ffs) on a large array. It checks starting + * from the indicated position until it finds a zero bit. If SET is true, + * the bit is set. The position of the bit is returned in store. + */ +#define FIND_FIRST_ZERO(START_IDX, STORE, SET) \ + do { \ + uint32_t __b_idx, __b_pos; \ + GET_BIT_POS((START_IDX), __b_idx, __b_pos); \ + for (; table->free_bits[__b_idx] == 0xFFFFFFFFFFFFFFFFULL; __b_idx++); \ + assert(__b_idx < (uint32_t)table->size); \ + uint64_t __check_value = table->free_bits[__b_idx]; \ + __b_pos = 0; \ + \ + if( 0x00000000FFFFFFFFULL == (__check_value & 0x00000000FFFFFFFFULL) ) { \ + __check_value >>= 32; __b_pos += 32; \ + } \ + if( 0x000000000000FFFFULL == (__check_value & 0x000000000000FFFFULL) ) { \ + __check_value >>= 16; __b_pos += 16; \ + } \ + if( 0x00000000000000FFULL == (__check_value & 0x00000000000000FFULL) ) { \ + __check_value >>= 8; __b_pos += 8; \ + } \ + if( 0x000000000000000FULL == (__check_value & 0x000000000000000FULL) ) { \ + __check_value >>= 4; __b_pos += 4; \ + } \ + if( 0x0000000000000003ULL == (__check_value & 0x0000000000000003ULL) ) { \ + __check_value >>= 2; __b_pos += 2; \ + } \ + if( 0x0000000000000001ULL == (__check_value & 0x0000000000000001ULL) ) { \ + __b_pos += 1; \ + } \ + if( (SET) ) { \ + table->free_bits[__b_idx] |= (1ULL << __b_pos); \ + } \ + (STORE) = (__b_idx * 8 * sizeof(uint64_t)) + __b_pos; \ + } while(0) + +/** + * Set the IDX bit in the free_bits array. The bit should be previously unset. + */ +#define SET_BIT(IDX) \ + do { \ + uint32_t __b_idx, __b_pos; \ + GET_BIT_POS((IDX), __b_idx, __b_pos); \ + assert( 0 == (table->free_bits[__b_idx] & (1UL << __b_pos))); \ + table->free_bits[__b_idx] |= (1ULL << __b_pos); \ + } while(0) + +/** + * Unset the IDX bit in the free_bits array. The bit should be previously set. + */ +#define UNSET_BIT(IDX) \ + do { \ + uint32_t __b_idx, __b_pos; \ + GET_BIT_POS((IDX), __b_idx, __b_pos); \ + assert( (table->free_bits[__b_idx] & (1UL << __b_pos))); \ + table->free_bits[__b_idx] ^= (1ULL << __b_pos); \ + } while(0) + +#if 0 +/** + * Validate the pointer array by making sure that the elements and + * the free bits array are in sync. It also check that the number + * of remaining free element is consistent. + */ +static void pmix_pointer_array_validate(pmix_pointer_array_t *array) +{ + int i, cnt = 0; + uint32_t b_idx, p_idx; + + for( i = 0; i < array->size; i++ ) { + GET_BIT_POS(i, b_idx, p_idx); + if( NULL == array->addr[i] ) { + cnt++; + assert( 0 == (array->free_bits[b_idx] & (1ULL << p_idx)) ); + } else { + assert( 0 != (array->free_bits[b_idx] & (1ULL << p_idx)) ); + } + } + assert(cnt == array->number_free); +} +#endif + /** * initialize an array object */ -pmix_status_t pmix_pointer_array_init(pmix_pointer_array_t* array, - int initial_allocation, - int max_size, int block_size) +int pmix_pointer_array_init(pmix_pointer_array_t* array, + int initial_allocation, + int max_size, int block_size) { size_t num_bytes; @@ -86,18 +181,24 @@ pmix_status_t pmix_pointer_array_init(pmix_pointer_array_t* array, } array->max_size = max_size; - array->block_size = block_size; + array->block_size = (0 == block_size ? 8 : block_size); + array->lowest_free = 0; num_bytes = (0 < initial_allocation ? initial_allocation : block_size); - array->number_free = num_bytes; - array->size = num_bytes; - num_bytes *= sizeof(void*); /* Allocate and set the array to NULL */ - array->addr = (void **)calloc(num_bytes, 1); + array->addr = (void **)calloc(num_bytes, sizeof(void*)); if (NULL == array->addr) { /* out of memory */ return PMIX_ERR_OUT_OF_RESOURCE; } + array->free_bits = (uint64_t*)calloc(TYPE_ELEM_COUNT(uint64_t, num_bytes), sizeof(uint64_t)); + if (NULL == array->free_bits) { /* out of memory */ + free(array->addr); + array->addr = NULL; + return PMIX_ERR_OUT_OF_RESOURCE; + } + array->number_free = num_bytes; + array->size = num_bytes; return PMIX_SUCCESS; } @@ -112,13 +213,11 @@ pmix_status_t pmix_pointer_array_init(pmix_pointer_array_t* array, */ int pmix_pointer_array_add(pmix_pointer_array_t *table, void *ptr) { - int i, index; + int index = table->size + 1; if (table->number_free == 0) { /* need to grow table */ - if (!grow_table(table, - (NULL == table->addr ? TABLE_INIT : table->size * TABLE_GROW), - INT_MAX)) { + if (!grow_table(table, index) ) { return PMIX_ERR_OUT_OF_RESOURCE; } } @@ -132,21 +231,19 @@ int pmix_pointer_array_add(pmix_pointer_array_t *table, void *ptr) */ index = table->lowest_free; - assert(table->addr[index] == NULL); + assert(NULL == table->addr[index]); table->addr[index] = ptr; table->number_free--; + SET_BIT(index); if (table->number_free > 0) { - for (i = table->lowest_free + 1; i < table->size; i++) { - if (table->addr[i] == NULL) { - table->lowest_free = i; - break; - } - } - } - else { + FIND_FIRST_ZERO(index, table->lowest_free, 0); + } else { table->lowest_free = table->size; } +#if 0 + pmix_pointer_array_validate(table); +#endif return index; } @@ -161,48 +258,48 @@ int pmix_pointer_array_add(pmix_pointer_array_t *table, void *ptr) * * Assumption: NULL element is free element. */ -pmix_status_t pmix_pointer_array_set_item(pmix_pointer_array_t *table, int index, - void * value) +int pmix_pointer_array_set_item(pmix_pointer_array_t *table, int index, + void * value) { assert(table != NULL); + if (PMIX_UNLIKELY(0 > index)) { + return PMIX_ERROR; + } + /* expand table if required to set a specific index */ if (table->size <= index) { - if (!grow_table(table, ((index / TABLE_GROW) + 1) * TABLE_GROW, - index)) { + if (!grow_table(table, index)) { return PMIX_ERROR; } } - + assert(table->size > index); /* mark element as free, if NULL element */ if( NULL == value ) { - if (index < table->lowest_free) { - table->lowest_free = index; - } if( NULL != table->addr[index] ) { + if (index < table->lowest_free) { + table->lowest_free = index; + } table->number_free++; + UNSET_BIT(index); } } else { if (NULL == table->addr[index]) { table->number_free--; - } - /* Reset lowest_free if required */ - if ( index == table->lowest_free ) { - int i; - - table->lowest_free = table->size; - for ( i=index + 1; isize; i++) { - if ( NULL == table->addr[i] ){ - table->lowest_free = i; - break; - } + SET_BIT(index); + /* Reset lowest_free if required */ + if ( index == table->lowest_free ) { + FIND_FIRST_ZERO(index, table->lowest_free, 0); } + } else { + assert( index != table->lowest_free ); } } table->addr[index] = value; #if 0 + pmix_pointer_array_validate(table); pmix_output(0,"pmix_pointer_array_set_item: OUT: " " table %p (size %ld, lowest free %ld, number free %ld)" " addr[%d] = %p\n", @@ -250,8 +347,7 @@ bool pmix_pointer_array_test_and_set_item (pmix_pointer_array_t *table, /* Do we need to grow the table? */ if (table->size <= index) { - if (!grow_table(table, (((index / TABLE_GROW) + 1) * TABLE_GROW), - index)) { + if (!grow_table(table, index)) { return false; } } @@ -259,22 +355,21 @@ bool pmix_pointer_array_test_and_set_item (pmix_pointer_array_t *table, /* * allow a specific index to be changed. */ + assert(NULL == table->addr[index]); table->addr[index] = value; table->number_free--; + SET_BIT(index); /* Reset lowest_free if required */ - if ( index == table->lowest_free ) { - int i; - - table->lowest_free = table->size; - for ( i=index; isize; i++) { - if ( NULL == table->addr[i] ){ - table->lowest_free = i; - break; - } + if( table->number_free > 0 ) { + if ( index == table->lowest_free ) { + FIND_FIRST_ZERO(index, table->lowest_free, 0); } + } else { + table->lowest_free = table->size; } #if 0 + pmix_pointer_array_validate(table); pmix_output(0,"pmix_pointer_array_test_and_set_item: OUT: " " table %p (size %ld, lowest free %ld, number free %ld)" " addr[%d] = %p\n", @@ -285,47 +380,55 @@ bool pmix_pointer_array_test_and_set_item (pmix_pointer_array_t *table, return true; } -pmix_status_t pmix_pointer_array_set_size(pmix_pointer_array_t *array, int new_size) +int pmix_pointer_array_set_size(pmix_pointer_array_t *array, int new_size) { if(new_size > array->size) { - if (!grow_table(array, new_size, new_size)) { + if (!grow_table(array, new_size)) { return PMIX_ERROR; } } return PMIX_SUCCESS; } -static bool grow_table(pmix_pointer_array_t *table, int soft, int hard) +static bool grow_table(pmix_pointer_array_t *table, int at_least) { - int new_size; - int i, new_size_int; + int i, new_size, new_size_int; void *p; - /* new_size = ((table->size + num_needed + table->block_size - 1) / - table->block_size) * table->block_size; */ - new_size = soft; - if( soft > table->max_size ) { - if( hard > table->max_size ) { + new_size = table->block_size * ((at_least + 1 + table->block_size - 1) / table->block_size); + if( new_size >= table->max_size ) { + new_size = table->max_size; + if( at_least >= table->max_size ) { return false; } - new_size = hard; - } - if( new_size >= table->max_size ) { - return false; } p = (void **) realloc(table->addr, new_size * sizeof(void *)); - if (p == NULL) { + if (NULL == p) { return false; } - new_size_int = (int) new_size; - table->number_free += new_size_int - table->size; + table->number_free += (new_size - table->size); table->addr = (void**)p; - for (i = table->size; i < new_size_int; ++i) { + for (i = table->size; i < new_size; ++i) { table->addr[i] = NULL; } - table->size = new_size_int; - + new_size_int = TYPE_ELEM_COUNT(uint64_t, new_size); + if( (int)(TYPE_ELEM_COUNT(uint64_t, table->size)) != new_size_int ) { + p = (uint64_t*)realloc(table->free_bits, new_size_int * sizeof(uint64_t)); + if (NULL == p) { + return false; + } + table->free_bits = (uint64_t*)p; + for (i = TYPE_ELEM_COUNT(uint64_t, table->size); + i < new_size_int; i++ ) { + table->free_bits[i] = 0; + } + } + table->size = new_size; +#if 0 + pmix_output(0, "grow_table %p to %d (max_size %d, block %d, number_free %d)\n", + (void*)table, table->size, table->max_size, table->block_size, table->number_free); +#endif return true; } diff --git a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_pointer_array.h b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_pointer_array.h index b3f647f89d..b369a5a0ce 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/class/pmix_pointer_array.h +++ b/opal/mca/pmix/pmix2x/pmix/src/class/pmix_pointer_array.h @@ -3,34 +3,37 @@ * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana * University Research and Technology * Corporation. All rights reserved. - * Copyright (c) 2004-2008 The University of Tennessee and The University + * Copyright (c) 2004-2017 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2013-2016 Intel, Inc. All rights reserved. - * Copyright (c) 2015 Research Organization for Information Science - * and Technology (RIST). All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */ +/** @file + * + * Utility functions to manage fortran <-> c opaque object + * translation. Note that since MPI defines fortran handles as + * [signed] int's, we use int everywhere in here where you would + * normally expect size_t. There's some code that makes sure indices + * don't go above FORTRAN_HANDLE_MAX (which is min(INT_MAX, fortran + * INTEGER max)), just to be sure. + */ #ifndef PMIX_POINTER_ARRAY_H #define PMIX_POINTER_ARRAY_H -#include - -#if HAVE_STDBOOL_H -#include -#endif +#include "pmix_config.h" #include "src/class/pmix_object.h" -#include +#include "src/include/prefetch.h" BEGIN_C_DECLS @@ -53,6 +56,8 @@ struct pmix_pointer_array_t { int max_size; /** block size for each allocation */ int block_size; + /** pointer to an array of bits to speed up the research for an empty position. */ + uint64_t* free_bits; /** pointer to array of pointers */ void **addr; }; @@ -63,7 +68,7 @@ typedef struct pmix_pointer_array_t pmix_pointer_array_t; /** * Class declaration */ -PMIX_CLASS_DECLARATION(pmix_pointer_array_t); +PMIX_EXPORT PMIX_CLASS_DECLARATION(pmix_pointer_array_t); /** * Initialize the pointer array with an initial size of initial_allocation. @@ -79,9 +84,9 @@ PMIX_CLASS_DECLARATION(pmix_pointer_array_t); * @return PMIX_SUCCESS if all initializations were succesfull. Otherwise, * the error indicate what went wrong in the function. */ -PMIX_EXPORT pmix_status_t pmix_pointer_array_init(pmix_pointer_array_t* array, - int initial_allocation, - int max_size, int block_size ); +PMIX_EXPORT int pmix_pointer_array_init(pmix_pointer_array_t* array, + int initial_allocation, + int max_size, int block_size); /** * Add a pointer to the array (Grow the array, if need be) @@ -101,11 +106,10 @@ PMIX_EXPORT int pmix_pointer_array_add(pmix_pointer_array_t *array, void *ptr); * @param index Index of element to be reset (IN) * @param value New value to be set at element index (IN) * - * @return PMIX_SUCCESS if item was inserted. Otherwise, - * the error indicate what went wrong in the function. + * @return Error code. (-1) indicates an error. */ -PMIX_EXPORT pmix_status_t pmix_pointer_array_set_item(pmix_pointer_array_t *array, - int index, void *value); +PMIX_EXPORT int pmix_pointer_array_set_item(pmix_pointer_array_t *array, + int index, void *value); /** * Get the value of an element in array @@ -121,7 +125,7 @@ static inline void *pmix_pointer_array_get_item(pmix_pointer_array_t *table, { void *p; - if( table->size <= element_index ) { + if( PMIX_UNLIKELY(0 > element_index || table->size <= element_index) ) { return NULL; } p = table->addr[element_index]; @@ -151,13 +155,10 @@ static inline int pmix_pointer_array_get_size(pmix_pointer_array_t *array) * * @param size Desired size of the array * - * @return PMIX_SUCCESS new size was set. Otherwise, - * the error indicate what went wrong in the function. - * * Simple function to set the size of the array in order to * hide the member field from external users. */ -PMIX_EXPORT pmix_status_t pmix_pointer_array_set_size(pmix_pointer_array_t *array, int size); +PMIX_EXPORT int pmix_pointer_array_set_size(pmix_pointer_array_t *array, int size); /** * Test whether a certain element is already in use. If not yet @@ -174,8 +175,8 @@ PMIX_EXPORT pmix_status_t pmix_pointer_array_set_size(pmix_pointer_array_t *arra * a value, unless the previous value is NULL ( equiv. to free ). */ PMIX_EXPORT bool pmix_pointer_array_test_and_set_item (pmix_pointer_array_t *table, - int index, - void *value); + int index, + void *value); /** * Empty the array. @@ -191,9 +192,12 @@ static inline void pmix_pointer_array_remove_all(pmix_pointer_array_t *array) array->lowest_free = 0; array->number_free = array->size; - for(i=0; isize; i++) { + for(i = 0; i < array->size; i++) { array->addr[i] = NULL; } + for(i = 0; i < (int)((array->size + 8*sizeof(uint64_t) - 1) / (8*sizeof(uint64_t))); i++) { + array->free_bits[i] = 0; + } } END_C_DECLS diff --git a/opal/mca/pmix/pmix2x/pmix/src/client/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/client/Makefile.include index e9abb45ff1..0bf6efed74 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/client/Makefile.include +++ b/opal/mca/pmix/pmix2x/pmix/src/client/Makefile.include @@ -22,7 +22,7 @@ sources += \ client/pmix_client_spawn.c \ client/pmix_client_connect.c -if WANT_PMIX_BACKWARD +if WANT_PMI_BACKWARD sources += \ client/pmi1.c \ client/pmi2.c diff --git a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client.c b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client.c index 66801e0de9..7c5953baee 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client.c +++ b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client.c @@ -70,6 +70,7 @@ static const char pmix_version_string[] = PMIX_VERSION; #include "src/util/output.h" #include "src/runtime/pmix_progress_threads.h" #include "src/runtime/pmix_rte.h" +#include "src/threads/threads.h" #include "src/mca/ptl/ptl.h" #include "src/include/pmix_globals.h" #if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) @@ -134,8 +135,8 @@ static void pmix_client_notify_recv(struct pmix_peer_t *peer, goto error; } - /* we always leave space for the evhandler name plus a callback object */ - chain->ninfo = ninfo + 2; + /* we always leave space for a callback object */ + chain->ninfo = ninfo + 1; PMIX_INFO_CREATE(chain->info, chain->ninfo); if (0 < ninfo) { @@ -145,10 +146,8 @@ static void pmix_client_notify_recv(struct pmix_peer_t *peer, goto error; } } - /* put the evhandler name tag in its place */ - PMIX_INFO_LOAD(&chain->info[chain->ninfo-2], PMIX_EVENT_HDLR_NAME, NULL, PMIX_STRING); /* now put the callback object tag in the last element */ - PMIX_INFO_LOAD(&chain->info[chain->ninfo-1], PMIX_EVENT_RETURN_OBJECT, NULL, PMIX_POINTER); + PMIX_INFO_LOAD(&chain->info[ninfo], PMIX_EVENT_RETURN_OBJECT, NULL, PMIX_POINTER); pmix_output_verbose(2, pmix_globals.debug_output, "[%s:%d] pmix:client_notify_recv - processing event %d, calling errhandler", @@ -168,6 +167,7 @@ static void pmix_client_notify_recv(struct pmix_peer_t *peer, pmix_client_globals_t pmix_client_globals = {{{0}}}; +pmix_mutex_t pmix_client_bootstrap_mutex = PMIX_MUTEX_STATIC_INIT; /* callback for wait completion */ static void wait_cbfunc(struct pmix_peer_t *pr, @@ -330,6 +330,8 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, return PMIX_ERR_BAD_PARAM; } + pmix_mutex_lock(&pmix_client_bootstrap_mutex); + if (0 < pmix_globals.init_cntr || PMIX_PROC_SERVER == pmix_globals.proc_type) { /* since we have been called before, the nspace and * rank should be known. So return them here if @@ -345,10 +347,12 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, _check_for_notify(info, ninfo); } ++pmix_globals.init_cntr; + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return PMIX_SUCCESS; } /* if we don't see the required info, then we cannot init */ if (NULL == getenv("PMIX_NAMESPACE")) { + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return PMIX_ERR_INVALID_NAMESPACE; } @@ -357,12 +361,11 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, if (PMIX_SUCCESS != (rc = pmix_rte_init(PMIX_PROC_CLIENT, info, ninfo, pmix_client_notify_recv))) { PMIX_ERROR_LOG(rc); + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return rc; } /* setup the globals */ - PMIX_CONSTRUCT(&pmix_globals.notifications, pmix_ring_buffer_t); - pmix_ring_buffer_init(&pmix_globals.notifications, 256); PMIX_CONSTRUCT(&pmix_client_globals.pending_requests, pmix_list_t); PMIX_CONSTRUCT(&pmix_client_globals.myserver, pmix_peer_t); @@ -372,6 +375,7 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, /* we require our nspace */ if (NULL == (evar = getenv("PMIX_NAMESPACE"))) { /* let the caller know that the server isn't available yet */ + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return PMIX_ERR_INVALID_NAMESPACE; } if (NULL != proc) { @@ -385,6 +389,7 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, /* we also require our rank */ if (NULL == (evar = getenv("PMIX_RANK"))) { /* let the caller know that the server isn't available yet */ + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return PMIX_ERR_DATA_VALUE_NOT_FOUND; } pmix_globals.myid.rank = strtol(evar, NULL, 10); @@ -398,6 +403,7 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, * to us at launch */ evar = getenv("PMIX_SECURITY_MODE"); if (PMIX_SUCCESS != (rc = pmix_psec.assign_module(pmix_globals.mypeer, evar))) { + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return PMIX_ERR_INIT; } /* the server will be using the same */ @@ -406,12 +412,14 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, /* setup the shared memory support */ #if defined(PMIX_ENABLE_DSTORE) && (PMIX_ENABLE_DSTORE == 1) if (PMIX_SUCCESS != (rc = pmix_dstore_init(NULL, 0))) { + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return PMIX_ERR_DATA_VALUE_NOT_FOUND; } #endif /* PMIX_ENABLE_DSTORE */ /* connect to the server */ if (PMIX_SUCCESS != (rc = pmix_ptl.connect_to_peer(&pmix_client_globals.myserver, info, ninfo))){ + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return rc; } @@ -422,6 +430,7 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(req, &cmd, 1, PMIX_CMD))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(req); + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return rc; } /* send to the server */ @@ -429,6 +438,7 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, cb.active = true; if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(&pmix_client_globals.myserver, req, job_data, (void*)&cb))){ PMIX_DESTRUCT(&cb); + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return rc; } /* wait for the data to return */ @@ -439,6 +449,7 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, if (PMIX_SUCCESS == rc) { pmix_globals.init_cntr++; } else { + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return rc; } @@ -469,14 +480,20 @@ PMIX_EXPORT pmix_status_t PMIx_Init(pmix_proc_t *proc, _check_for_notify(info, ninfo); } + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); + return PMIX_SUCCESS; } PMIX_EXPORT int PMIx_Initialized(void) { + pmix_mutex_lock(&pmix_client_bootstrap_mutex); + if (0 < pmix_globals.init_cntr) { + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return true; } + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return false; } @@ -488,8 +505,10 @@ PMIX_EXPORT pmix_status_t PMIx_Finalize(const pmix_info_t info[], size_t ninfo) size_t n; volatile bool active; + pmix_mutex_lock(&pmix_client_bootstrap_mutex); if (1 != pmix_globals.init_cntr) { --pmix_globals.init_cntr; + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return PMIX_SUCCESS; } pmix_globals.init_cntr = 0; @@ -497,6 +516,9 @@ PMIX_EXPORT pmix_status_t PMIx_Finalize(const pmix_info_t info[], size_t ninfo) pmix_output_verbose(2, pmix_globals.debug_output, "pmix:client finalize called"); + /* mark that I called finalize */ + pmix_globals.mypeer->finalized = true; + if ( 0 <= pmix_client_globals.myserver.sd ) { /* check to see if we are supposed to execute a * blocking fence prior to actually finalizing */ @@ -518,6 +540,7 @@ PMIX_EXPORT pmix_status_t PMIx_Finalize(const pmix_info_t info[], size_t ninfo) } } } + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); /* setup a cmd message to notify the PMIx * server that we are normally terminating */ @@ -585,14 +608,18 @@ PMIX_EXPORT pmix_status_t PMIx_Abort(int flag, const char msg[], pmix_output_verbose(2, pmix_globals.debug_output, "pmix:client abort called"); + pmix_mutex_lock(&pmix_client_bootstrap_mutex); if (pmix_globals.init_cntr <= 0) { + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return PMIX_ERR_INIT; } /* if we aren't connected, don't attempt to send */ if (!pmix_globals.connected) { + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return PMIX_ERR_UNREACH; } + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); /* create a buffer to hold the message */ bfr = PMIX_NEW(pmix_buffer_t); @@ -739,9 +766,12 @@ PMIX_EXPORT pmix_status_t PMIx_Put(pmix_scope_t scope, const char key[], pmix_va "pmix: executing put for key %s type %d", key, val->type); + pmix_mutex_lock(&pmix_client_bootstrap_mutex); if (pmix_globals.init_cntr <= 0) { + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return PMIX_ERR_INIT; } + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); /* create a callback object */ cb = PMIX_NEW(pmix_cb_t); @@ -825,17 +855,22 @@ static void _commitfn(int sd, short args, void *cbdata) pmix_cb_t *cb; pmix_status_t rc; + pmix_mutex_lock(&pmix_client_bootstrap_mutex); if (pmix_globals.init_cntr <= 0) { + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return PMIX_ERR_INIT; } /* if we are a server, or we aren't connected, don't attempt to send */ if (PMIX_PROC_SERVER == pmix_globals.proc_type) { + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return PMIX_SUCCESS; // not an error } if (!pmix_globals.connected) { + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return PMIX_ERR_UNREACH; } + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); /* create a callback object */ cb = PMIX_NEW(pmix_cb_t); @@ -927,9 +962,12 @@ PMIX_EXPORT pmix_status_t PMIx_Resolve_peers(const char *nodename, pmix_cb_t *cb; pmix_status_t rc; + pmix_mutex_lock(&pmix_client_bootstrap_mutex); if (pmix_globals.init_cntr <= 0) { + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return PMIX_ERR_INIT; } + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); /* create a callback object */ cb = PMIX_NEW(pmix_cb_t); @@ -990,9 +1028,12 @@ PMIX_EXPORT pmix_status_t PMIx_Resolve_nodes(const char *nspace, char **nodelist pmix_cb_t *cb; pmix_status_t rc; + pmix_mutex_lock(&pmix_client_bootstrap_mutex); if (pmix_globals.init_cntr <= 0) { + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); return PMIX_ERR_INIT; } + pmix_mutex_unlock(&pmix_client_bootstrap_mutex); /* create a callback object */ cb = PMIX_NEW(pmix_cb_t); diff --git a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_ops.h b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_ops.h index 0de1071595..4fdcf6c2b3 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_ops.h +++ b/opal/mca/pmix/pmix2x/pmix/src/client/pmix_client_ops.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -15,6 +15,7 @@ #include "src/buffer_ops/buffer_ops.h" #include "src/class/pmix_hash_table.h" +#include "src/threads/threads.h" BEGIN_C_DECLS @@ -25,6 +26,8 @@ typedef struct { PMIX_EXPORT extern pmix_client_globals_t pmix_client_globals; +PMIX_EXPORT extern pmix_mutex_t pmix_client_bootstrap_mutex; + END_C_DECLS #endif /* PMIX_CLIENT_OPS_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_esh.c b/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_esh.c index 3884253077..573a83d480 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_esh.c +++ b/opal/mca/pmix/pmix2x/pmix/src/dstore/pmix_esh.c @@ -854,7 +854,13 @@ static inline void _esh_session_release(session_t *s) } _delete_sm_desc(s->sm_seg_first); - close(s->lockfd); + /* the session_t structures are initialized to zero. If + * we release the session without having actually assigned + * a locking fd, then we don't want to close that fd + * as it doesn't belong to us */ + if (0 != s->lockfd) { + close(s->lockfd); + } if (NULL != s->lockfile) { if(PMIX_PROC_SERVER == pmix_globals.proc_type) { diff --git a/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event.h b/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event.h index 2899faa9a6..a8f9818c33 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event.h +++ b/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event.h @@ -22,6 +22,8 @@ #define PMIX_EVENT_H #include +#include "src/include/types.h" +#include PMIX_EVENT_HEADER #include #include "src/class/pmix_list.h" @@ -92,8 +94,10 @@ PMIX_CLASS_DECLARATION(pmix_events_t); * means for us to relay the event across that chain */ typedef struct pmix_event_chain_t { - pmix_object_t super; + pmix_list_item_t super; pmix_status_t status; + pmix_event_t ev; + bool timer_active; bool nondefault; bool endchain; pmix_proc_t source; @@ -120,22 +124,64 @@ pmix_status_t pmix_server_notify_client_of_event(pmix_status_t status, pmix_info_t info[], size_t ninfo, pmix_op_cbfunc_t cbfunc, void *cbdata); -#define PMIX_REPORT_EVENT(e, f) \ - do { \ - pmix_event_chain_t *_ch; \ - _ch = PMIX_NEW(pmix_event_chain_t); \ - _ch->status = (e); \ - _ch->ninfo = 2; \ - _ch->final_cbfunc = (f); \ - _ch->final_cbdata = _ch; \ - PMIX_INFO_CREATE(_ch->info, _ch->ninfo); \ - PMIX_INFO_LOAD(&_ch->info[0], \ - PMIX_EVENT_HDLR_NAME, \ - NULL, PMIX_STRING); \ - PMIX_INFO_LOAD(&_ch->info[1], \ - PMIX_EVENT_RETURN_OBJECT, \ - NULL, PMIX_POINTER); \ - pmix_invoke_local_event_hdlr(_ch); \ +void pmix_event_timeout_cb(int fd, short flags, void *arg); + +#define PMIX_REPORT_EVENT(e, p, r, f) \ + do { \ + pmix_event_chain_t *ch, *cp; \ + size_t n, ninfo; \ + pmix_info_t *info; \ + pmix_proc_t proc; \ + \ + ch = NULL; \ + /* see if we already have this event cached */ \ + PMIX_LIST_FOREACH(cp, &pmix_globals.cached_events, pmix_event_chain_t) { \ + if (cp->status == (e)) { \ + ch = cp; \ + break; \ + } \ + } \ + if (NULL == ch) { \ + /* nope - need to add it */ \ + ch = PMIX_NEW(pmix_event_chain_t); \ + ch->status = (e); \ + ch->range = (r); \ + (void)strncpy(ch->source.nspace, \ + (p)->info->nptr->nspace, \ + PMIX_MAX_NSLEN); \ + ch->source.rank = (p)->info->rank; \ + ch->ninfo = 2; \ + ch->final_cbfunc = (f); \ + ch->final_cbdata = ch; \ + PMIX_INFO_CREATE(ch->info, ch->ninfo); \ + PMIX_INFO_LOAD(&ch->info[0], \ + PMIX_EVENT_HDLR_NAME, \ + NULL, PMIX_STRING); \ + PMIX_INFO_LOAD(&ch->info[1], \ + PMIX_EVENT_RETURN_OBJECT, \ + NULL, PMIX_POINTER); \ + /* cache it */ \ + pmix_list_append(&pmix_globals.cached_events, &ch->super); \ + ch->timer_active = true; \ + pmix_event_assign(&ch->ev, pmix_globals.evbase, -1, 0, \ + pmix_event_timeout_cb, ch); \ + pmix_event_add(&ch->ev, &pmix_globals.event_window); \ + } else { \ + /* add this peer to the array of sources */ \ + (void)strncpy(proc.nspace, (p)->info->nptr->nspace, PMIX_MAX_NSLEN); \ + proc.rank = (p)->info->rank; \ + ninfo = ch->ninfo + 1; \ + PMIX_INFO_CREATE(info, ninfo); \ + /* must keep the hdlr name and return object at the end, so prepend */ \ + PMIX_INFO_LOAD(&info[0], PMIX_PROCID, \ + &proc, PMIX_PROC); \ + for (n=0; n < ch->ninfo; n++) { \ + PMIX_INFO_XFER(&info[n+1], &ch->info[n]); \ + } \ + PMIX_INFO_FREE(ch->info, ch->ninfo); \ + ch->info = info; \ + ch->ninfo = ninfo; \ + } \ } while(0) diff --git a/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event_notification.c b/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event_notification.c index 8b2fc65751..e2832c0a88 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event_notification.c +++ b/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event_notification.c @@ -229,6 +229,8 @@ static pmix_status_t notify_server_of_event(pmix_status_t status, PMIX_RELEASE(cb); goto cleanup; } + } else { + cbfunc(PMIX_SUCCESS, cbdata); } /* now notify any matching registered callbacks we have */ @@ -946,6 +948,24 @@ static bool check_range(pmix_range_trkr_t *rng, return false; } +void pmix_event_timeout_cb(int fd, short flags, void *arg) +{ + pmix_event_chain_t *ch = (pmix_event_chain_t*)arg; + + ch->timer_active = false; + + /* remove it from the list */ + pmix_list_remove_item(&pmix_globals.cached_events, &ch->super); + + /* process this event thru the regular channels */ + if (PMIX_PROC_SERVER == pmix_globals.proc_type) { + pmix_server_notify_client_of_event(ch->status, &ch->source, + ch->range, ch->info, ch->ninfo, + ch->final_cbfunc, ch->final_cbdata); + } else { + pmix_invoke_local_event_hdlr(ch); + } +} /**** CLASS INSTANTIATIONS ****/ @@ -1019,6 +1039,7 @@ PMIX_CLASS_INSTANCE(pmix_events_t, static void chcon(pmix_event_chain_t *p) { + p->timer_active = false; memset(p->source.nspace, 0, PMIX_MAX_NSLEN+1); p->source.rank = PMIX_RANK_UNDEF; p->nondefault = false; @@ -1034,6 +1055,9 @@ static void chcon(pmix_event_chain_t *p) } static void chdes(pmix_event_chain_t *p) { + if (p->timer_active) { + pmix_event_del(&p->ev); + } if (NULL != p->info) { PMIX_INFO_FREE(p->info, p->ninfo); } @@ -1042,5 +1066,5 @@ static void chdes(pmix_event_chain_t *p) } } PMIX_CLASS_INSTANCE(pmix_event_chain_t, - pmix_object_t, + pmix_list_item_t, chcon, chdes); diff --git a/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event_registration.c b/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event_registration.c index 66ab6b21de..0376705018 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event_registration.c +++ b/opal/mca/pmix/pmix2x/pmix/src/event/pmix_event_registration.c @@ -234,6 +234,8 @@ static pmix_status_t _add_hdlr(pmix_rshift_caddy_t *cd, pmix_list_t *xfer) active->code = PMIX_MAX_ERR_CONSTANT; active->nregs = 1; pmix_list_append(&pmix_globals.events.actives, &active->super); + /* ensure we register it */ + need_register = true; } } else { for (n=0; n < cd->ncodes; n++) { @@ -675,7 +677,7 @@ static void reg_event_hdlr(int sd, short args, void *cbdata) } /* check if any matching notifications have been cached */ - for (i=0; i < pmix_globals.notifications.size; i++) { + for (i=0; i < (size_t)pmix_globals.notifications.size; i++) { if (NULL == (ncd = (pmix_notify_caddy_t*)pmix_ring_buffer_poke(&pmix_globals.notifications, i))) { break; } @@ -912,11 +914,10 @@ static void dereg_event_hdlr(int sd, short args, void *cbdata) } } /* if we get here, then the registration could not be found */ - if (NULL != cd->cbfunc.opcbfn) { - cd->cbfunc.opcbfn(PMIX_ERR_NOT_FOUND, cd->cbdata); + if (NULL != msg) { + PMIX_RELEASE(msg); } - PMIX_RELEASE(cd); - return; + goto cleanup; report: if (NULL != msg) { diff --git a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.c b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.c index bdfb143c9a..5dfbcd4d72 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.c +++ b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.c @@ -71,6 +71,7 @@ PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_cb_t, static void pcon(pmix_peer_t *p) { + p->finalized = false; p->info = NULL; p->proc_cnt = 0; p->server_object = NULL; @@ -249,9 +250,9 @@ PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_shift_caddy_t, pmix_object_t, scon, scdes); -PMIX_CLASS_INSTANCE(pmix_info_caddy_t, - pmix_list_item_t, - NULL, NULL); +PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_info_caddy_t, + pmix_list_item_t, + NULL, NULL); static void qcon(pmix_query_caddy_t *p) { @@ -280,6 +281,6 @@ static void jdcon(pmix_job_data_caddy_t *p) #endif } -PMIX_CLASS_INSTANCE(pmix_job_data_caddy_t, - pmix_object_t, - jdcon, NULL); +PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_job_data_caddy_t, + pmix_object_t, + jdcon, NULL); diff --git a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.h b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.h index 300ea224dd..0e5548f733 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.h +++ b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_globals.h @@ -167,6 +167,7 @@ typedef struct pmix_personality_t { * by the socket, not the process nspace/rank */ typedef struct pmix_peer_t { pmix_object_t super; + bool finalized; pmix_rank_info_t *info; int proc_cnt; void *server_object; @@ -374,6 +375,8 @@ typedef struct { pmix_list_t nspaces; // list of pmix_nspace_t for the nspaces we know about pmix_buffer_t *cache_local; // data PUT by me to local scope pmix_buffer_t *cache_remote; // data PUT by me to remote scope + struct timeval event_window; + pmix_list_t cached_events; // events waiting in the window prior to processing pmix_ring_buffer_t notifications; // ring buffer of pending notifications } pmix_globals_t; diff --git a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_stdint.h b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_stdint.h index 982a442671..28c3099ef3 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/include/pmix_stdint.h +++ b/opal/mca/pmix/pmix2x/pmix/src/include/pmix_stdint.h @@ -1,3 +1,4 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana * University Research and Technology @@ -9,8 +10,11 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2016 IBM Corporation. All rights reserved. - * Copyright (c) 2016 Intel, Inc. All rights reserved. + * Copyright (c) 2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2016 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -35,105 +39,36 @@ #include #endif -/* 8-bit */ +/* 128-bit */ -#if SIZEOF_CHAR == 1 +#ifdef HAVE_INT128_T -#ifndef HAVE_INT8_T -typedef signed char int8_t; +typedef int128_t pmix_int128_t; +typedef uint128_t pmix_uint128_t; + +#define HAVE_PMIX_INT128_T 1 + +#elif defined(HAVE___INT128) + +/* suppress warning about __int128 type */ +#pragma GCC diagnostic push +/* Clang won't quietly accept "-pedantic", but GCC versions older than ~4.8 + * won't quietly accept "-Wpedanic". The whole "#pragma GCC diagnostic ..." + * facility only was added to GCC as of version 4.6. */ +#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 6) +#pragma GCC diagnostic ignored "-Wpedantic" +#else +#pragma GCC diagnostic ignored "-pedantic" #endif +typedef __int128 pmix_int128_t; +typedef unsigned __int128 pmix_uint128_t; +#pragma GCC diagnostic pop -#ifndef HAVE_UINT8_T -typedef unsigned char uint8_t; -#endif +#define HAVE_PMIX_INT128_T 1 #else -#error Failed to define 8-bit types - -#endif - -/* 16-bit */ - -#if SIZEOF_SHORT == 2 - -#ifndef HAVE_INT16_T -typedef signed short int16_t; -#endif - -#ifndef HAVE_UINT16_T -typedef unsigned short uint16_t; -#endif - -#else - -#error Failed to define 16-bit types - -#endif - -/* 32-bit */ - -#if SIZEOF_INT == 4 - -#ifndef HAVE_INT32_T -typedef signed int int32_t; -#endif - -#ifndef HAVE_UINT32_T -typedef unsigned int uint32_t; -#endif - -#elif SIZEOF_LONG == 4 - -#ifndef HAVE_INT32_T -typedef signed long int32_t; -#endif - -#ifndef HAVE_UINT32_T -typedef unsigned long uint32_t; -#endif - -#else - -#error Failed to define 32-bit types - -#endif - -/* 64-bit */ - -#if SIZEOF_INT == 8 - -#ifndef HAVE_INT64_T -typedef signed int int64_t; -#endif - -#ifndef HAVE_UINT64_T -typedef unsigned int uint64_t; -#endif - -#elif SIZEOF_LONG == 8 - -#ifndef HAVE_INT64_T -typedef signed long int64_t; -#endif - -#ifndef HAVE_UINT64_T -typedef unsigned long uint64_t; -#endif - -#elif HAVE_LONG_LONG && SIZEOF_LONG_LONG == 8 - -#ifndef HAVE_INT64_T -typedef signed long long int64_t; -#endif - -#ifndef HAVE_UINT64_T -typedef unsigned long long uint64_t; -#endif - -#else - -#error Failed to define 64-bit types +#define HAVE_PMIX_INT128_T 0 #endif @@ -174,143 +109,8 @@ typedef unsigned long long uintptr_t; #endif -/* fix up some constants that may be missing */ -#ifndef SIZE_MAX -# if SIZEOF_VOID_P == SIZEOF_INT -# define SIZE_MAX UINT_MAX -# elif SIZEOF_VOID_P == SIZEOF_LONG -# define SIZE_MAX ULONG_MAX -# else -# error Failed to find value for SIZE_MAX -# endif -#endif /* ifndef SIZE_MAX */ - - /* inttypes.h printf specifiers */ -#ifdef HAVE_INTTYPES_H # include -#else - -# if SIZEOF_LONG == 8 -# define __PRI64_PREFIX "l" -# define __PRIPTR_PREFIX "l" -# else -# define __PRI64_PREFIX "ll" -# define __PRIPTR_PREFIX -# endif - -/* Decimal notation. */ -# define PRId8 "d" -# define PRId16 "d" -# define PRId32 "d" -# define PRId64 __PRI64_PREFIX "d" - -# define PRIdLEAST8 "d" -# define PRIdLEAST16 "d" -# define PRIdLEAST32 "d" -# define PRIdLEAST64 __PRI64_PREFIX "d" - -# define PRIdFAST8 "d" -# define PRIdFAST16 __PRIPTR_PREFIX "d" -# define PRIdFAST32 __PRIPTR_PREFIX "d" -# define PRIdFAST64 __PRI64_PREFIX "d" - -# define PRIi8 "i" -# define PRIi16 "i" -# define PRIi32 "i" -# define PRIi64 __PRI64_PREFIX "i" - -# define PRIiLEAST8 "i" -# define PRIiLEAST16 "i" -# define PRIiLEAST32 "i" -# define PRIiLEAST64 __PRI64_PREFIX "i" - -# define PRIiFAST8 "i" -# define PRIiFAST16 __PRIPTR_PREFIX "i" -# define PRIiFAST32 __PRIPTR_PREFIX "i" -# define PRIiFAST64 __PRI64_PREFIX "i" - -/* Octal notation. */ -# define PRIo8 "o" -# define PRIo16 "o" -# define PRIo32 "o" -# define PRIo64 __PRI64_PREFIX "o" - -# define PRIoLEAST8 "o" -# define PRIoLEAST16 "o" -# define PRIoLEAST32 "o" -# define PRIoLEAST64 __PRI64_PREFIX "o" - -# define PRIoFAST8 "o" -# define PRIoFAST16 __PRIPTR_PREFIX "o" -# define PRIoFAST32 __PRIPTR_PREFIX "o" -# define PRIoFAST64 __PRI64_PREFIX "o" - -/* Unsigned integers. */ -# define PRIu8 "u" -# define PRIu16 "u" -# define PRIu32 "u" -# define PRIu64 __PRI64_PREFIX "u" - -# define PRIuLEAST8 "u" -# define PRIuLEAST16 "u" -# define PRIuLEAST32 "u" -# define PRIuLEAST64 __PRI64_PREFIX "u" - -# define PRIuFAST8 "u" -# define PRIuFAST16 __PRIPTR_PREFIX "u" -# define PRIuFAST32 __PRIPTR_PREFIX "u" -# define PRIuFAST64 __PRI64_PREFIX "u" - -/* lowercase hexadecimal notation. */ -# define PRIx8 "x" -# define PRIx16 "x" -# define PRIx32 "x" -# define PRIx64 __PRI64_PREFIX "x" - -# define PRIxLEAST8 "x" -# define PRIxLEAST16 "x" -# define PRIxLEAST32 "x" -# define PRIxLEAST64 __PRI64_PREFIX "x" - -# define PRIxFAST8 "x" -# define PRIxFAST16 __PRIPTR_PREFIX "x" -# define PRIxFAST32 __PRIPTR_PREFIX "x" -# define PRIxFAST64 __PRI64_PREFIX "x" - -/* UPPERCASE hexadecimal notation. */ -# define PRIX8 "X" -# define PRIX16 "X" -# define PRIX32 "X" -# define PRIX64 __PRI64_PREFIX "X" - -# define PRIXLEAST8 "X" -# define PRIXLEAST16 "X" -# define PRIXLEAST32 "X" -# define PRIXLEAST64 __PRI64_PREFIX "X" - -# define PRIXFAST8 "X" -# define PRIXFAST16 __PRIPTR_PREFIX "X" -# define PRIXFAST32 __PRIPTR_PREFIX "X" -# define PRIXFAST64 __PRI64_PREFIX "X" - -/* Macros for printing `intmax_t' and `uintmax_t'. */ -# define PRIdMAX __PRI64_PREFIX "d" -# define PRIiMAX __PRI64_PREFIX "i" -# define PRIoMAX __PRI64_PREFIX "o" -# define PRIuMAX __PRI64_PREFIX "u" -# define PRIxMAX __PRI64_PREFIX "x" -# define PRIXMAX __PRI64_PREFIX "X" - -/* Macros for printing `intptr_t' and `uintptr_t'. */ -# define PRIdPTR __PRIPTR_PREFIX "d" -# define PRIiPTR __PRIPTR_PREFIX "i" -# define PRIoPTR __PRIPTR_PREFIX "o" -# define PRIuPTR __PRIPTR_PREFIX "u" -# define PRIxPTR __PRIPTR_PREFIX "x" -# define PRIXPTR __PRIPTR_PREFIX "X" - -#endif #ifndef PRIsize_t # if defined(ACCEPT_C99) diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/configure.m4 b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/configure.m4 index 975e0dad05..f70e5a796e 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/configure.m4 +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/pdl/pdlopen/configure.m4 @@ -63,7 +63,7 @@ AC_DEFUN([MCA_pmix_pdl_pdlopen_CONFIG],[ ]) AS_IF([test "$pmix_pdl_pdlopen_happy" = "yes"], - [pmix_pdl_pdlopen_ADD_LIBS=$pmix_pdl_pdlopen_LIBS + [pdl_pdlopen_ADD_LIBS=$pmix_pdl_pdlopen_LIBS $1], [$2]) diff --git a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_sendrecv.c b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_sendrecv.c index 705d7861ab..5301d8a021 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_sendrecv.c +++ b/opal/mca/pmix/pmix2x/pmix/src/mca/ptl/base/ptl_base_sendrecv.c @@ -41,6 +41,7 @@ #include "src/class/pmix_pointer_array.h" #include "src/include/pmix_globals.h" +#include "src/client/pmix_client_ops.h" #include "src/server/pmix_server_ops.h" #include "src/util/error.h" @@ -137,9 +138,16 @@ static void lost_connection(pmix_peer_t *peer, pmix_status_t err) break; } } - } - } - PMIX_RELEASE(peer); + } + } + if (!peer->finalized) { + /* if this peer already called finalize, then + * we are just seeing their connection go away + * when they terminate - so do not generate + * an event. If not, then we do */ + PMIX_REPORT_EVENT(err, peer, PMIX_RANGE_NAMESPACE, _notify_complete); + } + PMIX_RELEASE(peer); } else { /* if I am a client, there is only * one connection we can have */ @@ -163,8 +171,11 @@ static void lost_connection(pmix_peer_t *peer, pmix_status_t err) } } PMIX_DESTRUCT(&buf); + /* if I called finalize, then don't generate an event */ + if (!pmix_globals.mypeer->finalized) { + PMIX_REPORT_EVENT(err, &pmix_client_globals.myserver, PMIX_RANGE_LOCAL, _notify_complete); + } } - PMIX_REPORT_EVENT(err, _notify_complete); } static pmix_status_t send_msg(int sd, pmix_ptl_send_t *msg) @@ -634,8 +645,8 @@ void pmix_ptl_base_process_msg(int fd, short flags, void *cbdata) * that is an error */ if (PMIX_PTL_TAG_DYNAMIC <= msg->hdr.tag) { pmix_output(0, "UNEXPECTED MESSAGE tag = %d", msg->hdr.tag); + PMIX_REPORT_EVENT(PMIX_ERROR, msg->peer, PMIX_RANGE_NAMESPACE, _notify_complete); PMIX_RELEASE(msg); - PMIX_REPORT_EVENT(PMIX_ERROR, _notify_complete); return; } diff --git a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_finalize.c b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_finalize.c index 5f2f705362..4caeea2f56 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_finalize.c +++ b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_finalize.c @@ -114,6 +114,8 @@ void pmix_rte_finalize(void) PMIX_RELEASE(pmix_globals.cache_remote); } PMIX_DESTRUCT(&pmix_globals.events); + PMIX_LIST_DESTRUCT(&pmix_globals.cached_events); + PMIX_DESTRUCT(&pmix_globals.notifications); /* now safe to release the event base */ if (!pmix_globals.external_evbase) { diff --git a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_init.c b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_init.c index d46ddf337d..0249279960 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_init.c +++ b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_init.c @@ -15,7 +15,7 @@ * Copyright (c) 2009 Oak Ridge National Labs. All rights reserved. * Copyright (c) 2010-2015 Los Alamos National Security, LLC. * All rights reserved. - * Copyright (c) 2013-2016 Intel, Inc. All rights reserved + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. * $COPYRIGHT$ @@ -153,6 +153,13 @@ int pmix_rte_init(pmix_proc_type_t type, memset(&pmix_globals.myid, 0, sizeof(pmix_proc_t)); PMIX_CONSTRUCT(&pmix_globals.nspaces, pmix_list_t); PMIX_CONSTRUCT(&pmix_globals.events, pmix_events_t); + pmix_globals.event_window.tv_sec = pmix_event_caching_window; + pmix_globals.event_window.tv_usec = 0; + PMIX_CONSTRUCT(&pmix_globals.cached_events, pmix_list_t); + /* construct the global notification ring buffer */ + PMIX_CONSTRUCT(&pmix_globals.notifications, pmix_ring_buffer_t); + pmix_ring_buffer_init(&pmix_globals.notifications, 256); + /* get our effective id's */ pmix_globals.uid = geteuid(); pmix_globals.gid = getegid(); diff --git a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_params.c b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_params.c index e2c60025bb..7432cdca9a 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_params.c +++ b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_params.c @@ -43,6 +43,7 @@ bool pmix_timing_overhead = true; static bool pmix_register_done = false; char *pmix_net_private_ipv4 = NULL; +int pmix_event_caching_window; pmix_status_t pmix_register_params(void) { @@ -90,6 +91,14 @@ pmix_status_t pmix_register_params(void) return ret; } + pmix_event_caching_window = 3; + (void) pmix_mca_base_var_register ("pmix", "pmix", NULL, "event_caching_window", + "Time (in seconds) to cache events before reporting them - this " + "allows for event aggregation", + PMIX_MCA_BASE_VAR_TYPE_INT, NULL, 0, 0, + PMIX_INFO_LVL_9, PMIX_MCA_BASE_VAR_SCOPE_ALL, + &pmix_event_caching_window); + return PMIX_SUCCESS; } diff --git a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_progress_threads.c b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_progress_threads.c index f3002445cb..efa32eaa6b 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_progress_threads.c +++ b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_progress_threads.c @@ -21,53 +21,12 @@ #include PMIX_EVENT_HEADER #include "src/class/pmix_list.h" +#include "src/threads/threads.h" #include "src/util/error.h" #include "src/util/fd.h" #include "src/runtime/pmix_progress_threads.h" -/* define a thread object */ -#define PMIX_THREAD_CANCELLED ((void*)1); -typedef void *(*pmix_thread_fn_t) (pmix_object_t *); - -typedef struct pmix_thread_t { - pmix_object_t super; - pmix_thread_fn_t t_run; - void* t_arg; - pthread_t t_handle; -} pmix_thread_t; -static void ptcon(pmix_thread_t *p) -{ - p->t_arg = NULL; - p->t_handle = (pthread_t) -1; -} -PMIX_CLASS_INSTANCE(pmix_thread_t, - pmix_object_t, - ptcon, NULL); - -static int pmix_thread_start(pmix_thread_t *t) -{ - int rc; - - if (PMIX_ENABLE_DEBUG) { - if (NULL == t->t_run || t->t_handle != (pthread_t) -1) { - return PMIX_ERR_BAD_PARAM; - } - } - - rc = pthread_create(&t->t_handle, NULL, (void*(*)(void*)) t->t_run, t); - - return (rc == 0) ? PMIX_SUCCESS : PMIX_ERROR; -} - - -static int pmix_thread_join(pmix_thread_t *t, void **thr_return) -{ - int rc = pthread_join(t->t_handle, thr_return); - t->t_handle = (pthread_t) -1; - return (rc == 0) ? PMIX_SUCCESS : PMIX_ERROR; -} - /* create a tracking object for progress threads */ typedef struct { diff --git a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_rte.h b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_rte.h index 0ef36e271e..aacf0f1ede 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_rte.h +++ b/opal/mca/pmix/pmix2x/pmix/src/runtime/pmix_rte.h @@ -11,7 +11,7 @@ * All rights reserved. * Copyright (c) 2008 Sun Microsystems, Inc. All rights reserved. * Copyright (c) 2010-2012 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2014-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2014-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -46,6 +46,7 @@ extern bool pmix_timing_overhead; extern int pmix_initialized; extern char *pmix_net_private_ipv4; +extern int pmix_event_caching_window; /** version string of pmix */ extern const char pmix_version_string[]; diff --git a/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server.c b/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server.c index 7046511180..bcfe3a2c7e 100644 --- a/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server.c +++ b/opal/mca/pmix/pmix2x/pmix/src/server/pmix_server.c @@ -105,10 +105,6 @@ static pmix_status_t initialize_server_base(pmix_server_module_t *module) pmix_globals.myid.rank = strtol(evar, NULL, 10); } - /* construct the global notification ring buffer */ - PMIX_CONSTRUCT(&pmix_globals.notifications, pmix_ring_buffer_t); - pmix_ring_buffer_init(&pmix_globals.notifications, 256); - /* setup the server-specific globals */ PMIX_CONSTRUCT(&pmix_server_globals.clients, pmix_pointer_array_t); pmix_pointer_array_init(&pmix_server_globals.clients, 1, INT_MAX, 1); @@ -263,7 +259,6 @@ PMIX_EXPORT pmix_status_t PMIx_server_finalize(void) PMIX_LIST_DESTRUCT(&pmix_server_globals.remote_pnd); PMIX_LIST_DESTRUCT(&pmix_server_globals.local_reqs); PMIX_DESTRUCT(&pmix_server_globals.gdata); - PMIX_DESTRUCT(&pmix_globals.notifications); PMIX_LIST_DESTRUCT(&pmix_server_globals.events); if (NULL != security_mode) { @@ -1020,7 +1015,7 @@ PMIX_EXPORT pmix_status_t PMIx_server_dmodex_request(const pmix_proc_t *proc, } pmix_output_verbose(2, pmix_globals.debug_output, - "pmix:server register client %s:%d", + "pmix:server dmodex request%s:%d", proc->nspace, proc->rank); cd = PMIX_NEW(pmix_setup_caddy_t); @@ -2222,6 +2217,8 @@ static pmix_status_t server_switchyard(pmix_peer_t *peer, uint32_t tag, if (PMIX_FINALIZE_CMD == cmd) { pmix_output_verbose(2, pmix_globals.debug_output, "recvd FINALIZE"); + /* mark that this peer called finalize */ + peer->finalized = true; /* call the local server, if supported */ if (NULL != pmix_host_server.client_finalized) { PMIX_PEER_CADDY(cd, peer, tag); diff --git a/opal/mca/pmix/pmix2x/pmix/src/threads/Makefile.include b/opal/mca/pmix/pmix2x/pmix/src/threads/Makefile.include new file mode 100644 index 0000000000..ba93edb67a --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/threads/Makefile.include @@ -0,0 +1,40 @@ +# -*- makefile -*- +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2016 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2014 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2015 Research Organization for Information Science +# and Technology (RIST). All rights reserved. +# Copyright (c) 2017 Intel, Inc. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# This makefile.am does not stand on its own - it is included from pmix/Makefile.am + +# Source code files +headers += \ + threads/condition.h \ + threads/mutex.h \ + threads/mutex_unix.h \ + threads/threads.h \ + threads/tsd.h \ + threads/wait_sync.h \ + threads/thread_usage.h + +libpmix_la_SOURCES += \ + threads/condition.c \ + threads/mutex.c \ + threads/thread.c \ + threads/wait_sync.c diff --git a/opal/mca/pmix/pmix2x/pmix/src/threads/condition.c b/opal/mca/pmix/pmix2x/pmix/src/threads/condition.c new file mode 100644 index 0000000000..13a9d3ab16 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/threads/condition.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "pmix_config.h" + +#include "src/threads/condition.h" + + +static void pmix_condition_construct(pmix_condition_t *c) +{ + c->c_waiting = 0; + c->c_signaled = 0; +} + + +static void pmix_condition_destruct(pmix_condition_t *c) +{ +} + +PMIX_CLASS_INSTANCE(pmix_condition_t, + pmix_object_t, + pmix_condition_construct, + pmix_condition_destruct); diff --git a/opal/mca/pmix/pmix2x/pmix/src/threads/condition.h b/opal/mca/pmix/pmix2x/pmix/src/threads/condition.h new file mode 100644 index 0000000000..7a18660d8f --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/threads/condition.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2007 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2015 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +#ifndef PMIX_CONDITION_SPINLOCK_H +#define PMIX_CONDITION_SPINLOCK_H + +#include "pmix_config.h" +#ifdef HAVE_SYS_TIME_H +#include +#endif +#include +#include + +#include "src/threads/mutex.h" + +BEGIN_C_DECLS + +struct pmix_condition_t { + pmix_object_t super; + volatile int c_waiting; + volatile int c_signaled; +}; +typedef struct pmix_condition_t pmix_condition_t; + +PMIX_EXPORT PMIX_CLASS_DECLARATION(pmix_condition_t); + + +static inline int pmix_condition_wait(pmix_condition_t *c, pmix_mutex_t *m) +{ + int rc = 0; + c->c_waiting++; + + if (c->c_signaled) { + c->c_waiting--; + return 0; + } + + c->c_signaled--; + c->c_waiting--; + return rc; +} + +static inline int pmix_condition_signal(pmix_condition_t *c) +{ + if (c->c_waiting) { + c->c_signaled++; + } + return 0; +} + +static inline int pmix_condition_broadcast(pmix_condition_t *c) +{ + c->c_signaled = c->c_waiting; + return 0; +} + +END_C_DECLS + +#endif diff --git a/opal/mca/pmix/pmix2x/pmix/src/threads/mutex.c b/opal/mca/pmix/pmix2x/pmix/src/threads/mutex.c new file mode 100644 index 0000000000..d7f5e9298e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/threads/mutex.c @@ -0,0 +1,94 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2007-2016 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2015 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "pmix_config.h" + +#include "src/threads/mutex.h" + +static void pmix_mutex_construct(pmix_mutex_t *m) +{ +#if PMIX_ENABLE_DEBUG + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + + /* set type to ERRORCHECK so that we catch recursive locks */ +#if PMIX_HAVE_PTHREAD_MUTEX_ERRORCHECK_NP + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP); +#elif PMIX_HAVE_PTHREAD_MUTEX_ERRORCHECK + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); +#endif /* PMIX_HAVE_PTHREAD_MUTEX_ERRORCHECK_NP */ + + pthread_mutex_init(&m->m_lock_pthread, &attr); + pthread_mutexattr_destroy(&attr); + + m->m_lock_debug = 0; + m->m_lock_file = NULL; + m->m_lock_line = 0; +#else + + /* Without debugging, choose the fastest available mutexes */ + pthread_mutex_init(&m->m_lock_pthread, NULL); + +#endif /* PMIX_ENABLE_DEBUG */ + +#if PMIX_HAVE_ATOMIC_SPINLOCKS + pmix_atomic_init( &m->m_lock_atomic, PMIX_ATOMIC_UNLOCKED ); +#endif +} + +static void pmix_mutex_destruct(pmix_mutex_t *m) +{ + pthread_mutex_destroy(&m->m_lock_pthread); +} + +PMIX_CLASS_INSTANCE(pmix_mutex_t, + pmix_object_t, + pmix_mutex_construct, + pmix_mutex_destruct); + +static void pmix_recursive_mutex_construct(pmix_recursive_mutex_t *m) +{ + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + +#if PMIX_ENABLE_DEBUG + m->m_lock_debug = 0; + m->m_lock_file = NULL; + m->m_lock_line = 0; +#endif + + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + + pthread_mutex_init(&m->m_lock_pthread, &attr); + pthread_mutexattr_destroy(&attr); + +#if PMIX_HAVE_ATOMIC_SPINLOCKS + pmix_atomic_init( &m->m_lock_atomic, PMIX_ATOMIC_UNLOCKED ); +#endif +} + +PMIX_CLASS_INSTANCE(pmix_recursive_mutex_t, + pmix_object_t, + pmix_recursive_mutex_construct, + pmix_mutex_destruct); diff --git a/opal/mca/pmix/pmix2x/pmix/src/threads/mutex.h b/opal/mca/pmix/pmix2x/pmix/src/threads/mutex.h new file mode 100644 index 0000000000..37a3a4c2d0 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/threads/mutex.h @@ -0,0 +1,103 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2016 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2007-2016 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2007 Voltaire. All rights reserved. + * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_MUTEX_H +#define PMIX_MUTEX_H 1 + +#include "pmix_config.h" + +#include "src/threads/thread_usage.h" + +BEGIN_C_DECLS + +/** + * @file: + * + * Mutual exclusion functions. + * + * Functions for locking of critical sections. + */ + +/** + * Opaque mutex object + */ +typedef struct pmix_mutex_t pmix_mutex_t; +typedef struct pmix_mutex_t pmix_recursive_mutex_t; + +/** + * Try to acquire a mutex. + * + * @param mutex Address of the mutex. + * @return 0 if the mutex was acquired, 1 otherwise. + */ +static inline int pmix_mutex_trylock(pmix_mutex_t *mutex); + + +/** + * Acquire a mutex. + * + * @param mutex Address of the mutex. + */ +static inline void pmix_mutex_lock(pmix_mutex_t *mutex); + + +/** + * Release a mutex. + * + * @param mutex Address of the mutex. + */ +static inline void pmix_mutex_unlock(pmix_mutex_t *mutex); + + +/** + * Try to acquire a mutex using atomic operations. + * + * @param mutex Address of the mutex. + * @return 0 if the mutex was acquired, 1 otherwise. + */ +static inline int pmix_mutex_atomic_trylock(pmix_mutex_t *mutex); + + +/** + * Acquire a mutex using atomic operations. + * + * @param mutex Address of the mutex. + */ +static inline void pmix_mutex_atomic_lock(pmix_mutex_t *mutex); + + +/** + * Release a mutex using atomic operations. + * + * @param mutex Address of the mutex. + */ +static inline void pmix_mutex_atomic_unlock(pmix_mutex_t *mutex); + +END_C_DECLS + +#include "mutex_unix.h" + +#endif /* PMIX_MUTEX_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/threads/mutex_unix.h b/opal/mca/pmix/pmix2x/pmix/src/threads/mutex_unix.h new file mode 100644 index 0000000000..ffe3249040 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/threads/mutex_unix.h @@ -0,0 +1,215 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2006 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2007-2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2015-2016 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef PMIX_MUTEX_UNIX_H +#define PMIX_MUTEX_UNIX_H 1 + +/** + * @file: + * + * Mutual exclusion functions: Unix implementation. + * + * Functions for locking of critical sections. + * + * On unix, use pthreads or our own atomic operations as + * available. + */ + +#include "pmix_config.h" + +#include +#include +#include + +#include "src/class/pmix_object.h" +#include "src/atomics/sys/atomic.h" + +BEGIN_C_DECLS + +struct pmix_mutex_t { + pmix_object_t super; + + pthread_mutex_t m_lock_pthread; + +#if PMIX_ENABLE_DEBUG + int m_lock_debug; + const char *m_lock_file; + int m_lock_line; +#endif + + pmix_atomic_lock_t m_lock_atomic; +}; +PMIX_EXPORT PMIX_CLASS_DECLARATION(pmix_mutex_t); +PMIX_EXPORT PMIX_CLASS_DECLARATION(pmix_recursive_mutex_t); + +#if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) +#define PMIX_PTHREAD_RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP +#elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) +#define PMIX_PTHREAD_RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER +#endif + +#if PMIX_ENABLE_DEBUG +#define PMIX_MUTEX_STATIC_INIT \ + { \ + .super = PMIX_OBJ_STATIC_INIT(pmix_mutex_t), \ + .m_lock_pthread = PTHREAD_MUTEX_INITIALIZER, \ + .m_lock_debug = 0, \ + .m_lock_file = NULL, \ + .m_lock_line = 0, \ + .m_lock_atomic = { .u = { .lock = PMIX_ATOMIC_UNLOCKED } }, \ + } +#else +#define PMIX_MUTEX_STATIC_INIT \ + { \ + .super = PMIX_OBJ_STATIC_INIT(pmix_mutex_t), \ + .m_lock_pthread = PTHREAD_MUTEX_INITIALIZER, \ + .m_lock_atomic = { .u = { .lock = PMIX_ATOMIC_UNLOCKED } }, \ + } +#endif + +#if defined(PMIX_PTHREAD_RECURSIVE_MUTEX_INITIALIZER) + +#if PMIX_ENABLE_DEBUG +#define PMIX_RECURSIVE_MUTEX_STATIC_INIT \ + { \ + .super = PMIX_OBJ_STATIC_INIT(pmix_mutex_t), \ + .m_lock_pthread = PMIX_PTHREAD_RECURSIVE_MUTEX_INITIALIZER, \ + .m_lock_debug = 0, \ + .m_lock_file = NULL, \ + .m_lock_line = 0, \ + .m_lock_atomic = { .u = { .lock = PMIX_ATOMIC_UNLOCKED } }, \ + } +#else +#define PMIX_RECURSIVE_MUTEX_STATIC_INIT \ + { \ + .super = PMIX_OBJ_STATIC_INIT(pmix_mutex_t), \ + .m_lock_pthread = PMIX_PTHREAD_RECURSIVE_MUTEX_INITIALIZER, \ + .m_lock_atomic = { .u = { .lock = PMIX_ATOMIC_UNLOCKED } }, \ + } +#endif + +#endif + +/************************************************************************ + * + * mutex operations (non-atomic versions) + * + ************************************************************************/ + +static inline int pmix_mutex_trylock(pmix_mutex_t *m) +{ +#if PMIX_ENABLE_DEBUG + int ret = pthread_mutex_trylock(&m->m_lock_pthread); + if (ret == EDEADLK) { + errno = ret; + perror("pmix_mutex_trylock()"); + abort(); + } + return ret; +#else + return pthread_mutex_trylock(&m->m_lock_pthread); +#endif +} + +static inline void pmix_mutex_lock(pmix_mutex_t *m) +{ +#if PMIX_ENABLE_DEBUG + int ret = pthread_mutex_lock(&m->m_lock_pthread); + if (ret == EDEADLK) { + errno = ret; + perror("pmix_mutex_lock()"); + abort(); + } +#else + pthread_mutex_lock(&m->m_lock_pthread); +#endif +} + +static inline void pmix_mutex_unlock(pmix_mutex_t *m) +{ +#if PMIX_ENABLE_DEBUG + int ret = pthread_mutex_unlock(&m->m_lock_pthread); + if (ret == EPERM) { + errno = ret; + perror("pmix_mutex_unlock"); + abort(); + } +#else + pthread_mutex_unlock(&m->m_lock_pthread); +#endif +} + +/************************************************************************ + * + * mutex operations (atomic versions) + * + ************************************************************************/ + +#if PMIX_HAVE_ATOMIC_SPINLOCKS + +/************************************************************************ + * Spin Locks + ************************************************************************/ + +static inline int pmix_mutex_atomic_trylock(pmix_mutex_t *m) +{ + return pmix_atomic_trylock(&m->m_lock_atomic); +} + +static inline void pmix_mutex_atomic_lock(pmix_mutex_t *m) +{ + pmix_atomic_lock(&m->m_lock_atomic); +} + +static inline void pmix_mutex_atomic_unlock(pmix_mutex_t *m) +{ + pmix_atomic_unlock(&m->m_lock_atomic); +} + +#else + +/************************************************************************ + * Standard locking + ************************************************************************/ + +static inline int pmix_mutex_atomic_trylock(pmix_mutex_t *m) +{ + return pmix_mutex_trylock(m); +} + +static inline void pmix_mutex_atomic_lock(pmix_mutex_t *m) +{ + pmix_mutex_lock(m); +} + +static inline void pmix_mutex_atomic_unlock(pmix_mutex_t *m) +{ + pmix_mutex_unlock(m); +} + +#endif + +END_C_DECLS + +#endif /* PMIX_MUTEX_UNIX_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/threads/thread.c b/opal/mca/pmix/pmix2x/pmix/src/threads/thread.c new file mode 100644 index 0000000000..6513cc9e49 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/threads/thread.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2010 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2015-2017 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "pmix_config.h" + +#include "src/threads/threads.h" +#include "src/threads/tsd.h" +#include "pmix_common.h" + +bool pmix_debug_threads = false; + +static void pmix_thread_construct(pmix_thread_t *t); + +static pthread_t pmix_main_thread; + +struct pmix_tsd_key_value { + pmix_tsd_key_t key; + pmix_tsd_destructor_t destructor; +}; + +static struct pmix_tsd_key_value *pmix_tsd_key_values = NULL; +static int pmix_tsd_key_values_count = 0; + +PMIX_EXPORT PMIX_CLASS_INSTANCE(pmix_thread_t, + pmix_object_t, + pmix_thread_construct, NULL); + + +/* + * Constructor + */ +static void pmix_thread_construct(pmix_thread_t *t) +{ + t->t_run = 0; + t->t_handle = (pthread_t) -1; +} + +int pmix_thread_start(pmix_thread_t *t) +{ + int rc; + + if (PMIX_ENABLE_DEBUG) { + if (NULL == t->t_run || t->t_handle != (pthread_t) -1) { + return PMIX_ERR_BAD_PARAM; + } + } + + rc = pthread_create(&t->t_handle, NULL, (void*(*)(void*)) t->t_run, t); + + return (rc == 0) ? PMIX_SUCCESS : PMIX_ERROR; +} + + +int pmix_thread_join(pmix_thread_t *t, void **thr_return) +{ + int rc = pthread_join(t->t_handle, thr_return); + t->t_handle = (pthread_t) -1; + return (rc == 0) ? PMIX_SUCCESS : PMIX_ERROR; +} + + +bool pmix_thread_self_compare(pmix_thread_t *t) +{ + return t->t_handle == pthread_self(); +} + + +pmix_thread_t *pmix_thread_get_self(void) +{ + pmix_thread_t *t = PMIX_NEW(pmix_thread_t); + t->t_handle = pthread_self(); + return t; +} + +void pmix_thread_kill(pmix_thread_t *t, int sig) +{ + pthread_kill(t->t_handle, sig); +} + +int pmix_tsd_key_create(pmix_tsd_key_t *key, + pmix_tsd_destructor_t destructor) +{ + int rc; + rc = pthread_key_create(key, destructor); + if ((0 == rc) && (pthread_self() == pmix_main_thread)) { + pmix_tsd_key_values = (struct pmix_tsd_key_value *)realloc(pmix_tsd_key_values, (pmix_tsd_key_values_count+1) * sizeof(struct pmix_tsd_key_value)); + pmix_tsd_key_values[pmix_tsd_key_values_count].key = *key; + pmix_tsd_key_values[pmix_tsd_key_values_count].destructor = destructor; + pmix_tsd_key_values_count ++; + } + return rc; +} + +int pmix_tsd_keys_destruct() +{ + int i; + void * ptr; + for (i=0; i +#include + +#include "src/class/pmix_object.h" +#if PMIX_ENABLE_DEBUG +#include "src/util/output.h" +#endif + +#include "mutex.h" +#include "condition.h" + +BEGIN_C_DECLS + +typedef void *(*pmix_thread_fn_t) (pmix_object_t *); + +#define PMIX_THREAD_CANCELLED ((void*)1); + +struct pmix_thread_t { + pmix_object_t super; + pmix_thread_fn_t t_run; + void* t_arg; + pthread_t t_handle; +}; + +typedef struct pmix_thread_t pmix_thread_t; + +#if PMIX_ENABLE_DEBUG +PMIX_EXPORT extern bool pmix_debug_threads; +#endif + + +PMIX_EXPORT PMIX_CLASS_DECLARATION(pmix_thread_t); + +#if PMIX_ENABLE_DEBUG +#define PMIX_ACQUIRE_THREAD(lck, cnd, act) \ + do { \ + PMIX_THREAD_LOCK((lck)); \ + if (pmix_debug_threads) { \ + pmix_output(0, "Waiting for thread %s:%d", \ + __FILE__, __LINE__); \ + } \ + while (*(act)) { \ + pmix_condition_wait((cnd), (lck)); \ + } \ + if (pmix_debug_threads) { \ + pmix_output(0, "Thread obtained %s:%d", \ + __FILE__, __LINE__); \ + } \ + *(act) = true; \ + } while(0); +#else +#define PMIX_ACQUIRE_THREAD(lck, cnd, act) \ + do { \ + PMIX_THREAD_LOCK((lck)); \ + while (*(act)) { \ + pmix_condition_wait((cnd), (lck)); \ + } \ + *(act) = true; \ + } while(0); +#endif + + +#if PMIX_ENABLE_DEBUG +#define PMIX_RELEASE_THREAD(lck, cnd, act) \ + do { \ + if (pmix_debug_threads) { \ + pmix_output(0, "Releasing thread %s:%d", \ + __FILE__, __LINE__); \ + } \ + *(act) = false; \ + pmix_condition_broadcast((cnd)); \ + PMIX_THREAD_UNLOCK((lck)); \ + } while(0); +#else +#define PMIX_RELEASE_THREAD(lck, cnd, act) \ + do { \ + *(act) = false; \ + pmix_condition_broadcast((cnd)); \ + PMIX_THREAD_UNLOCK((lck)); \ + } while(0); +#endif + + +#define PMIX_WAKEUP_THREAD(cnd, act) \ + do { \ + *(act) = false; \ + pmix_condition_broadcast((cnd)); \ + } while(0); + + +PMIX_EXPORT int pmix_thread_start(pmix_thread_t *); +PMIX_EXPORT int pmix_thread_join(pmix_thread_t *, void **thread_return); +PMIX_EXPORT bool pmix_thread_self_compare(pmix_thread_t*); +PMIX_EXPORT pmix_thread_t *pmix_thread_get_self(void); +PMIX_EXPORT void pmix_thread_kill(pmix_thread_t *, int sig); +PMIX_EXPORT void pmix_thread_set_main(void); + +END_C_DECLS + +#endif /* PMIX_THREAD_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/threads/tsd.h b/opal/mca/pmix/pmix2x/pmix/src/threads/tsd.h new file mode 100644 index 0000000000..589027217e --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/threads/tsd.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2007-2013 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2008 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2015-2017 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + + +#ifndef PMIX_THREADS_TSD_H +#define PMIX_THREADS_TSD_H + +#include "pmix_config.h" + +#include + +#include "pmix_common.h" + +BEGIN_C_DECLS + +/** + * @file + * + * Thread Specific Datastore Interface + * + * Functions for providing thread-specific datastore capabilities. + */ + + +/** + * Prototype for callback when tsd data is being destroyed + */ +typedef void (*pmix_tsd_destructor_t)(void *value); + +#if defined(DOXYGEN) + +/** + * Typedef for thread-specific data key + */ +typedef void* pmix_tsd_key_t; + + +/** + * Delete a thread-specific data key + * + * Delete a thread-specific data key previously returned by + * pmix_tsd_key_create(). The destructor associated with the key is + * not fired in any thread and memory cleanup is the responsibility of + * the caller. + * + * @note Unlike pthread_key_delete, this function should not be called + * from within a destructor. It can not be universally supported at + * this time. + * + * @param key[in] The key for accessing thread-specific data + * + * @retval PMIX_SUCCESS Success + * @retval EINVAL Invalid key + */ +PMIX_EXPORT int pmix_tsd_key_delete(pmix_tsd_key_t key); + + +/** + * Set a thread-specific data value + * + * Associates value with key in the current thread. The value for the + * key in other threads is not changed. Different threads may assign + * different values to the same key. + * + * @note This function should not be called within + * pmix_tsd_key_delete(). + * + * @param key[in] Thread specific data key to modify + * @param value[in] Value to associate with key + * + * @retval PMIX_SUCCESS Success + * @retval ENOMEM Insufficient memory exists to associate the + * value with the key + * @retval EINVAL Invalid key + */ +PMIX_EXPORT int pmix_tsd_setspecific(pmix_tsd_key_t key, void *value); + + +/** + * Get a thread-specific data value + * + * Get the data associated with the given key, as set by + * pmix_tsd_setspecific(). If pmix_tsd_setspecific() hasn't been + * called in the current thread with the given key, NULL is returned + * in valuep. + * + * @param key[in] Thread specific data key to modify + * @param value[out] Value to associate with key + * + * @retval PMIX_SUCCESS Success + * @retval ENOMEM Insufficient memory exists to associate the + * value with the key + * @retval EINVAL Invalid key + */ +PMIX_EXPORT int pmix_tsd_getspecific(pmix_tsd_key_t key, void **valuep); + +#else + +typedef pthread_key_t pmix_tsd_key_t; + +static inline int +pmix_tsd_key_delete(pmix_tsd_key_t key) +{ + return pthread_key_delete(key); +} + +static inline int +pmix_tsd_setspecific(pmix_tsd_key_t key, void *value) +{ + return pthread_setspecific(key, value); +} + +static inline int +pmix_tsd_getspecific(pmix_tsd_key_t key, void **valuep) +{ + *valuep = pthread_getspecific(key); + return PMIX_SUCCESS; +} + +#endif + +/** + * Create thread-specific data key + * + * Create a thread-specific data key visible to all threads in the + * current process. The returned key is valid in all threads, + * although the values bound to the key by pmix_tsd_setspecific() are + * allocated on a per-thread basis and persist for the life of the + * calling thread. + * + * Upon key creation, the value NULL is associated with the new key in + * all active threads. When a new thread is created, the value NULL + * is associated with all defined keys in the new thread. + * + * The destructor parameter may be NULL. At thread exit, if + * destructor is non-NULL AND the thread has a non-NULL value + * associated with the key, the function is called with the current + * value as its argument. + * + * @param key[out] The key for accessing thread-specific data + * @param destructor[in] Cleanup function to call when a thread exits + * + * @retval PMIX_SUCCESS Success + * @retval EAGAIN The system lacked the necessary resource to + * create another thread specific data key + * @retval ENOMEM Insufficient memory exists to create the key + */ +PMIX_EXPORT int pmix_tsd_key_create(pmix_tsd_key_t *key, + pmix_tsd_destructor_t destructor); + + +/** + * Destruct all thread-specific data keys + * + * Destruct all thread-specific data keys and invoke the destructor + * + * This should only be invoked in the main thread. + * This is made necessary since destructors are not invoked on the + * keys of the main thread, since there is no such thing as + * pthread_join(main_thread) + * + * @retval PMIX_SUCCESS Success + */ +PMIX_EXPORT int pmix_tsd_keys_destruct(void); + +END_C_DECLS + +#endif /* PMIX_MTHREADS_TSD_H */ diff --git a/opal/mca/pmix/pmix2x/pmix/src/threads/wait_sync.c b/opal/mca/pmix/pmix2x/pmix/src/threads/wait_sync.c new file mode 100644 index 0000000000..c825f4cb6b --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/threads/wait_sync.c @@ -0,0 +1,102 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2014-2016 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2016 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +#include "wait_sync.h" + +static pmix_mutex_t wait_sync_lock = PMIX_MUTEX_STATIC_INIT; +static pmix_wait_sync_t* wait_sync_list = NULL; + +#define PMIX_WAIT_SYNC_PASS_OWNERSHIP(who) \ + do { \ + pthread_mutex_lock( &(who)->lock); \ + pthread_cond_signal( &(who)->condition ); \ + pthread_mutex_unlock( &(who)->lock); \ + } while(0) + +int pmix_sync_wait_mt(pmix_wait_sync_t *sync) +{ + /* Don't stop if the waiting synchronization is completed. We avoid the + * race condition around the release of the synchronization using the + * signaling field. + */ + if(sync->count <= 0) + return (0 == sync->status) ? PMIX_SUCCESS : PMIX_ERROR; + + /* lock so nobody can signal us during the list updating */ + pthread_mutex_lock(&sync->lock); + + /* Now that we hold the lock make sure another thread has not already + * call cond_signal. + */ + if(sync->count <= 0) { + pthread_mutex_unlock(&sync->lock); + return (0 == sync->status) ? PMIX_SUCCESS : PMIX_ERROR; + } + + /* Insert sync on the list of pending synchronization constructs */ + pmix_mutex_lock(&wait_sync_lock); + if( NULL == wait_sync_list ) { + sync->next = sync->prev = sync; + wait_sync_list = sync; + } else { + sync->prev = wait_sync_list->prev; + sync->prev->next = sync; + sync->next = wait_sync_list; + wait_sync_list->prev = sync; + } + pmix_mutex_unlock(&wait_sync_lock); + + /** + * If we are not responsible for progresing, go silent until something worth noticing happen: + * - this thread has been promoted to take care of the progress + * - our sync has been triggered. + */ + check_status: + if( sync != wait_sync_list ) { + pthread_cond_wait(&sync->condition, &sync->lock); + + /** + * At this point either the sync was completed in which case + * we should remove it from the wait list, or/and I was + * promoted as the progress manager. + */ + + if( sync->count <= 0 ) { /* Completed? */ + pthread_mutex_unlock(&sync->lock); + goto i_am_done; + } + /* either promoted, or spurious wakeup ! */ + goto check_status; + } + + pthread_mutex_unlock(&sync->lock); + while(sync->count > 0) { /* progress till completion */ + } + assert(sync == wait_sync_list); + + i_am_done: + /* My sync is now complete. Trim the list: remove self, wake next */ + pmix_mutex_lock(&wait_sync_lock); + sync->prev->next = sync->next; + sync->next->prev = sync->prev; + /* In case I am the progress manager, pass the duties on */ + if( sync == wait_sync_list ) { + wait_sync_list = (sync == sync->next) ? NULL : sync->next; + if( NULL != wait_sync_list ) + PMIX_WAIT_SYNC_PASS_OWNERSHIP(wait_sync_list); + } + pmix_mutex_unlock(&wait_sync_lock); + + return (0 == sync->status) ? PMIX_SUCCESS : PMIX_ERROR; +} diff --git a/opal/mca/pmix/pmix2x/pmix/src/threads/wait_sync.h b/opal/mca/pmix/pmix2x/pmix/src/threads/wait_sync.h new file mode 100644 index 0000000000..50717a96d7 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/src/threads/wait_sync.h @@ -0,0 +1,118 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2014-2016 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2016 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2016 Mellanox Technologies. All rights reserved. + * Copyright (c) 2016 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * Copyright (c) 2017 Intel, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#if !defined(PMIX_THREADS_WAIT_SYNC_H) +#define PMIX_THREADS_WAIT_SYNC_H + +#include "src/atomics/sys/atomic.h" +#include "src/threads/condition.h" +#include "src/util/error.h" +#include + +BEGIN_C_DECLS + +typedef struct pmix_wait_sync_t { + int32_t count; + int32_t status; + pthread_cond_t condition; + pthread_mutex_t lock; + struct pmix_wait_sync_t *next; + struct pmix_wait_sync_t *prev; + volatile bool signaling; +} pmix_wait_sync_t; + +#define REQUEST_PENDING (void*)0L +#define REQUEST_COMPLETED (void*)1L + +#define PMIX_SYNC_WAIT(sync) sync_wait_mt (sync) + +/* The loop in release handles a race condition between the signaling + * thread and the destruction of the condition variable. The signaling + * member will be set to false after the final signaling thread has + * finished operating on the sync object. This is done to avoid + * extra atomics in the signalling function and keep it as fast + * as possible. Note that the race window is small so spinning here + * is more optimal than sleeping since this macro is called in + * the critical path. */ +#define PMIX_WAIT_SYNC_RELEASE(sync) \ + while ((sync)->signaling) { \ + continue; \ + } \ + pthread_cond_destroy(&(sync)->condition); \ + pthread_mutex_destroy(&(sync)->lock); + +#define PMIX_WAIT_SYNC_RELEASE_NOWAIT(sync) \ + pthread_cond_destroy(&(sync)->condition); \ + pthread_mutex_destroy(&(sync)->lock); + + +#define PMIX_WAIT_SYNC_SIGNAL(sync) \ + pthread_mutex_lock(&(sync->lock)); \ + pthread_cond_signal(&sync->condition); \ + pthread_mutex_unlock(&(sync->lock)); \ + sync->signaling = false; + +#define PMIX_WAIT_SYNC_SIGNALLED(sync){ \ + (sync)->signaling = false; \ +} + +PMIX_EXPORT int pmix_sync_wait_mt(pmix_wait_sync_t *sync); +static inline int pmix_sync_wait_st (pmix_wait_sync_t *sync) +{ + while (sync->count > 0) { + } + + return sync->status; +} + + +#define PMIX_WAIT_SYNC_INIT(sync,c) \ + do { \ + (sync)->count = (c); \ + (sync)->next = NULL; \ + (sync)->prev = NULL; \ + (sync)->status = 0; \ + (sync)->signaling = (0 != (c)); \ + pthread_cond_init (&(sync)->condition, NULL); \ + pthread_mutex_init (&(sync)->lock, NULL); \ + } while(0) + +/** + * Update the status of the synchronization primitive. If an error is + * reported the synchronization is completed and the signal + * triggered. The status of the synchronization will be reported to + * the waiting threads. + */ +static inline void pmix_wait_sync_update(pmix_wait_sync_t *sync, int updates, int status) +{ + if( PMIX_LIKELY(PMIX_SUCCESS == status) ) { + if( 0 != (PMIX_THREAD_ADD32(&sync->count, -updates)) ) { + return; + } + } else { + /* this is an error path so just use the atomic */ + sync->status = PMIX_ERROR; + pmix_atomic_wmb (); + pmix_atomic_swap_32 (&sync->count, 0); + } + PMIX_WAIT_SYNC_SIGNAL(sync); +} + +END_C_DECLS + +#endif /* defined(PMIX_THREADS_WAIT_SYNC_H) */ diff --git a/opal/mca/pmix/pmix2x/pmix/test/Makefile.am b/opal/mca/pmix/pmix2x/pmix/test/Makefile.am index 1d1a0b8f46..ec37922965 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/test/Makefile.am @@ -34,7 +34,7 @@ AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_builddir)/src/include -I$(top_buildd noinst_SCRIPTS = pmix_client_otheruser.sh noinst_PROGRAMS = -if WANT_PMIX_BACKWARD +if WANT_PMI_BACKWARD noinst_PROGRAMS += pmi_client pmi2_client endif @@ -48,7 +48,7 @@ pmix_test_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) pmix_test_LDADD = \ $(top_builddir)/src/libpmix.la -if WANT_PMIX_BACKWARD +if WANT_PMI_BACKWARD pmi_client_SOURCES = $(headers) \ pmi_client.c pmi_client_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) diff --git a/opal/mca/pmix/pmix2x/pmix/test/simple/Makefile.am b/opal/mca/pmix/pmix2x/pmix/test/simple/Makefile.am index 8c1dfbffaf..32f93de75c 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/simple/Makefile.am +++ b/opal/mca/pmix/pmix2x/pmix/test/simple/Makefile.am @@ -11,7 +11,7 @@ # All rights reserved. # Copyright (c) 2006-2010 Cisco Systems, Inc. All rights reserved. # Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved. -# Copyright (c) 2013-2016 Intel, Inc. All rights reserved +# Copyright (c) 2013-2017 Intel, Inc. All rights reserved. # $COPYRIGHT$ # # Additional copyrights may follow @@ -21,7 +21,7 @@ AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_builddir)/src/include -I$(top_builddir)/include -I$(top_builddir)/include/pmix -noinst_PROGRAMS = simptest simpclient simppub simpdyn simpft simpdmodex test_pmix simptool +noinst_PROGRAMS = simptest simpclient simppub simpdyn simpft simpdmodex test_pmix simptool simpdie simptest_SOURCES = \ simptest.c @@ -70,3 +70,9 @@ simptool_SOURCES = \ simptool_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) simptool_LDADD = \ $(top_builddir)/src/libpmix.la + +simpdie_SOURCES = \ + simpdie.c +simpdie_LDFLAGS = $(PMIX_PKG_CONFIG_LDFLAGS) +simpdie_LDADD = \ + $(top_builddir)/src/libpmix.la diff --git a/opal/mca/pmix/pmix2x/pmix/test/simple/simpdie.c b/opal/mca/pmix/pmix2x/pmix/test/simple/simpdie.c new file mode 100644 index 0000000000..60744a68b7 --- /dev/null +++ b/opal/mca/pmix/pmix2x/pmix/test/simple/simpdie.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2004-2010 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2011 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2006-2013 Los Alamos National Security, LLC. + * All rights reserved. + * Copyright (c) 2009-2012 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2011 Oak Ridge National Labs. All rights reserved. + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. + * Copyright (c) 2015 Mellanox Technologies, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + */ + +#include +#include + +#include +#include +#include +#include + +#include "src/class/pmix_object.h" +#include "src/buffer_ops/types.h" +#include "src/util/argv.h" +#include "src/util/output.h" +#include "src/util/printf.h" + +static pmix_proc_t myproc; +static bool completed; + +static void notification_fn(size_t evhdlr_registration_id, + pmix_status_t status, + const pmix_proc_t *source, + pmix_info_t info[], size_t ninfo, + pmix_info_t results[], size_t nresults, + pmix_event_notification_cbfunc_fn_t cbfunc, + void *cbdata) +{ + size_t n; + + pmix_output(0, "Client %s:%d NOTIFIED with status %d source %s:%d and %d info", + myproc.nspace, myproc.rank, status, source->nspace, source->rank, (int)ninfo); + for (n=0; n < ninfo; n++) { + if (0 == strncmp(info[n].key, PMIX_PROCID, PMIX_MAX_KEYLEN) && + PMIX_PROC == info[n].value.type) { + pmix_output(0, "[%s:%d] added proc: %s:%d", myproc.nspace, myproc.rank, + info[n].value.data.proc->nspace, info[n].value.data.proc->rank); + } else { + pmix_output(0, "[%s:%d] key: %s", myproc.nspace, myproc.rank, info[n].key); + } + } + if (NULL != cbfunc) { + cbfunc(PMIX_SUCCESS, NULL, 0, NULL, NULL, cbdata); + } + completed = true; +} + +static void op_callbk(pmix_status_t status, + void *cbdata) +{ + pmix_output(0, "CLIENT: OP CALLBACK CALLED WITH STATUS %d", status); +} + +static void errhandler_reg_callbk (pmix_status_t status, + size_t errhandler_ref, + void *cbdata) +{ + pmix_output(0, "Client: ERRHANDLER REGISTRATION CALLBACK CALLED WITH STATUS %d, ref=%lu", + status, (unsigned long)errhandler_ref); +} + +int main(int argc, char **argv) +{ + int rc; + pmix_value_t value; + pmix_value_t *val = &value; + pmix_proc_t proc; + uint32_t nprocs; + + /* init us */ + if (PMIX_SUCCESS != (rc = PMIx_Init(&myproc, NULL, 0))) { + pmix_output(0, "Client ns %s rank %d: PMIx_Init failed: %d", myproc.nspace, myproc.rank, rc); + exit(0); + } + pmix_output(0, "Client ns %s rank %d: Running", myproc.nspace, myproc.rank); + + /* get our universe size */ + (void)strncpy(proc.nspace, myproc.nspace, PMIX_MAX_NSLEN); + proc.rank = PMIX_RANK_WILDCARD; + if (PMIX_SUCCESS != (rc = PMIx_Get(&proc, PMIX_UNIV_SIZE, NULL, 0, &val))) { + pmix_output(0, "Client ns %s rank %d: PMIx_Get universe size failed: %d", myproc.nspace, myproc.rank, rc); + goto done; + } + nprocs = val->data.uint32; + PMIX_VALUE_RELEASE(val); + pmix_output(0, "Client %s:%d universe size %d", myproc.nspace, myproc.rank, nprocs); + completed = false; + + /* register our errhandler */ + PMIx_Register_event_handler(NULL, 0, NULL, 0, + notification_fn, errhandler_reg_callbk, NULL); + + /* call fence to sync */ + PMIX_PROC_CONSTRUCT(&proc); + (void)strncpy(proc.nspace, myproc.nspace, PMIX_MAX_NSLEN); + proc.rank = PMIX_RANK_WILDCARD; + if (PMIX_SUCCESS != (rc = PMIx_Fence(&proc, 1, NULL, 0))) { + pmix_output(0, "Client ns %s rank %d: PMIx_Fence failed: %d", myproc.nspace, myproc.rank, rc); + goto done; + } + + /* rank=0 dies */ + if (4 < nprocs) { + /* have two exit */ + if (myproc.rank < 2) { + pmix_output(0, "Client ns %s rank %d: bye-bye!", myproc.nspace, myproc.rank); + exit(1); + } + } else if (0 == myproc.rank) { + pmix_output(0, "Client ns %s rank %d: bye-bye!", myproc.nspace, myproc.rank); + exit(1); + } + /* everyone simply waits */ + while (!completed) { + struct timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = 100000; + nanosleep(&ts, NULL); + } + + done: + /* finalize us */ + pmix_output(0, "Client ns %s rank %d: Finalizing", myproc.nspace, myproc.rank); + PMIx_Deregister_event_handler(1, op_callbk, NULL); + + if (PMIX_SUCCESS != (rc = PMIx_Finalize(NULL, 0))) { + fprintf(stderr, "Client ns %s rank %d:PMIx_Finalize failed: %d\n", myproc.nspace, myproc.rank, rc); + } else { + fprintf(stderr, "Client ns %s rank %d:PMIx_Finalize successfully completed\n", myproc.nspace, myproc.rank); + } + fflush(stderr); + return(0); +} diff --git a/opal/mca/pmix/pmix2x/pmix/test/simple/simptest.c b/opal/mca/pmix/pmix2x/pmix/test/simple/simptest.c index 528139e762..75969651fa 100644 --- a/opal/mca/pmix/pmix2x/pmix/test/simple/simptest.c +++ b/opal/mca/pmix/pmix2x/pmix/test/simple/simptest.c @@ -13,7 +13,7 @@ * All rights reserved. * Copyright (c) 2009-2012 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2011 Oak Ridge National Labs. All rights reserved. - * Copyright (c) 2013-2016 Intel, Inc. All rights reserved. + * Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. * Copyright (c) 2016 IBM Corporation. All rights reserved. @@ -196,6 +196,54 @@ static void opcbfunc(pmix_status_t status, void *cbdata) x->active = false; } +/* this is an event notification function that we explicitly request + * be called when the PMIX_MODEL_DECLARED notification is issued. + * We could catch it in the general event notification function and test + * the status to see if the status matched, but it often is simpler + * to declare a use-specific notification callback point. In this case, + * we are asking to know whenever a model is declared as a means + * of testing server self-notification */ +static void model_callback(size_t evhdlr_registration_id, + pmix_status_t status, + const pmix_proc_t *source, + pmix_info_t info[], size_t ninfo, + pmix_info_t results[], size_t nresults, + pmix_event_notification_cbfunc_fn_t cbfunc, + void *cbdata) +{ + size_t n; + + /* just let us know it was received */ + fprintf(stderr, "Model event handler called with status %d(%s)\n", status, PMIx_Error_string(status)); + for (n=0; n < ninfo; n++) { + if (PMIX_STRING == info[n].value.type) { + fprintf(stderr, "\t%s:\t%s\n", info[n].key, info[n].value.data.string); + } + } + + /* we must NOT tell the event handler state machine that we + * are the last step as that will prevent it from notifying + * anyone else that might be listening for declarations */ + if (NULL != cbfunc) { + cbfunc(PMIX_SUCCESS, NULL, 0, NULL, NULL, cbdata); + } + wakeup = 0; +} + +/* event handler registration is done asynchronously */ +static void model_registration_callback(pmix_status_t status, + size_t evhandler_ref, + void *cbdata) +{ + volatile int *active = (volatile int*)cbdata; + + if (PMIX_SUCCESS != status) { + fprintf(stderr, "simptest EVENT HANDLER REGISTRATION FAILED WITH STATUS %d, ref=%lu\n", + status, (unsigned long)evhandler_ref); + } + *active = status; +} + int main(int argc, char **argv) { char **client_env=NULL; @@ -208,9 +256,12 @@ int main(int argc, char **argv) myxfer_t *x; pmix_proc_t proc; wait_tracker_t *child; - pmix_info_t info[2]; + pmix_info_t *info; + size_t ninfo; bool cross_version = false; bool usock = true; + volatile int active; + pmix_status_t code; /* smoke test */ if (PMIX_SUCCESS != 0) { @@ -261,20 +312,46 @@ int main(int argc, char **argv) } /* setup the server library and tell it to support tool connections */ - PMIX_INFO_CONSTRUCT(&info[0]); - (void)strncpy(info[0].key, PMIX_SERVER_TOOL_SUPPORT, PMIX_MAX_KEYLEN); - PMIX_INFO_CONSTRUCT(&info[1]); + ninfo = 2; + PMIX_INFO_CREATE(info, ninfo); + PMIX_INFO_LOAD(&info[0], PMIX_SERVER_TOOL_SUPPORT, NULL, PMIX_BOOL); PMIX_INFO_LOAD(&info[1], PMIX_USOCK_DISABLE, &usock, PMIX_BOOL); if (PMIX_SUCCESS != (rc = PMIx_server_init(&mymodule, info, 2))) { fprintf(stderr, "Init failed with error %d\n", rc); return rc; } - PMIX_INFO_DESTRUCT(&info[0]); - PMIX_INFO_DESTRUCT(&info[1]); + PMIX_INFO_FREE(info, ninfo); - /* register the errhandler */ - PMIx_Register_event_handler(NULL, 0, NULL, 0, - errhandler, errhandler_reg_callbk, NULL); + /* register the default errhandler */ + active = -1; + ninfo = 1; + PMIX_INFO_CREATE(info, ninfo); + PMIX_INFO_LOAD(&info[0], PMIX_EVENT_HDLR_NAME, "SIMPTEST-DEFAULT", PMIX_STRING); + PMIx_Register_event_handler(NULL, 0, info, ninfo, + errhandler, errhandler_reg_callbk, (void*)&active); + while (-1 == active) { + usleep(10); + } + PMIX_INFO_FREE(info, ninfo); + if (0 != active) { + exit(active); + } + + /* register a handler specifically for when models declare */ + active = -1; + ninfo = 1; + PMIX_INFO_CREATE(info, ninfo); + PMIX_INFO_LOAD(&info[0], PMIX_EVENT_HDLR_NAME, "SIMPTEST-MODEL", PMIX_STRING); + code = PMIX_MODEL_DECLARED; + PMIx_Register_event_handler(&code, 1, info, ninfo, + model_callback, model_registration_callback, (void*)&active); + while (-1 == active) { + usleep(10); + } + PMIX_INFO_FREE(info, ninfo); + if (0 != active) { + exit(active); + } /* setup the pub data, in case it is used */ PMIX_CONSTRUCT(&pubdata, pmix_list_t); @@ -368,7 +445,23 @@ int main(int argc, char **argv) nanosleep(&ts, NULL); } - /* deregister the errhandler */ + /* try notifying ourselves */ + ninfo = 3; + PMIX_INFO_CREATE(info, ninfo); + PMIX_INFO_LOAD(&info[0], PMIX_PROGRAMMING_MODEL, "PMIX", PMIX_STRING); + PMIX_INFO_LOAD(&info[1], PMIX_MODEL_LIBRARY_NAME, "test", PMIX_STRING); + /* mark that it is not to go to any default handlers */ + PMIX_INFO_LOAD(&info[2], PMIX_EVENT_NON_DEFAULT, NULL, PMIX_BOOL); + wakeup = -1; + PMIx_Notify_event(PMIX_MODEL_DECLARED, + &pmix_globals.myid, PMIX_RANGE_PROC_LOCAL, + info, ninfo, NULL, NULL); + while (-1 == wakeup) { + usleep(10); + } + PMIX_INFO_FREE(info, ninfo); + + /* deregister the event handlers */ PMIx_Deregister_event_handler(0, NULL, NULL); /* release any pub data */ @@ -443,8 +536,11 @@ static void errhandler_reg_callbk (pmix_status_t status, size_t errhandler_ref, void *cbdata) { + volatile int *active = (volatile int*)cbdata; + pmix_output(0, "SERVER: ERRHANDLER REGISTRATION CALLBACK CALLED WITH STATUS %d, ref=%lu", status, (unsigned long)errhandler_ref); + *active = status; } static pmix_status_t connected(const pmix_proc_t *proc, void *server_object,