From ee3517427e57d4b38a6954e71fc9f62de2d2b0eb Mon Sep 17 00:00:00 2001 From: Noah Evans Date: Mon, 4 Feb 2019 20:20:37 -0700 Subject: [PATCH 1/5] Add threads framework Add a framework to support different types of threading models including user space thread packages such as Qthreads and argobot: https://github.com/pmodels/argobots https://github.com/Qthreads/qthreads The default threading model is pthreads. Alternate thread models are specificed at configure time using the --with-threads=X option. The framework is static. The theading model to use is selected at Open MPI configure/build time. mca/threads: implement Argobots threading layer config: fix thread configury - Add double quotations - Change Argobot to Argobots config: implement Argobots check If the poll time is too long, MPI hangs. This quick fix just sets it to 0, but it is not good for the Pthreads version. Need to find a good way to abstract it. Note that even 1 (= 1 millisecond) causes disastrous performance degradation. rework threads MCA framework configury It now works more like the ompi/mca/rte configury, modulo some edge items that are special for threading package linking, etc. qthreads module some argobots cleanup Signed-off-by: Noah Evans Signed-off-by: Shintaro Iwasaki Signed-off-by: Howard Pritchard --- config/opal_check_pthread_pids.m4 | 112 ------ config/opal_config_threads.m4 | 69 ---- configure.ac | 26 +- ompi/attribute/attribute.c | 2 +- ompi/communicator/comm.c | 2 +- ompi/communicator/communicator.h | 2 +- ompi/file/file.h | 2 +- ompi/info/info.h | 2 +- ompi/mca/common/monitoring/monitoring_prof.c | 2 +- ompi/mca/common/ompio/common_ompio.h | 2 +- ompi/mca/io/ompio/io_ompio.h | 2 +- ompi/mca/io/ompio/io_ompio_component.c | 2 +- ompi/mca/io/ompio/io_ompio_module.c | 2 +- ompi/mca/io/romio321/src/io_romio321.h | 2 +- .../io/romio321/src/io_romio321_component.c | 2 +- ompi/mca/osc/pt2pt/osc_pt2pt.h | 2 +- ompi/mca/osc/pt2pt/osc_pt2pt_active_target.c | 2 +- ompi/mca/osc/pt2pt/osc_pt2pt_passive_target.c | 2 +- ompi/mca/osc/pt2pt/osc_pt2pt_sync.h | 2 +- ompi/mca/osc/rdma/osc_rdma.h | 2 +- ompi/mca/osc/rdma/osc_rdma_active_target.c | 2 +- ompi/mca/osc/rdma/osc_rdma_component.c | 2 +- ompi/mca/osc/rdma/osc_rdma_sync.h | 2 +- ompi/mca/pml/base/pml_base_bsend.c | 4 +- ompi/mca/pml/ob1/pml_ob1_comm.h | 2 +- ompi/mca/pml/ob1/pml_ob1_recvfrag.c | 2 +- ompi/mpi/c/comm_get_name.c | 2 +- ompi/mpi/c/is_thread_main.c | 2 +- ompi/proc/proc.c | 2 +- ompi/request/request.h | 4 +- ompi/runtime/mpiruntime.h | 2 +- ompi/runtime/ompi_mpi_init.c | 2 +- ompi/runtime/ompi_rte.c | 5 +- ompi/runtime/ompi_rte.h | 4 +- opal/Makefile.am | 1 - opal/class/opal_fifo.h | 2 +- opal/class/opal_free_list.h | 2 +- opal/class/opal_lifo.h | 2 +- opal/class/opal_list.h | 2 +- opal/class/opal_object.h | 2 +- opal/class/opal_pointer_array.h | 2 +- opal/class/opal_ring_buffer.h | 2 +- opal/class/opal_tree.h | 2 +- opal/mca/allocator/basic/allocator_basic.h | 2 +- .../allocator/bucket/allocator_bucket_alloc.h | 2 +- opal/mca/btl/ofi/btl_ofi_rdma.h | 2 +- opal/mca/btl/tcp/btl_tcp_component.c | 2 +- opal/mca/btl/uct/btl_uct.h | 2 +- opal/mca/btl/usnic/btl_usnic_cagent.c | 2 +- opal/mca/btl/usnic/btl_usnic_cclient.c | 2 +- opal/mca/btl/vader/btl_vader_component.c | 2 +- opal/mca/common/ucx/common_ucx_wpool.h | 2 +- opal/mca/event/event.h | 2 + opal/mca/event/external/external.h | 3 - opal/mca/event/libevent2022/libevent2022.h | 7 +- .../event/libevent2022/libevent2022_module.c | 4 +- opal/mca/hwloc/base/hwloc_base_frame.c | 2 +- opal/mca/hwloc/base/hwloc_base_util.c | 2 +- opal/mca/mpool/base/mpool_base_alloc.c | 2 +- opal/mca/patcher/linux/patcher_linux.h | 2 +- opal/mca/pmix/base/base.h | 4 +- opal/mca/pmix/base/pmix_base_frame.c | 2 +- opal/mca/pmix/pmix-internal.h | 20 +- opal/mca/rcache/rcache.h | 2 +- opal/mca/threads/Makefile.am | 47 +++ opal/mca/threads/README.md | 41 +++ opal/mca/threads/argobots/Makefile.am | 36 ++ opal/mca/threads/argobots/configure.m4 | 81 +++++ opal/mca/threads/argobots/owner.txt | 7 + opal/mca/threads/argobots/threads_argobots.h | 38 ++ .../argobots/threads_argobots_component.c | 57 +++ .../argobots/threads_argobots_condition.c | 39 +++ .../threads/argobots/threads_argobots_event.c | 143 ++++++++ .../argobots/threads_argobots_module.c | 158 +++++++++ .../threads/argobots/threads_argobots_mutex.c | 174 +++++++++ .../threads/argobots/threads_argobots_mutex.h | 229 ++++++++++++ .../argobots/threads_argobots_threads.h | 40 +++ .../threads/argobots/threads_argobots_tsd.h | 54 +++ .../argobots/threads_argobots_wait_sync.c | 116 ++++++ .../argobots/threads_argobots_wait_sync.h | 107 ++++++ opal/mca/threads/base/Makefile.am | 25 ++ opal/mca/threads/base/base.h | 48 +++ opal/mca/threads/base/owner.txt | 7 + opal/mca/threads/base/threads_base.c | 50 +++ opal/{ => mca}/threads/condition.h | 60 ++-- opal/mca/threads/configure.m4 | 60 ++++ opal/{ => mca}/threads/mutex.h | 61 ++-- opal/mca/threads/pthreads/Makefile.am | 32 ++ .../mca/threads/pthreads/configure.m4 | 331 ++++++++++++++---- opal/mca/threads/pthreads/owner.txt | 7 + .../pthreads/threads_pthreads_component.c | 54 +++ .../pthreads/threads_pthreads_condition.c} | 6 +- .../pthreads/threads_pthreads_module.c} | 114 +++--- .../threads/pthreads/threads_pthreads_mutex.c | 133 +++++++ .../pthreads/threads_pthreads_mutex.h} | 51 +-- .../pthreads/threads_pthreads_threads.h | 40 +++ .../threads/pthreads/threads_pthreads_tsd.h | 53 +++ .../pthreads/threads_pthreads_wait_sync.c} | 48 +-- .../pthreads/threads_pthreads_wait_sync.h} | 74 ++-- opal/mca/threads/qthreads/Makefile.am | 30 ++ opal/mca/threads/qthreads/configure.m4 | 81 +++++ opal/mca/threads/qthreads/owner.txt | 7 + opal/mca/threads/qthreads/threads_qthreads.h | 36 ++ .../qthreads/threads_qthreads_component.c | 54 +++ .../qthreads/threads_qthreads_condition.c | 42 +++ .../qthreads/threads_qthreads_module.c | 92 +++++ .../qthreads/threads_qthreads_mutex.c} | 84 ++--- .../threads/qthreads/threads_qthreads_mutex.h | 210 +++++++++++ .../qthreads/threads_qthreads_threads.h | 40 +++ .../threads/qthreads/threads_qthreads_tsd.h | 52 +++ .../qthreads/threads_qthreads_wait_sync.h | 66 ++++ opal/mca/threads/thread.h | 55 +++ opal/{ => mca}/threads/thread_usage.h | 138 ++++---- opal/{ => mca}/threads/threads.h | 38 +- opal/{ => mca}/threads/tsd.h | 60 ++-- opal/mca/threads/wait_sync.h | 60 ++++ opal/mca/timer/linux/timer_linux_component.c | 1 + opal/runtime/opal_cr.c | 4 +- opal/runtime/opal_finalize.c | 2 +- opal/runtime/opal_init.c | 7 +- opal/runtime/opal_params.c | 4 +- opal/runtime/opal_progress.h | 2 +- opal/runtime/opal_progress_threads.c | 2 +- opal/threads/Makefile.am | 39 --- opal/util/cmd_line.c | 2 +- opal/util/cmd_line.h | 2 +- opal/util/info.h | 2 +- opal/util/info_subscriber.h | 2 +- opal/util/keyval_parse.c | 2 +- opal/util/net.c | 2 +- opal/util/output.c | 2 +- oshmem/mca/memheap/buddy/memheap_buddy.h | 2 +- .../mca/memheap/ptmalloc/memheap_ptmalloc.h | 2 +- oshmem/proc/proc.c | 2 +- oshmem/request/request.h | 2 +- oshmem/runtime/oshmem_shmem_init.c | 2 +- test/asm/Makefile.am | 14 +- test/class/opal_fifo.c | 26 +- test/class/opal_lifo.c | 17 +- test/threads/opal_condition.c | 4 +- test/threads/opal_thread.c | 2 +- 141 files changed, 3471 insertions(+), 808 deletions(-) delete mode 100644 config/opal_check_pthread_pids.m4 delete mode 100644 config/opal_config_threads.m4 create mode 100644 opal/mca/threads/Makefile.am create mode 100644 opal/mca/threads/README.md create mode 100644 opal/mca/threads/argobots/Makefile.am create mode 100644 opal/mca/threads/argobots/configure.m4 create mode 100644 opal/mca/threads/argobots/owner.txt create mode 100644 opal/mca/threads/argobots/threads_argobots.h create mode 100644 opal/mca/threads/argobots/threads_argobots_component.c create mode 100644 opal/mca/threads/argobots/threads_argobots_condition.c create mode 100644 opal/mca/threads/argobots/threads_argobots_event.c create mode 100644 opal/mca/threads/argobots/threads_argobots_module.c create mode 100644 opal/mca/threads/argobots/threads_argobots_mutex.c create mode 100644 opal/mca/threads/argobots/threads_argobots_mutex.h create mode 100644 opal/mca/threads/argobots/threads_argobots_threads.h create mode 100644 opal/mca/threads/argobots/threads_argobots_tsd.h create mode 100644 opal/mca/threads/argobots/threads_argobots_wait_sync.c create mode 100644 opal/mca/threads/argobots/threads_argobots_wait_sync.h create mode 100644 opal/mca/threads/base/Makefile.am create mode 100644 opal/mca/threads/base/base.h create mode 100644 opal/mca/threads/base/owner.txt create mode 100644 opal/mca/threads/base/threads_base.c rename opal/{ => mca}/threads/condition.h (68%) create mode 100644 opal/mca/threads/configure.m4 rename opal/{ => mca}/threads/mutex.h (77%) create mode 100644 opal/mca/threads/pthreads/Makefile.am rename config/opal_config_pthreads.m4 => opal/mca/threads/pthreads/configure.m4 (63%) create mode 100644 opal/mca/threads/pthreads/owner.txt create mode 100644 opal/mca/threads/pthreads/threads_pthreads_component.c rename opal/{threads/condition.c => mca/threads/pthreads/threads_pthreads_condition.c} (85%) rename opal/{threads/thread.c => mca/threads/pthreads/threads_pthreads_module.c} (57%) create mode 100644 opal/mca/threads/pthreads/threads_pthreads_mutex.c rename opal/{threads/mutex_unix.h => mca/threads/pthreads/threads_pthreads_mutex.h} (83%) create mode 100644 opal/mca/threads/pthreads/threads_pthreads_threads.h create mode 100644 opal/mca/threads/pthreads/threads_pthreads_tsd.h rename opal/{threads/wait_sync.c => mca/threads/pthreads/threads_pthreads_wait_sync.c} (72%) rename opal/{threads/wait_sync.h => mca/threads/pthreads/threads_pthreads_wait_sync.h} (62%) create mode 100644 opal/mca/threads/qthreads/Makefile.am create mode 100644 opal/mca/threads/qthreads/configure.m4 create mode 100644 opal/mca/threads/qthreads/owner.txt create mode 100644 opal/mca/threads/qthreads/threads_qthreads.h create mode 100644 opal/mca/threads/qthreads/threads_qthreads_component.c create mode 100644 opal/mca/threads/qthreads/threads_qthreads_condition.c create mode 100644 opal/mca/threads/qthreads/threads_qthreads_module.c rename opal/{threads/mutex.c => mca/threads/qthreads/threads_qthreads_mutex.c} (55%) create mode 100644 opal/mca/threads/qthreads/threads_qthreads_mutex.h create mode 100644 opal/mca/threads/qthreads/threads_qthreads_threads.h create mode 100644 opal/mca/threads/qthreads/threads_qthreads_tsd.h create mode 100644 opal/mca/threads/qthreads/threads_qthreads_wait_sync.h create mode 100644 opal/mca/threads/thread.h rename opal/{ => mca}/threads/thread_usage.h (77%) rename opal/{ => mca}/threads/threads.h (87%) rename opal/{ => mca}/threads/tsd.h (75%) create mode 100644 opal/mca/threads/wait_sync.h delete mode 100644 opal/threads/Makefile.am diff --git a/config/opal_check_pthread_pids.m4 b/config/opal_check_pthread_pids.m4 deleted file mode 100644 index 1cdf5b9c437..00000000000 --- a/config/opal_check_pthread_pids.m4 +++ /dev/null @@ -1,112 +0,0 @@ -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$ -dnl -dnl Additional copyrights may follow -dnl -dnl $HEADER$ -dnl - -AC_DEFUN([OPAL_CHECK_PTHREAD_PIDS],[ -# -# Arguments: none -# -# Dependencies: None -# -# Sets: -# OPAL_THREADS_HAVE_DIFFERENT_PIDS (variable) -# -# Test for Linux-like threads in the system. OPAL no longer supports -# 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)]) - -OPAL_VAR_SCOPE_PUSH([CFLAGS_save CPPFLAGS_save LDFLAGS_save LIBS_save MSG]) -CFLAGS_save="$CFLAGS" -CFLAGS="$CFLAGS $THREAD_CFLAGS" -CPPFLAGS_save="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS $THREAD_CPPFLAGS" -LDFLAGS_save="$LDFLAGS" -LDFLAGS="$LDFLAGS $THREAD_LDFLAGS" -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); -}])], -[MSG=no OPAL_THREADS_HAVE_DIFFERENT_PIDS=0], -[MSG=yes OPAL_THREADS_HAVE_DIFFERENT_PIDS=1], -[ - # If we're cross compiling, we can't do another AC_* function here because - # it we haven't displayed the result from the last one yet. So defer - # another test until below. - OPAL_THREADS_HAVE_DIFFERENT_PIDS= - MSG="cross compiling (need another test)"]) - -CFLAGS="$CFLAGS_save" -CPPFLAGS="$CPPFLAGS_save" -LDFLAGS="$LDFLAGS_save" -LIBS="$LIBS_save" - -AC_MSG_RESULT([$MSG]) - -AS_IF([test "x$OPAL_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], - [OPAL_THREADS_HAVE_DIFFERENT_PIDS=1])]) - -AS_IF([test "$OPAL_THREADS_HAVE_DIFFERENT_PIDS" = "1"], - [AC_MSG_WARN([This version of Open MPI only supports environments where]) - AC_MSG_WARN([threads have the same PID. Please use an older version of]) - AC_MSG_WARN([Open MPI if you need support on systems with different]) - AC_MSG_WARN([PIDs for threads in the same process. Open MPI 1.4.x]) - AC_MSG_WARN([supports such systems, as does at least some versions the]) - AC_MSG_WARN([Open MPI 1.5.x series.]) - AC_MSG_ERROR([Cannot continue]) - ]) - -# -# if pthreads is not available, then the system does not have an insane threads -# model -# -OPAL_VAR_SCOPE_POP])dnl diff --git a/config/opal_config_threads.m4 b/config/opal_config_threads.m4 deleted file mode 100644 index d136cccf86b..00000000000 --- a/config/opal_config_threads.m4 +++ /dev/null @@ -1,69 +0,0 @@ -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 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([OPAL_CONFIG_THREADS],[ -# -# Arguments: none -# -# Dependencies: None -# -# Modifies: -# none - see called tests -# -# configure threads -# - -# -# Check we have POSIX threads -# -OPAL_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" - -OPAL_CHECK_PTHREAD_PIDS - -])dnl - diff --git a/configure.ac b/configure.ac index 303e1559bdb..e31928d1577 100644 --- a/configure.ac +++ b/configure.ac @@ -26,6 +26,8 @@ # Copyright (c) 2018 Amazon.com, Inc. or its affiliates. # All Rights reserved. # Copyright (c) 2018 FUJITSU LIMITED. All rights reserved. +# Copyright (c) 2019 Triad National Security, LLC. All rights +# reserved. # $COPYRIGHT$ # # Additional copyrights may follow @@ -945,22 +947,6 @@ OPAL_CHECK_BROKEN_QSORT # all: type of getsockopt optlen # all: type of recvfrom optlen -# -# Check out what thread support we have -# -OPAL_CONFIG_THREADS - -CFLAGS="$CFLAGS $THREAD_CFLAGS" -CPPFLAGS="$CPPFLAGS $THREAD_CPPFLAGS" -LDFLAGS="$LDFLAGS $THREAD_LDFLAGS" -LIBS="$LIBS $THREAD_LIBS" - -OPAL_WRAPPER_FLAGS_ADD([CFLAGS], [$THREAD_CFLAGS]) -OPAL_WRAPPER_FLAGS_ADD([CXXFLAGS], [$THREAD_CXXFLAGS]) -OPAL_WRAPPER_FLAGS_ADD([FCFLAGS], [$THREAD_FCFLAGS]) -OPAL_WRAPPER_FLAGS_ADD([LDFLAGS], [$THREAD_LDFLAGS]) -# no need to update WRAPPER_EXTRA_LIBS - we'll get it from LT later - # # What is the local equivalent of "ln -s" # @@ -1113,6 +1099,14 @@ AC_MSG_RESULT([$opal_subdir_args]) OPAL_MCA +# +# Now that we know how to support threads with wrappers, update +# +OPAL_WRAPPER_FLAGS_ADD([CFLAGS], [$THREAD_CFLAGS]) +OPAL_WRAPPER_FLAGS_ADD([CXXFLAGS], [$THREAD_CXXFLAGS]) +OPAL_WRAPPER_FLAGS_ADD([FCFLAGS], [$THREAD_FCFLAGS]) +OPAL_WRAPPER_FLAGS_ADD([LDFLAGS], [$THREAD_LDFLAGS]) + m4_ifdef([project_ompi], [OMPI_REQUIRE_ENDPOINT_TAG_FINI]) # Last minute disable of OpenSHMEM if we didn't find any oshmem SPMLs diff --git a/ompi/attribute/attribute.c b/ompi/attribute/attribute.c index b3f5eda4568..c731069728d 100644 --- a/ompi/attribute/attribute.c +++ b/ompi/attribute/attribute.c @@ -232,7 +232,7 @@ #include "ompi_config.h" #include "opal/class/opal_bitmap.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/sys/atomic.h" #include "ompi/attribute/attribute.h" diff --git a/ompi/communicator/comm.c b/ompi/communicator/comm.c index 7b0ecf6230c..b56fc470fec 100644 --- a/ompi/communicator/comm.c +++ b/ompi/communicator/comm.c @@ -41,7 +41,7 @@ #include "opal/util/string_copy.h" #include "ompi/proc/proc.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/util/bit_ops.h" #include "opal/util/output.h" #include "ompi/mca/topo/topo.h" diff --git a/ompi/communicator/communicator.h b/ompi/communicator/communicator.h index 6adedd7a4a0..87a148dfd72 100644 --- a/ompi/communicator/communicator.h +++ b/ompi/communicator/communicator.h @@ -36,7 +36,7 @@ #include "opal/class/opal_hash_table.h" #include "opal/util/info_subscriber.h" #include "ompi/errhandler/errhandler.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "ompi/communicator/comm_request.h" #include "mpi.h" diff --git a/ompi/file/file.h b/ompi/file/file.h index 8e3fbb85a3d..bb50903ae5d 100644 --- a/ompi/file/file.h +++ b/ompi/file/file.h @@ -30,7 +30,7 @@ #include "mpi.h" #include "opal/class/opal_list.h" #include "ompi/errhandler/errhandler.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/util/info_subscriber.h" #include "ompi/mca/io/io.h" diff --git a/ompi/info/info.h b/ompi/info/info.h index 6e9466bc7c0..4128fb91890 100644 --- a/ompi/info/info.h +++ b/ompi/info/info.h @@ -32,7 +32,7 @@ #include "opal/util/info.h" #include "opal/class/opal_list.h" #include "opal/class/opal_pointer_array.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/mca/base/mca_base_var_enum.h" diff --git a/ompi/mca/common/monitoring/monitoring_prof.c b/ompi/mca/common/monitoring/monitoring_prof.c index a4ea139c679..1dcc0ca916c 100644 --- a/ompi/mca/common/monitoring/monitoring_prof.c +++ b/ompi/mca/common/monitoring/monitoring_prof.c @@ -58,7 +58,7 @@ writing 4x4 matrix to monitoring_avg.mat #define OMPI_COMPILING_FORTRAN_WRAPPERS 1 #endif -#include "opal/threads/thread_usage.h" +#include "opal/mca/threads/thread_usage.h" #include "ompi/include/mpi.h" #include "ompi/mpi/fortran/base/constants.h" diff --git a/ompi/mca/common/ompio/common_ompio.h b/ompi/mca/common/ompio/common_ompio.h index 13f8850be4c..0201e09177d 100644 --- a/ompi/mca/common/ompio/common_ompio.h +++ b/ompi/mca/common/ompio/common_ompio.h @@ -29,7 +29,7 @@ #include "mpi.h" #include "opal/class/opal_list.h" #include "ompi/errhandler/errhandler.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "ompi/file/file.h" #include "ompi/mca/io/io.h" #include "ompi/mca/fs/fs.h" diff --git a/ompi/mca/io/ompio/io_ompio.h b/ompi/mca/io/ompio/io_ompio.h index 218c8a4ada5..4c019240892 100644 --- a/ompi/mca/io/ompio/io_ompio.h +++ b/ompi/mca/io/ompio/io_ompio.h @@ -29,7 +29,7 @@ #include "mpi.h" #include "opal/class/opal_list.h" #include "ompi/errhandler/errhandler.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "ompi/file/file.h" #include "ompi/mca/io/io.h" #include "ompi/mca/fs/fs.h" diff --git a/ompi/mca/io/ompio/io_ompio_component.c b/ompi/mca/io/ompio/io_ompio_component.c index 0f8cfa97556..2d82f164750 100644 --- a/ompi/mca/io/ompio/io_ompio_component.c +++ b/ompi/mca/io/ompio/io_ompio_component.c @@ -28,7 +28,7 @@ #include "mpi.h" #include "opal/class/opal_list.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/mca/base/base.h" #include "ompi/mca/io/io.h" #include "ompi/mca/fs/base/base.h" diff --git a/ompi/mca/io/ompio/io_ompio_module.c b/ompi/mca/io/ompio/io_ompio_module.c index 061ac714ca2..d80c93fb6ff 100644 --- a/ompi/mca/io/ompio/io_ompio_module.c +++ b/ompi/mca/io/ompio/io_ompio_module.c @@ -20,7 +20,7 @@ #include "ompi_config.h" #include "mpi.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "ompi/mca/io/io.h" #include "io_ompio.h" diff --git a/ompi/mca/io/romio321/src/io_romio321.h b/ompi/mca/io/romio321/src/io_romio321.h index 0f948bc3b2d..63e588fd549 100644 --- a/ompi/mca/io/romio321/src/io_romio321.h +++ b/ompi/mca/io/romio321/src/io_romio321.h @@ -24,7 +24,7 @@ #define MCA_IO_ROMIO321_H #include "ompi_config.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "ompi/request/request.h" #include "ompi/file/file.h" #include "ompi/mca/io/io.h" diff --git a/ompi/mca/io/romio321/src/io_romio321_component.c b/ompi/mca/io/romio321/src/io_romio321_component.c index e3dbbcf3919..2f1b50a822f 100644 --- a/ompi/mca/io/romio321/src/io_romio321_component.c +++ b/ompi/mca/io/romio321/src/io_romio321_component.c @@ -27,7 +27,7 @@ #include "mpi.h" #include "opal/class/opal_list.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/mca/base/base.h" #include "ompi/mca/io/io.h" #include "io_romio321.h" diff --git a/ompi/mca/osc/pt2pt/osc_pt2pt.h b/ompi/mca/osc/pt2pt/osc_pt2pt.h index 85bad738462..1d1412831bd 100644 --- a/ompi/mca/osc/pt2pt/osc_pt2pt.h +++ b/ompi/mca/osc/pt2pt/osc_pt2pt.h @@ -30,7 +30,7 @@ #include "opal/class/opal_list.h" #include "opal/class/opal_free_list.h" #include "opal/class/opal_hash_table.h" -#include "opal/threads/threads.h" +#include "opal/mca/threads/threads.h" #include "opal/util/output.h" #include "ompi/win/win.h" diff --git a/ompi/mca/osc/pt2pt/osc_pt2pt_active_target.c b/ompi/mca/osc/pt2pt/osc_pt2pt_active_target.c index 59831842bc9..ab04c697ed5 100644 --- a/ompi/mca/osc/pt2pt/osc_pt2pt_active_target.c +++ b/ompi/mca/osc/pt2pt/osc_pt2pt_active_target.c @@ -33,7 +33,7 @@ #include "mpi.h" #include "opal/runtime/opal_progress.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "ompi/communicator/communicator.h" #include "ompi/mca/osc/base/base.h" diff --git a/ompi/mca/osc/pt2pt/osc_pt2pt_passive_target.c b/ompi/mca/osc/pt2pt/osc_pt2pt_passive_target.c index 59b585337c0..0cafe109c3a 100644 --- a/ompi/mca/osc/pt2pt/osc_pt2pt_passive_target.c +++ b/ompi/mca/osc/pt2pt/osc_pt2pt_passive_target.c @@ -31,7 +31,7 @@ #include "mpi.h" #include "opal/runtime/opal_progress.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "ompi/communicator/communicator.h" #include "ompi/mca/osc/base/base.h" #include "opal/include/opal_stdint.h" diff --git a/ompi/mca/osc/pt2pt/osc_pt2pt_sync.h b/ompi/mca/osc/pt2pt/osc_pt2pt_sync.h index cf5da61bf88..98d8a084d04 100644 --- a/ompi/mca/osc/pt2pt/osc_pt2pt_sync.h +++ b/ompi/mca/osc/pt2pt/osc_pt2pt_sync.h @@ -14,7 +14,7 @@ #include "ompi_config.h" #include "opal/class/opal_free_list.h" -#include "opal/threads/threads.h" +#include "opal/mca/threads/threads.h" enum ompi_osc_pt2pt_sync_type_t { /** default value */ diff --git a/ompi/mca/osc/rdma/osc_rdma.h b/ompi/mca/osc/rdma/osc_rdma.h index 6c0d7c1575d..ad2049bccb6 100644 --- a/ompi/mca/osc/rdma/osc_rdma.h +++ b/ompi/mca/osc/rdma/osc_rdma.h @@ -27,7 +27,7 @@ #include "ompi_config.h" #include "opal/class/opal_free_list.h" #include "opal/class/opal_hash_table.h" -#include "opal/threads/threads.h" +#include "opal/mca/threads/threads.h" #include "opal/util/output.h" #include "opal/mca/shmem/shmem.h" diff --git a/ompi/mca/osc/rdma/osc_rdma_active_target.c b/ompi/mca/osc/rdma/osc_rdma_active_target.c index 80c31fc00b3..f6cf6bb2820 100644 --- a/ompi/mca/osc/rdma/osc_rdma_active_target.c +++ b/ompi/mca/osc/rdma/osc_rdma_active_target.c @@ -31,7 +31,7 @@ #include "osc_rdma_active_target.h" #include "mpi.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "ompi/communicator/communicator.h" #include "ompi/mca/osc/base/base.h" diff --git a/ompi/mca/osc/rdma/osc_rdma_component.c b/ompi/mca/osc/rdma/osc_rdma_component.c index e8daf47e277..ab6406957db 100644 --- a/ompi/mca/osc/rdma/osc_rdma_component.c +++ b/ompi/mca/osc/rdma/osc_rdma_component.c @@ -42,7 +42,7 @@ #include "osc_rdma_dynamic.h" #include "osc_rdma_accumulate.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/util/arch.h" #include "opal/util/argv.h" #include "opal/util/printf.h" diff --git a/ompi/mca/osc/rdma/osc_rdma_sync.h b/ompi/mca/osc/rdma/osc_rdma_sync.h index ce0daa5db94..31bf5bc3295 100644 --- a/ompi/mca/osc/rdma/osc_rdma_sync.h +++ b/ompi/mca/osc/rdma/osc_rdma_sync.h @@ -14,7 +14,7 @@ #include "osc_rdma_types.h" #include "opal/class/opal_object.h" -#include "opal/threads/threads.h" +#include "opal/mca/threads/threads.h" /** * @brief synchronization types diff --git a/ompi/mca/pml/base/pml_base_bsend.c b/ompi/mca/pml/base/pml_base_bsend.c index 4da15522b8b..3826253e2ae 100644 --- a/ompi/mca/pml/base/pml_base_bsend.c +++ b/ompi/mca/pml/base/pml_base_bsend.c @@ -24,8 +24,8 @@ */ #include "ompi_config.h" -#include "opal/threads/mutex.h" -#include "opal/threads/condition.h" +#include "opal/mca/threads/mutex.h" +#include "opal/mca/threads/condition.h" #include "ompi/datatype/ompi_datatype.h" #include "opal/mca/allocator/base/base.h" #include "opal/mca/allocator/allocator.h" diff --git a/ompi/mca/pml/ob1/pml_ob1_comm.h b/ompi/mca/pml/ob1/pml_ob1_comm.h index 706ca07157f..25313b4d204 100644 --- a/ompi/mca/pml/ob1/pml_ob1_comm.h +++ b/ompi/mca/pml/ob1/pml_ob1_comm.h @@ -26,7 +26,7 @@ #ifndef MCA_PML_OB1_COMM_H #define MCA_PML_OB1_COMM_H -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/class/opal_list.h" #include "ompi/proc/proc.h" #include "ompi/communicator/communicator.h" diff --git a/ompi/mca/pml/ob1/pml_ob1_recvfrag.c b/ompi/mca/pml/ob1/pml_ob1_recvfrag.c index ad48fdb9d59..0457d6feb0b 100644 --- a/ompi/mca/pml/ob1/pml_ob1_recvfrag.c +++ b/ompi/mca/pml/ob1/pml_ob1_recvfrag.c @@ -33,7 +33,7 @@ #include "ompi_config.h" #include "opal/class/opal_list.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/prefetch.h" #include "ompi/constants.h" diff --git a/ompi/mpi/c/comm_get_name.c b/ompi/mpi/c/comm_get_name.c index c4904f13bf5..f7a0ce43d8a 100644 --- a/ompi/mpi/c/comm_get_name.c +++ b/ompi/mpi/c/comm_get_name.c @@ -23,7 +23,7 @@ #include -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/util/string_copy.h" #include "ompi/mpi/c/bindings.h" diff --git a/ompi/mpi/c/is_thread_main.c b/ompi/mpi/c/is_thread_main.c index 1be65a19194..3dead8d09d8 100644 --- a/ompi/mpi/c/is_thread_main.c +++ b/ompi/mpi/c/is_thread_main.c @@ -25,7 +25,7 @@ #include "ompi/communicator/communicator.h" #include "ompi/errhandler/errhandler.h" #include "ompi/runtime/mpiruntime.h" -#include "opal/threads/threads.h" +#include "opal/mca/threads/threads.h" #if OMPI_BUILD_MPI_PROFILING #if OPAL_HAVE_WEAK_SYMBOLS diff --git a/ompi/proc/proc.c b/ompi/proc/proc.c index a4907d83850..3621328222f 100644 --- a/ompi/proc/proc.c +++ b/ompi/proc/proc.c @@ -32,7 +32,7 @@ #include "ompi/constants.h" #include "opal/datatype/opal_convertor.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/dss/dss.h" #include "opal/util/arch.h" #include "opal/util/show_help.h" diff --git a/ompi/request/request.h b/ompi/request/request.h index 6460fbe4faf..4b0c28c4e6e 100644 --- a/ompi/request/request.h +++ b/ompi/request/request.h @@ -35,8 +35,8 @@ #include "mpi.h" #include "opal/class/opal_free_list.h" #include "opal/class/opal_pointer_array.h" -#include "opal/threads/condition.h" -#include "opal/threads/wait_sync.h" +#include "opal/mca/threads/condition.h" +#include "opal/mca/threads/wait_sync.h" #include "ompi/constants.h" BEGIN_C_DECLS diff --git a/ompi/runtime/mpiruntime.h b/ompi/runtime/mpiruntime.h index f311de538f5..81c9741c2e2 100644 --- a/ompi/runtime/mpiruntime.h +++ b/ompi/runtime/mpiruntime.h @@ -36,7 +36,7 @@ #include "opal/class/opal_list.h" #include "opal/class/opal_hash_table.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" BEGIN_C_DECLS diff --git a/ompi/runtime/ompi_mpi_init.c b/ompi/runtime/ompi_mpi_init.c index aa3975308aa..17d7186400d 100644 --- a/ompi/runtime/ompi_mpi_init.c +++ b/ompi/runtime/ompi_mpi_init.c @@ -46,7 +46,7 @@ #include "opal/mca/base/base.h" #include "opal/mca/hwloc/base/base.h" #include "opal/runtime/opal_progress.h" -#include "opal/threads/threads.h" +#include "opal/mca/threads/threads.h" #include "opal/util/arch.h" #include "opal/util/argv.h" #include "opal/util/output.h" diff --git a/ompi/runtime/ompi_rte.c b/ompi/runtime/ompi_rte.c index 66a2db21edb..9864c517a70 100644 --- a/ompi/runtime/ompi_rte.c +++ b/ompi/runtime/ompi_rte.c @@ -8,7 +8,7 @@ * reserved. * Copyright (c) 2014-2018 Cisco Systems, Inc. All rights reserved * Copyright (c) 2018 Amazon.com, Inc. or its affiliates. All Rights reserved. - * Copyright (c) 2018 Triad National Security, LLC. All rights + * Copyright (c) 2018-2020 Triad National Security, LLC. All rights * reserved. * Copyright (c) 2019 Research Organization for Information Science * and Technology (RIST). All rights reserved. @@ -46,8 +46,7 @@ #include "opal/util/string_copy.h" #include "opal/mca/hwloc/base/base.h" #include "opal/mca/pmix/base/base.h" -#include "opal/threads/threads.h" -#include "opal/threads/tsd.h" +#include "opal/mca/threads/tsd.h" #include "opal/class/opal_list.h" #include "opal/dss/dss.h" diff --git a/ompi/runtime/ompi_rte.h b/ompi/runtime/ompi_rte.h index de3bb91be3f..3425939f7e5 100644 --- a/ompi/runtime/ompi_rte.h +++ b/ompi/runtime/ompi_rte.h @@ -6,6 +6,8 @@ * Copyright (c) 2014-2020 Intel, Inc. All rights reserved. * Copyright (c) 2019 Research Organization for Information Science * and Technology (RIST). All rights reserved. + * Copyright (c) 2020 Triad National Security, LLC. All rights + * reserved. * * $COPYRIGHT$ * @@ -169,7 +171,7 @@ struct opal_proc_t; -#include "opal/threads/threads.h" +#include "opal/mca/threads/threads.h" #include "opal/util/proc.h" #include "opal/mca/hwloc/hwloc-internal.h" #include "opal/mca/pmix/pmix-internal.h" diff --git a/opal/Makefile.am b/opal/Makefile.am index b657794eabc..de2588716ed 100644 --- a/opal/Makefile.am +++ b/opal/Makefile.am @@ -71,7 +71,6 @@ endif include class/Makefile.am include memoryhooks/Makefile.am include runtime/Makefile.am -include threads/Makefile.am include mca/Makefile.am include tools/Makefile.am include dss/Makefile.am diff --git a/opal/class/opal_fifo.h b/opal/class/opal_fifo.h index ebb3a0e7d8e..89b90329383 100644 --- a/opal/class/opal_fifo.h +++ b/opal/class/opal_fifo.h @@ -28,7 +28,7 @@ #include "opal/class/opal_lifo.h" #include "opal/sys/atomic.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" BEGIN_C_DECLS diff --git a/opal/class/opal_free_list.h b/opal/class/opal_free_list.h index b7fd1920219..ddc383fb912 100644 --- a/opal/class/opal_free_list.h +++ b/opal/class/opal_free_list.h @@ -27,7 +27,7 @@ #include "opal_config.h" #include "opal/class/opal_lifo.h" #include "opal/prefetch.h" -#include "opal/threads/condition.h" +#include "opal/mca/threads/condition.h" #include "opal/constants.h" #include "opal/runtime/opal.h" diff --git a/opal/class/opal_lifo.h b/opal/class/opal_lifo.h index 4d07ef6ccda..99b90be10a2 100644 --- a/opal/class/opal_lifo.h +++ b/opal/class/opal_lifo.h @@ -31,7 +31,7 @@ #include "opal/class/opal_list.h" #include "opal/sys/atomic.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" BEGIN_C_DECLS diff --git a/opal/class/opal_list.h b/opal/class/opal_list.h index f9f1f00ab26..4ec07fc6e7f 100644 --- a/opal/class/opal_list.h +++ b/opal/class/opal_list.h @@ -75,7 +75,7 @@ #if OPAL_ENABLE_DEBUG /* Need atomics for debugging (reference counting) */ #include "opal/sys/atomic.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #endif BEGIN_C_DECLS diff --git a/opal/class/opal_object.h b/opal/class/opal_object.h index f7945a0b97d..ec7f992ff3e 100644 --- a/opal/class/opal_object.h +++ b/opal/class/opal_object.h @@ -123,7 +123,7 @@ #include #include -#include "opal/threads/thread_usage.h" +#include "opal/mca/threads/thread_usage.h" BEGIN_C_DECLS diff --git a/opal/class/opal_pointer_array.h b/opal/class/opal_pointer_array.h index 5900243b043..ec6a883f5e4 100644 --- a/opal/class/opal_pointer_array.h +++ b/opal/class/opal_pointer_array.h @@ -31,7 +31,7 @@ #include "opal_config.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/class/opal_object.h" #include "opal/prefetch.h" diff --git a/opal/class/opal_ring_buffer.h b/opal/class/opal_ring_buffer.h index 7a841b3bbcb..ed607709dfd 100644 --- a/opal/class/opal_ring_buffer.h +++ b/opal/class/opal_ring_buffer.h @@ -26,7 +26,7 @@ #include "opal_config.h" -#include "opal/threads/threads.h" +#include "opal/mca/threads/threads.h" #include "opal/class/opal_object.h" #include "opal/util/output.h" diff --git a/opal/class/opal_tree.h b/opal/class/opal_tree.h index e73d0a48d9c..c80c52d18af 100644 --- a/opal/class/opal_tree.h +++ b/opal/class/opal_tree.h @@ -67,7 +67,7 @@ #if OPAL_ENABLE_DEBUG /* Need atomics for debugging (reference counting) */ #include "opal/sys/atomic.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #endif BEGIN_C_DECLS diff --git a/opal/mca/allocator/basic/allocator_basic.h b/opal/mca/allocator/basic/allocator_basic.h index aa257457dbc..4766a994c8d 100644 --- a/opal/mca/allocator/basic/allocator_basic.h +++ b/opal/mca/allocator/basic/allocator_basic.h @@ -29,7 +29,7 @@ #include "opal_config.h" #include #include -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/class/opal_free_list.h" #include "opal/mca/allocator/allocator.h" diff --git a/opal/mca/allocator/bucket/allocator_bucket_alloc.h b/opal/mca/allocator/bucket/allocator_bucket_alloc.h index fe0b66e881e..103b611d7b4 100644 --- a/opal/mca/allocator/bucket/allocator_bucket_alloc.h +++ b/opal/mca/allocator/bucket/allocator_bucket_alloc.h @@ -29,7 +29,7 @@ #include "opal_config.h" #include #include -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/mca/allocator/allocator.h" BEGIN_C_DECLS diff --git a/opal/mca/btl/ofi/btl_ofi_rdma.h b/opal/mca/btl/ofi/btl_ofi_rdma.h index a9ad34c147d..b4e1965081e 100644 --- a/opal/mca/btl/ofi/btl_ofi_rdma.h +++ b/opal/mca/btl/ofi/btl_ofi_rdma.h @@ -14,7 +14,7 @@ #ifndef BTL_OFI_RDMA_H #define BTL_OFI_RDMA_H -#include "opal/threads/thread_usage.h" +#include "opal/mca/threads/thread_usage.h" #include "btl_ofi.h" #include "btl_ofi_endpoint.h" diff --git a/opal/mca/btl/tcp/btl_tcp_component.c b/opal/mca/btl/tcp/btl_tcp_component.c index e7f40e0c3c5..408173ea3a3 100644 --- a/opal/mca/btl/tcp/btl_tcp_component.c +++ b/opal/mca/btl/tcp/btl_tcp_component.c @@ -79,7 +79,7 @@ #include "opal/mca/btl/base/btl_base_error.h" #include "opal/mca/reachable/base/base.h" #include "opal/mca/pmix/pmix-internal.h" -#include "opal/threads/threads.h" +#include "opal/mca/threads/threads.h" #include "opal/constants.h" #include "opal/mca/btl/btl.h" diff --git a/opal/mca/btl/uct/btl_uct.h b/opal/mca/btl/uct/btl_uct.h index a3dee5f7d15..36b6df5d4c2 100644 --- a/opal/mca/btl/uct/btl_uct.h +++ b/opal/mca/btl/uct/btl_uct.h @@ -39,7 +39,7 @@ #include "opal/class/opal_fifo.h" #include "opal/class/opal_hash_table.h" #include "opal/mca/pmix/pmix-internal.h" -#include "opal/threads/tsd.h" +#include "opal/mca/threads/tsd.h" #include #include "btl_uct_types.h" diff --git a/opal/mca/btl/usnic/btl_usnic_cagent.c b/opal/mca/btl/usnic/btl_usnic_cagent.c index b265d37f352..ff17600a96c 100644 --- a/opal/mca/btl/usnic/btl_usnic_cagent.c +++ b/opal/mca/btl/usnic/btl_usnic_cagent.c @@ -22,7 +22,7 @@ #endif #include "opal_stdint.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/mca/event/event.h" #include "opal/util/show_help.h" #include "opal/types.h" diff --git a/opal/mca/btl/usnic/btl_usnic_cclient.c b/opal/mca/btl/usnic/btl_usnic_cclient.c index d1498d92249..cca6157dea1 100644 --- a/opal/mca/btl/usnic/btl_usnic_cclient.c +++ b/opal/mca/btl/usnic/btl_usnic_cclient.c @@ -25,7 +25,7 @@ #include #include "opal_stdint.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/mca/event/event.h" #include "opal/util/output.h" #include "opal/util/fd.h" diff --git a/opal/mca/btl/vader/btl_vader_component.c b/opal/mca/btl/vader/btl_vader_component.c index de26ecbf03c..128b802e7a3 100644 --- a/opal/mca/btl/vader/btl_vader_component.c +++ b/opal/mca/btl/vader/btl_vader_component.c @@ -33,7 +33,7 @@ #include "opal/util/output.h" #include "opal/util/show_help.h" #include "opal/util/printf.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/mca/btl/base/btl_base_error.h" #include "btl_vader.h" diff --git a/opal/mca/common/ucx/common_ucx_wpool.h b/opal/mca/common/ucx/common_ucx_wpool.h index 87ce6f8ba2f..79f2163c438 100644 --- a/opal/mca/common/ucx/common_ucx_wpool.h +++ b/opal/mca/common/ucx/common_ucx_wpool.h @@ -15,7 +15,7 @@ #include "opal/runtime/opal_progress.h" #include "opal/include/opal/constants.h" #include "opal/class/opal_list.h" -#include "opal/threads/tsd.h" +#include "opal/mca/threads/tsd.h" BEGIN_C_DECLS diff --git a/opal/mca/event/event.h b/opal/mca/event/event.h index b0958b64e09..65f8f69e054 100644 --- a/opal/mca/event/event.h +++ b/opal/mca/event/event.h @@ -48,6 +48,8 @@ BEGIN_C_DECLS #define OPAL_TIMEOUT_DEFAULT {1, 0} +OPAL_DECLSPEC void opal_event_use_threads(void); + /** * Structure for event components. */ diff --git a/opal/mca/event/external/external.h b/opal/mca/event/external/external.h index 00378f684fe..6fe67feeeab 100644 --- a/opal/mca/event/external/external.h +++ b/opal/mca/event/external/external.h @@ -71,9 +71,6 @@ OPAL_DECLSPEC int opal_event_finalize(void); #define opal_event_set_priority(x, n) event_priority_set((x), (n)) -/* thread support APIs */ -#define opal_event_use_threads() evthread_use_pthreads() - /* Basic event APIs */ #define opal_event_enable_debug_mode() event_enable_debug_mode() diff --git a/opal/mca/event/libevent2022/libevent2022.h b/opal/mca/event/libevent2022/libevent2022.h index de3443539f0..3b8834d0fb2 100644 --- a/opal/mca/event/libevent2022/libevent2022.h +++ b/opal/mca/event/libevent2022/libevent2022.h @@ -48,8 +48,8 @@ #include #include "opal/class/opal_object.h" -#include "opal/threads/mutex.h" -#include "opal/threads/threads.h" +#include "opal/mca/threads/mutex.h" +#include "opal/mca/threads/threads.h" #include "opal/util/output.h" #include "opal/constants.h" #include "opal/util/argv.h" @@ -102,9 +102,6 @@ OPAL_DECLSPEC int opal_event_finalize(void); #define opal_event_set_priority(x, n) event_priority_set((x), (n)) -/* thread support APIs */ -#define opal_event_use_threads() evthread_use_pthreads() - /* Basic event APIs */ #define opal_event_enable_debug_mode() event_enable_debug_mode() diff --git a/opal/mca/event/libevent2022/libevent2022_module.c b/opal/mca/event/libevent2022/libevent2022_module.c index b36f4d4f985..68bf898c161 100644 --- a/opal/mca/event/libevent2022/libevent2022_module.c +++ b/opal/mca/event/libevent2022/libevent2022_module.c @@ -53,8 +53,8 @@ #include #include "opal/class/opal_object.h" -#include "opal/threads/mutex.h" -#include "opal/threads/threads.h" +#include "opal/mca/threads/mutex.h" +#include "opal/mca/threads/threads.h" #include "opal/util/output.h" #include "opal/util/argv.h" #include "opal/util/fd.h" diff --git a/opal/mca/hwloc/base/hwloc_base_frame.c b/opal/mca/hwloc/base/hwloc_base_frame.c index af85a642dcd..a4a843a3698 100644 --- a/opal/mca/hwloc/base/hwloc_base_frame.c +++ b/opal/mca/hwloc/base/hwloc_base_frame.c @@ -21,7 +21,7 @@ #include "opal/util/show_help.h" #include "opal/mca/mca.h" #include "opal/mca/base/base.h" -#include "opal/threads/tsd.h" +#include "opal/mca/threads/tsd.h" #include "opal/mca/hwloc/hwloc-internal.h" #include "opal/mca/hwloc/base/base.h" diff --git a/opal/mca/hwloc/base/hwloc_base_util.c b/opal/mca/hwloc/base/hwloc_base_util.c index 988afc0e710..9a345b6ba7b 100644 --- a/opal/mca/hwloc/base/hwloc_base_util.c +++ b/opal/mca/hwloc/base/hwloc_base_util.c @@ -55,8 +55,8 @@ #include "opal/util/os_dirpath.h" #include "opal/util/show_help.h" #include "opal/util/printf.h" -#include "opal/threads/tsd.h" #include "opal/mca/pmix/pmix-internal.h" +#include "opal/mca/threads/tsd.h" #include "opal/mca/hwloc/hwloc-internal.h" #include "opal/mca/hwloc/base/base.h" diff --git a/opal/mca/mpool/base/mpool_base_alloc.c b/opal/mca/mpool/base/mpool_base_alloc.c index 3d0c3e8c425..b75d8b07ad6 100644 --- a/opal/mca/mpool/base/mpool_base_alloc.c +++ b/opal/mca/mpool/base/mpool_base_alloc.c @@ -29,7 +29,7 @@ #include "opal/mca/mpool/mpool.h" #include "base.h" #include "mpool_base_tree.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/util/info.h" #include "opal/align.h" diff --git a/opal/mca/patcher/linux/patcher_linux.h b/opal/mca/patcher/linux/patcher_linux.h index de4e85b35da..1d7b041b74f 100644 --- a/opal/mca/patcher/linux/patcher_linux.h +++ b/opal/mca/patcher/linux/patcher_linux.h @@ -18,7 +18,7 @@ #include "opal/mca/patcher/patcher.h" #include "opal/class/opal_list.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" struct mca_patcher_linux_patch_got_t { opal_list_item_t super; diff --git a/opal/mca/pmix/base/base.h b/opal/mca/pmix/base/base.h index 9dbfa1483a8..6021870799a 100644 --- a/opal/mca/pmix/base/base.h +++ b/opal/mca/pmix/base/base.h @@ -1,5 +1,7 @@ /* * Copyright (c) 2014-2019 Intel, Inc. All rights reserved. + * Copyright (c) 2020 Triad National Security, LLC. All rights + * reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -14,7 +16,7 @@ #include "opal_config.h" #include "opal/types.h" -#include "opal/threads/threads.h" +#include "opal/mca/threads/threads.h" #include "opal/mca/mca.h" #include "opal/mca/base/mca_base_framework.h" diff --git a/opal/mca/pmix/base/pmix_base_frame.c b/opal/mca/pmix/base/pmix_base_frame.c index eacb1e48c3a..0d509b5bfd6 100644 --- a/opal/mca/pmix/base/pmix_base_frame.c +++ b/opal/mca/pmix/base/pmix_base_frame.c @@ -13,7 +13,7 @@ #include "opal/constants.h" #include "opal/mca/mca.h" -#include "opal/threads/thread_usage.h" +#include "opal/mca/threads/thread_usage.h" #include "opal/util/argv.h" #include "opal/util/output.h" #include "opal/mca/base/base.h" diff --git a/opal/mca/pmix/pmix-internal.h b/opal/mca/pmix/pmix-internal.h index d8f8dd0cfb7..ac4969d8f38 100644 --- a/opal/mca/pmix/pmix-internal.h +++ b/opal/mca/pmix/pmix-internal.h @@ -5,6 +5,8 @@ * reserved. * Copyright (c) 2019 Research Organization for Information Science * and Technology (RIST). All rights reserved. + * Copyright (c) 2020 Triad National Security, LLC. All rights + * reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -24,6 +26,7 @@ #include "opal/mca/mca.h" #include "opal/mca/event/event.h" +#include "opal/mca/threads/threads.h" #include "opal/dss/dss.h" #include "opal/runtime/opal.h" #include "opal/dss/dss.h" @@ -61,21 +64,23 @@ typedef struct { } opal_info_item_t; OBJ_CLASS_DECLARATION(opal_info_item_t); +typedef opal_cond_t opal_pmix_condition_t; typedef struct { opal_mutex_t mutex; - pthread_cond_t cond; + opal_pmix_condition_t cond; volatile bool active; int status; char *msg; } opal_pmix_lock_t; -#define opal_pmix_condition_wait(a,b) pthread_cond_wait(a, &(b)->m_lock_pthread) +#define opal_pmix_condition_wait(a,b) opal_cond_wait(a, b) +#define opal_pmix_condition_broadcast(a) opal_cond_broadcast(a) #define OPAL_PMIX_CONSTRUCT_LOCK(l) \ do { \ OBJ_CONSTRUCT(&(l)->mutex, opal_mutex_t); \ - pthread_cond_init(&(l)->cond, NULL); \ + opal_cond_init(&(l)->cond); \ (l)->active = true; \ (l)->status = 0; \ (l)->msg = NULL; \ @@ -86,7 +91,7 @@ typedef struct { do { \ OPAL_ACQUIRE_OBJECT((l)); \ OBJ_DESTRUCT(&(l)->mutex); \ - pthread_cond_destroy(&(l)->cond); \ + opal_cond_destroy(&(l)->cond); \ if (NULL != (l)->msg) { \ free((l)->msg); \ } \ @@ -161,7 +166,7 @@ typedef struct { __FILE__, __LINE__); \ } \ (lck)->active = false; \ - pthread_cond_broadcast(&(lck)->cond); \ + opal_pmix_condition_broadcast(&(lck)->cond); \ opal_mutex_unlock(&(lck)->mutex); \ } while(0) #else @@ -169,18 +174,17 @@ typedef struct { do { \ assert(0 != opal_mutex_trylock(&(lck)->mutex)); \ (lck)->active = false; \ - pthread_cond_broadcast(&(lck)->cond); \ + opal_pmix_condition_broadcast(&(lck)->cond); \ opal_mutex_unlock(&(lck)->mutex); \ } while(0) #endif - #define OPAL_PMIX_WAKEUP_THREAD(lck) \ do { \ opal_mutex_lock(&(lck)->mutex); \ (lck)->active = false; \ OPAL_POST_OBJECT(lck); \ - pthread_cond_broadcast(&(lck)->cond); \ + opal_pmix_condition_broadcast(&(lck)->cond); \ opal_mutex_unlock(&(lck)->mutex); \ } while(0) diff --git a/opal/mca/rcache/rcache.h b/opal/mca/rcache/rcache.h index f95fa1a5972..ed68deca7ac 100644 --- a/opal/mca/rcache/rcache.h +++ b/opal/mca/rcache/rcache.h @@ -27,7 +27,7 @@ #define MCA_RCACHE_H #include "opal/mca/mca.h" #include "opal/mca/mpool/mpool.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" /* forward-declaration of rcache module structure */ diff --git a/opal/mca/threads/Makefile.am b/opal/mca/threads/Makefile.am new file mode 100644 index 00000000000..d79d571f66d --- /dev/null +++ b/opal/mca/threads/Makefile.am @@ -0,0 +1,47 @@ +# +# 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-2020 Cisco Systems, Inc. All rights reserved +# Copyright (c) 2019 Sandia National Laboratories. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# main library setup +noinst_LTLIBRARIES = libmca_threads.la +libmca_threads_la_SOURCES = + +# local files +headers = \ + condition.h \ + mutex.h \ + thread.h \ + threads.h \ + thread_usage.h \ + tsd.h \ + wait_sync.h +nodist_headers = +libmca_threads_la_SOURCES += $(headers) + +# Conditionally install the header files +if WANT_INSTALL_HEADERS +opaldir = $(opalincludedir)/$(subdir) +nobase_opal_HEADERS = $(headers) +nobase_nodist_opal_HEADERS = $(nodist_headers) +endif + +include base/Makefile.am + +distclean-local: + rm -f base/static-components.h diff --git a/opal/mca/threads/README.md b/opal/mca/threads/README.md new file mode 100644 index 00000000000..aaf7911d4ae --- /dev/null +++ b/opal/mca/threads/README.md @@ -0,0 +1,41 @@ +# MCA THREADING FRAMEWORK + +This MCA framework makes it possible to integrate new threading frameworks with the Open MPI runtime. + +## BACKGROUND + +There has been a lot of interest in integrating alternative threading models, in particular lightweight threading models with MPI implementations. Open MPI's modular component architecture seems like an ideal architecture for this sort of integration (in fact it was, Open MPI used to support Solaris and Windows threads). + +Recently there has been interest in integrating MPI with lightweight tasking layers, which led to work reviving and modernizing the old modular threading code but with an emphasis on integrating lightweight threading models. + +## SELECTING A THREADING MODEL + +The threading model is chosen via the configure option `--with-threads=`. This will choose a compile time threading model as well as compiling the relevant MCA. + +## IMPLEMENTATION + +The MCA for threading libraries is implemented in two places, once as a set of `.h` files in `mca/threads//threads__{threads,mutex,tsd}.h` which are defined inline to the main thread implementation and also as an MCA component that is loaded at runtime. + +For performance reasons, in particular synchronization overhead, it is not possible to implement a threading model as a traditional MCA. This means --at least in the short term-- that threading models are chosen at compile time rather than runtime options, using mechanisms similar to Open MPI's libevent integration. + +The .h files are meant to be run on the fast path containing inline synchonization functions (threads__mutex.h, thread local storage (threads__tsd.h) and the opal_thread structure (threads__thread.h). + +The rest of the threading implementation follows the normal MCA model: + +* `threads__component.c` describes the version of the module and specifies the module open behavior (the threading model initialization goes here). + +* `threads__condition.c` defines an instance of `opal_condition_t` which is used by `condition.h` to define Open MPI specific condition variables. + +* `threads__event.c` defines an interface to Open MPI's libevent hooks. It allows the threading module to use threading model specific memory allocation and synchronization structures with Open MPI's libevent integration. + +* `threads__module.c` defines the interface to opal's thread handle. It provides ways of comparing threads, getting the value of a thread via its handle and the implementation of thread local storage. + +* `threads__mutex.c` provides a slow path interface to creating and destroying mutices dynamically via mca allocation. They can also be defined statically using the `.h` fast path interface. + +* `threads__wait_sync.c` provides condition variable like waiting capability that ensures MPI progress while it waits. + +## TODO + +Libevent integration with lightweight threading models is a work in progress. The current Open MPI libevent library assumes preemption and does not yield by default. Lightweight threading libraries typically require tasks to be cooperative and to voluntarily yield after some time. + +Open MPI itself needs to be altered to use a common yielding model instead of usleep(3). diff --git a/opal/mca/threads/argobots/Makefile.am b/opal/mca/threads/argobots/Makefile.am new file mode 100644 index 00000000000..cf8a941fd9b --- /dev/null +++ b/opal/mca/threads/argobots/Makefile.am @@ -0,0 +1,36 @@ +# +# 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) 2008 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2019 Sandia National Laboratories. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +noinst_LTLIBRARIES = libmca_threads_argobots.la + +libmca_threads_argobots_la_SOURCES = \ + threads_argobots.h \ + threads_argobots_component.c \ + threads_argobots_condition.c \ + threads_argobots_event.c \ + threads_argobots_module.c \ + threads_argobots_mutex.c \ + threads_argobots_mutex.h \ + threads_argobots_threads.h \ + threads_argobots_tsd.h \ + threads_argobots_wait_sync.c \ + threads_argobots_wait_sync.h + +AM_LDFLAGS = -labt diff --git a/opal/mca/threads/argobots/configure.m4 b/opal/mca/threads/argobots/configure.m4 new file mode 100644 index 00000000000..1702bc307e0 --- /dev/null +++ b/opal/mca/threads/argobots/configure.m4 @@ -0,0 +1,81 @@ +# -*- shell-script -*- +# +# 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 Research Organization for Information Science +# and Technology (RIST). All rights reserved. +# Copyright (c) 2019 Sandia National Laboratories. All rights reserved. +# Copyright (c) 2019 Triad National Security, LLC. All rights +# Reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +AC_DEFUN([OPAL_CONFIG_ARGOBOTS_THREADS],[ + AC_CHECK_HEADERS([abt.h], + [AC_CHECK_LIB([abt],[ABT_init], + [threads_argobots_happy="yes"], + [threads_argobots_happy="no"])], + [threads_argobots_happy="no"]) + + AS_IF([test "$threads_argobots_happy" = "yes"], + [$1], + [$2]) +])dnl + + +AC_DEFUN([MCA_opal_threads_argobots_PRIORITY], [30]) + +AC_DEFUN([MCA_opal_threads_argobots_COMPILE_MODE], [ + AC_MSG_CHECKING([for MCA component $2:$3 compile mode]) + $4="static" + AC_MSG_RESULT([$$4]) +]) + +# If component was selected, $1 will be 1 and we should set the base header +AC_DEFUN([MCA_opal_threads_argobots_POST_CONFIG],[ + AS_IF([test "$1" = "1"], + [opal_thread_type_found="argobots" + AC_DEFINE_UNQUOTED([MCA_threads_base_include_HEADER], + ["opal/mca/threads/argobots/threads_argobots_threads.h"], + [Header to include for threads implementation]) + AC_DEFINE_UNQUOTED([MCA_threads_mutex_base_include_HEADER], + ["opal/mca/threads/argobots/threads_argobots_mutex.h"], + [Header to include for mutex implementation]) + AC_DEFINE_UNQUOTED([MCA_threads_tsd_base_include_HEADER], + ["opal/mca/threads/argobots/threads_argobots_tsd.h"], + [Header to include for tsd implementation]) + AC_DEFINE_UNQUOTED([MCA_threads_wait_sync_base_include_HEADER], + ["opal/mca/threads/argobots/threads_argobots_wait_sync.h"], + [Header to include for wait_sync implementation]) + ]) + +])dnl + +# MCA_threads_argobots_CONFIG(action-if-can-compile, +# [action-if-cant-compile]) +# ------------------------------------------------ +AC_DEFUN([MCA_opal_threads_argobots_CONFIG],[ + AC_CONFIG_FILES([opal/mca/threads/argobots/Makefile]) + + AS_IF([test "$with_threads" = "argobots"], + [OPAL_CONFIG_ARGOBOTS_THREADS([argobots_threads_works=1], [argobots_threads_works=0])], + [argobots_threads_works=0]) + + AS_IF([test "$argobots_threads_works" = "1"], + [$1 + opal_thread_type_found="argobots"], + [$2]) +]) diff --git a/opal/mca/threads/argobots/owner.txt b/opal/mca/threads/argobots/owner.txt new file mode 100644 index 00000000000..1cd89be1e87 --- /dev/null +++ b/opal/mca/threads/argobots/owner.txt @@ -0,0 +1,7 @@ +# +# owner/status file +# owner: institution that is responsible for this package +# status: e.g. active, maintenance, unmaintained +# +owner: SNL +status: active diff --git a/opal/mca/threads/argobots/threads_argobots.h b/opal/mca/threads/argobots/threads_argobots.h new file mode 100644 index 00000000000..83673860c84 --- /dev/null +++ b/opal/mca/threads/argobots/threads_argobots.h @@ -0,0 +1,38 @@ +/* -*- 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) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef OPAL_MCA_THREADS_ARGOBOTS_THREADS_ARGOBOTS_H +#define OPAL_MCA_THREADS_ARGOBOTS_THREADS_ARGOBOTS_H + +#include + +static inline void opal_threads_argobots_ensure_init(void) +{ + if (ABT_SUCCESS != ABT_initialized()) { + ABT_init(0, 0); + } +} + +#endif /* OPAL_MCA_THREADS_ARGOBOTS_THREADS_ARGOBOTS_H */ diff --git a/opal/mca/threads/argobots/threads_argobots_component.c b/opal/mca/threads/argobots/threads_argobots_component.c new file mode 100644 index 00000000000..6d3fd0a519c --- /dev/null +++ b/opal/mca/threads/argobots/threads_argobots_component.c @@ -0,0 +1,57 @@ +/* -*- 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 + * 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) 2007-2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "opal_config.h" + +#include "opal/mca/threads/argobots/threads_argobots.h" +#include "opal/mca/threads/thread.h" +#include "opal/mca/threads/threads.h" +#include "opal/constants.h" +#include + +static int opal_threads_argobots_open(void); + +const opal_threads_base_component_1_0_0_t mca_threads_argobots_component = { + /* First, the mca_component_t struct containing meta information + * about the component itself */ + .threadsc_version = { + OPAL_THREADS_BASE_VERSION_1_0_0, + + /* Component name and version */ + .mca_component_name = "argobots", + MCA_BASE_MAKE_VERSION(component, OPAL_MAJOR_VERSION, OPAL_MINOR_VERSION, + OPAL_RELEASE_VERSION), + + .mca_open_component = opal_threads_argobots_open, + }, + .threadsc_data = { + /* The component is checkpoint ready */ + MCA_BASE_METADATA_PARAM_CHECKPOINT + }, +}; + +int opal_threads_argobots_open(void) +{ + opal_threads_argobots_ensure_init(); + return OPAL_SUCCESS; +} diff --git a/opal/mca/threads/argobots/threads_argobots_condition.c b/opal/mca/threads/argobots/threads_argobots_condition.c new file mode 100644 index 00000000000..56b11cf9526 --- /dev/null +++ b/opal/mca/threads/argobots/threads_argobots_condition.c @@ -0,0 +1,39 @@ +/* -*- 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) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "opal_config.h" + +#include "opal/mca/threads/condition.h" + +static void opal_condition_construct(opal_condition_t *c) +{ + c->c_waiting = 0; + c->c_signaled = 0; +} + +static void opal_condition_destruct(opal_condition_t *c) +{ +} + +OBJ_CLASS_INSTANCE(opal_condition_t, + opal_object_t, + opal_condition_construct, + opal_condition_destruct); diff --git a/opal/mca/threads/argobots/threads_argobots_event.c b/opal/mca/threads/argobots/threads_argobots_event.c new file mode 100644 index 00000000000..c4c14e1aef2 --- /dev/null +++ b/opal/mca/threads/argobots/threads_argobots_event.c @@ -0,0 +1,143 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "opal/mca/threads/threads.h" +#include "opal/mca/threads/argobots/threads_argobots.h" +#include "opal/mca/event/libevent2022/libevent/include/event2/thread.h" +#include "opal/mca/event/libevent2022/libevent/include/event2/event-config.h" +#include "opal/mca/event/libevent2022/libevent/include/event2/util.h" + +#include + +static void *evthread_argobots_lock_alloc(unsigned locktype) +{ + ABT_mutex lock; + if (locktype & EVTHREAD_LOCKTYPE_RECURSIVE) { + ABT_mutex_attr abt_mutex_attr; + ABT_mutex_attr_create(&abt_mutex_attr); + ABT_mutex_attr_set_recursive(abt_mutex_attr, ABT_TRUE); + ABT_mutex_create_with_attr(abt_mutex_attr, &lock); + ABT_mutex_attr_free(&abt_mutex_attr); + } else { + ABT_mutex_create(&lock); + } + return lock; +} + +static void evthread_argobots_lock_free(void *_lock, unsigned locktype) +{ + ABT_mutex lock = _lock; + ABT_mutex_free(&lock); +} + +static int evthread_argobots_lock(unsigned mode, void *_lock) +{ + int ret; + ABT_mutex lock = _lock; + if (mode & EVTHREAD_TRY) { + ret = ABT_mutex_trylock(lock); + } else { + ret = ABT_mutex_lock(lock); + } + return ABT_SUCCESS == ret ? 0 : -1; +} + +static int evthread_argobots_unlock(unsigned mode, void *_lock) +{ + ABT_mutex lock = _lock; + int ret = ABT_mutex_unlock(lock); + /* This yield is necessary to avoid taking a lock consecutively. */ + ABT_thread_yield(); + return ABT_SUCCESS == ret ? 0 : -1; +} + +static unsigned long evthread_argobots_get_id(void) +{ + ABT_thread thr; + ABT_thread_self(&thr); + return (unsigned long)((intptr_t)thr); +} + +static void *evthread_argobots_cond_alloc(unsigned condflags) +{ + ABT_cond cond; + ABT_cond_create(&cond); + return cond; +} + +static void evthread_argobots_cond_free(void *_cond) +{ + ABT_cond cond = _cond; + ABT_cond_free(&cond); +} + +static int evthread_argobots_cond_signal(void *_cond, int broadcast) +{ + ABT_cond cond = _cond; + int ret; + if (broadcast) { + ret = ABT_cond_broadcast(cond); + } else { + ret = ABT_cond_signal(cond); + } + return ABT_SUCCESS == ret ? 0 : -1; +} + +static int evthread_argobots_cond_wait(void *_cond, void *_lock, + const struct timeval *tv) +{ + int ret; + ABT_cond cond = _cond; + ABT_mutex lock = _lock; + + if (tv) { + struct timeval now, abstime; + struct timespec ts; + evutil_gettimeofday(&now, NULL); + evutil_timeradd(&now, tv, &abstime); + ts.tv_sec = abstime.tv_sec; + ts.tv_nsec = abstime.tv_usec * 1000; + ret = ABT_cond_timedwait(cond, lock, &ts); + if (ABT_ERR_COND_TIMEDOUT == ret) { + return 1; + } else if (ABT_SUCCESS != ret) { + return -1; + } else { + return 0; + } + } else { + ret = ABT_cond_wait(cond, lock); + return ABT_SUCCESS == ret ? 0 : -1; + } +} + +void opal_event_use_threads(void) +{ + struct evthread_lock_callbacks cbs = { + EVTHREAD_LOCK_API_VERSION, + EVTHREAD_LOCKTYPE_RECURSIVE, + evthread_argobots_lock_alloc, + evthread_argobots_lock_free, + evthread_argobots_lock, + evthread_argobots_unlock + }; + struct evthread_condition_callbacks cond_cbs = { + EVTHREAD_CONDITION_API_VERSION, + evthread_argobots_cond_alloc, + evthread_argobots_cond_free, + evthread_argobots_cond_signal, + evthread_argobots_cond_wait + }; + opal_threads_argobots_ensure_init(); + evthread_set_lock_callbacks(&cbs); + evthread_set_condition_callbacks(&cond_cbs); + evthread_set_id_callback(evthread_argobots_get_id); +} diff --git a/opal/mca/threads/argobots/threads_argobots_module.c b/opal/mca/threads/argobots/threads_argobots_module.c new file mode 100644 index 00000000000..16ab9e1c94f --- /dev/null +++ b/opal/mca/threads/argobots/threads_argobots_module.c @@ -0,0 +1,158 @@ +/* -*- 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) 2019 Sandia National Laboratories. All rights reserved. + * + * Copyright (c) 2020 Cisco Systems, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "opal_config.h" + +#include + +#include "opal/mca/threads/argobots/threads_argobots.h" +#include "opal/constants.h" +#include "opal/util/sys_limits.h" +#include "opal/util/output.h" +#include "opal/prefetch.h" +#include "opal/mca/threads/threads.h" +#include "opal/mca/threads/tsd.h" + +#include + +struct opal_tsd_key_value { + opal_tsd_key_t key; + opal_tsd_destructor_t destructor; +}; + +static ABT_thread opal_main_thread; +struct opal_tsd_key_value *opal_tsd_key_values = NULL; +static int opal_tsd_key_values_count = 0; + +/* + * Constructor + */ +static void opal_thread_construct(opal_thread_t *t) +{ + t->t_run = 0; + t->t_handle = ABT_THREAD_NULL; +} + +OBJ_CLASS_INSTANCE(opal_thread_t, + opal_object_t, + opal_thread_construct, NULL); + +static inline ABT_thread opal_thread_get_argobots_self(void) +{ + ABT_thread self; + ABT_thread_self(&self); + return self; +} + +static void opal_thread_argobots_wrapper(void *arg) +{ + opal_thread_t *t = (opal_thread_t *)arg; + t->t_ret = ((void *(*)(void *))t->t_run)(t); +} + +opal_thread_t *opal_thread_get_self(void) +{ + opal_threads_argobots_ensure_init(); + opal_thread_t *t = OBJ_NEW(opal_thread_t); + t->t_handle = opal_thread_get_argobots_self(); + return t; +} + +bool opal_thread_self_compare(opal_thread_t *t) +{ + opal_threads_argobots_ensure_init(); + return opal_thread_get_argobots_self() == t->t_handle; +} + +int opal_thread_join(opal_thread_t *t, void **thr_return) +{ + int rc = ABT_thread_free(&t->t_handle); + if (thr_return) { + *thr_return = t->t_ret; + } + t->t_handle = ABT_THREAD_NULL; + return (ABT_SUCCESS == rc) ? OPAL_SUCCESS : OPAL_ERROR; +} + +void opal_thread_set_main() +{ + opal_threads_argobots_ensure_init(); + opal_main_thread = opal_thread_get_argobots_self(); +} + +int opal_thread_start(opal_thread_t *t) +{ + opal_threads_argobots_ensure_init(); + int rc; + if (OPAL_ENABLE_DEBUG) { + if (NULL == t->t_run || ABT_THREAD_NULL != t->t_handle) { + return OPAL_ERR_BAD_PARAM; + } + } + + ABT_xstream self_xstream; + ABT_xstream_self(&self_xstream); + rc = ABT_thread_create_on_xstream(self_xstream, + opal_thread_argobots_wrapper, t, + ABT_THREAD_ATTR_NULL, &t->t_handle); + + return (ABT_SUCCESS == rc) ? OPAL_SUCCESS : OPAL_ERROR; +} + +OBJ_CLASS_DECLARATION(opal_thread_t); + +int opal_tsd_key_create(opal_tsd_key_t *key, opal_tsd_destructor_t destructor) +{ + opal_threads_argobots_ensure_init(); + int rc; + rc = ABT_key_create(destructor, key); + if ((ABT_SUCCESS == rc) && + (opal_thread_get_argobots_self() == opal_main_thread)) { + opal_tsd_key_values = (struct opal_tsd_key_value *) + realloc(opal_tsd_key_values, (opal_tsd_key_values_count + 1) * + sizeof(struct opal_tsd_key_value)); + opal_tsd_key_values[opal_tsd_key_values_count].key = *key; + opal_tsd_key_values[opal_tsd_key_values_count].destructor = destructor; + opal_tsd_key_values_count++; + } + return (ABT_SUCCESS == rc) ? OPAL_SUCCESS : OPAL_ERROR; +} + +int opal_tsd_keys_destruct(void) +{ + int i; + void *ptr; + for (i = 0; i < opal_tsd_key_values_count; i++) { + if (OPAL_SUCCESS == + opal_tsd_getspecific(opal_tsd_key_values[i].key, &ptr)) { + if (NULL != opal_tsd_key_values[i].destructor) { + opal_tsd_key_values[i].destructor(ptr); + opal_tsd_setspecific(opal_tsd_key_values[i].key, NULL); + } + } + } + if (0 < opal_tsd_key_values_count) { + free(opal_tsd_key_values); + opal_tsd_key_values_count = 0; + } + return OPAL_SUCCESS; +} diff --git a/opal/mca/threads/argobots/threads_argobots_mutex.c b/opal/mca/threads/argobots/threads_argobots_mutex.c new file mode 100644 index 00000000000..7c8ffda43a7 --- /dev/null +++ b/opal/mca/threads/argobots/threads_argobots_mutex.c @@ -0,0 +1,174 @@ +/* -*- 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) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "opal/mca/threads/argobots/threads_argobots.h" +#include "opal_config.h" + +#include + +#include "opal/mca/threads/mutex.h" +#include "opal/mca/threads/argobots/threads_argobots_mutex.h" +#include "opal/constants.h" + +/* + * Wait and see if some upper layer wants to use threads, if support + * exists. + */ +bool opal_uses_threads = false; + +static void mca_threads_argobots_mutex_constructor(opal_mutex_t *p_mutex) +{ + opal_threads_argobots_ensure_init(); + p_mutex->m_lock_argobots = OPAL_ABT_MUTEX_NULL; + p_mutex->m_recursive = 0; +#if OPAL_ENABLE_DEBUG + p_mutex->m_lock_debug = 0; + p_mutex->m_lock_file = NULL; + p_mutex->m_lock_line = 0; +#endif + opal_atomic_lock_init(&p_mutex->m_lock_atomic, 0); +} + +static void mca_threads_argobots_mutex_destructor(opal_mutex_t *p_mutex) +{ + if (OPAL_ABT_MUTEX_NULL != p_mutex->m_lock_argobots) { + ABT_mutex_free(&p_mutex->m_lock_argobots); + } +} + +static void mca_threads_argobots_recursive_mutex_constructor + (opal_recursive_mutex_t *p_mutex) +{ + opal_threads_argobots_ensure_init(); + p_mutex->m_lock_argobots = OPAL_ABT_MUTEX_NULL; + p_mutex->m_recursive = 1; +#if OPAL_ENABLE_DEBUG + p_mutex->m_lock_debug = 0; + p_mutex->m_lock_file = NULL; + p_mutex->m_lock_line = 0; +#endif + opal_atomic_lock_init(&p_mutex->m_lock_atomic, 0); +} + +static void mca_threads_argobots_recursive_mutex_destructor + (opal_recursive_mutex_t *p_mutex) +{ + if (OPAL_ABT_MUTEX_NULL != p_mutex->m_lock_argobots) { + ABT_mutex_free(&p_mutex->m_lock_argobots); + } +} + +OBJ_CLASS_INSTANCE(opal_mutex_t, + opal_object_t, + mca_threads_argobots_mutex_constructor, + mca_threads_argobots_mutex_destructor); +OBJ_CLASS_INSTANCE(opal_recursive_mutex_t, + opal_object_t, + mca_threads_argobots_recursive_mutex_constructor, + mca_threads_argobots_recursive_mutex_destructor); + +void opal_mutex_create(struct opal_mutex_t *m) +{ + opal_threads_argobots_ensure_init(); + while (OPAL_ABT_MUTEX_NULL == m->m_lock_argobots) { + ABT_mutex abt_mutex; + if (m->m_recursive) { + ABT_mutex_attr abt_mutex_attr; + ABT_mutex_attr_create(&abt_mutex_attr); + ABT_mutex_attr_set_recursive(abt_mutex_attr, ABT_TRUE); + ABT_mutex_create_with_attr(abt_mutex_attr, &abt_mutex); + ABT_mutex_attr_free(&abt_mutex_attr); + } else { + ABT_mutex_create(&abt_mutex); + } + void *null_ptr = OPAL_ABT_MUTEX_NULL; + if (opal_atomic_compare_exchange_strong_ptr( + (intptr_t *)&m->m_lock_argobots, (intptr_t *)&null_ptr, + (intptr_t)abt_mutex)) { + /* mutex is successfully created and substituted. */ + return; + } + ABT_mutex_free(&abt_mutex); + } +} + +static void opal_cond_create(opal_cond_t *cond) +{ + opal_threads_argobots_ensure_init(); + while (OPAL_ABT_COND_NULL == *cond) { + ABT_cond new_cond; + ABT_cond_create(&new_cond); + void *null_ptr = OPAL_ABT_COND_NULL; + if (opal_atomic_compare_exchange_strong_ptr((intptr_t *)cond, + (intptr_t *)&null_ptr, + (intptr_t)new_cond)) { + /* cond is successfully created and substituted. */ + return; + } + ABT_cond_free(&new_cond); + } +} + +int opal_cond_init(opal_cond_t *cond) +{ + *cond = OPAL_ABT_COND_NULL; + return OPAL_SUCCESS; +} + +int opal_cond_wait(opal_cond_t *cond, opal_mutex_t *lock) +{ + if (OPAL_ABT_COND_NULL == *cond) { + opal_cond_create(cond); + } + int ret = ABT_cond_wait(*cond, lock->m_lock_argobots); + return ABT_SUCCESS == ret ? OPAL_SUCCESS : OPAL_ERROR; +} + +int opal_cond_broadcast(opal_cond_t *cond) +{ + if (OPAL_ABT_COND_NULL == *cond) { + opal_cond_create(cond); + } + int ret = ABT_cond_broadcast(*cond); + return ABT_SUCCESS == ret ? OPAL_SUCCESS : OPAL_ERROR; +} + +int opal_cond_signal(opal_cond_t *cond) +{ + if (OPAL_ABT_COND_NULL == *cond) { + opal_cond_create(cond); + } + int ret = ABT_cond_signal(*cond); + return ABT_SUCCESS == ret ? OPAL_SUCCESS : OPAL_ERROR; +} + +int opal_cond_destroy(opal_cond_t *cond) +{ + int ret = ABT_SUCCESS; + if (OPAL_ABT_COND_NULL != *cond) { + ret = ABT_cond_free(cond); + } + return ABT_SUCCESS == ret ? OPAL_SUCCESS : OPAL_ERROR; +} diff --git a/opal/mca/threads/argobots/threads_argobots_mutex.h b/opal/mca/threads/argobots/threads_argobots_mutex.h new file mode 100644 index 00000000000..8fb4d1f4138 --- /dev/null +++ b/opal/mca/threads/argobots/threads_argobots_mutex.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-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-2018 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) 2019 Sandia National Laboratories. All rights reserved. + * Copyright (c) 2020 Triad National Security, LLC. All rights + * reserved. + * + * Copyright (c) 2020 Cisco Systems, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef OPAL_MCA_THREADS_ARGOBOTS_THREADS_ARGOBOTS_MUTEX_H +#define OPAL_MCA_THREADS_ARGOBOTS_THREADS_ARGOBOTS_MUTEX_H + +#include "opal_config.h" + +#include +#include + +#include "opal/mca/threads/argobots/threads_argobots.h" + +#include "opal/class/opal_object.h" +#include "opal/sys/atomic.h" +#include "opal/util/output.h" + +#include + +BEGIN_C_DECLS + +/* Don't use ABT_MUTEX_NULL, since it might be not NULL. */ +#define OPAL_ABT_MUTEX_NULL 0 + +struct opal_mutex_t { + opal_object_t super; + + ABT_mutex m_lock_argobots; + int m_recursive; + +#if OPAL_ENABLE_DEBUG + int m_lock_debug; + const char *m_lock_file; + int m_lock_line; +#endif + + opal_atomic_lock_t m_lock_atomic; +}; + +OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_mutex_t); +OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_recursive_mutex_t); + +#if OPAL_ENABLE_DEBUG +#define OPAL_MUTEX_STATIC_INIT \ + { \ + .super = OPAL_OBJ_STATIC_INIT(opal_mutex_t), \ + .m_lock_argobots = OPAL_ABT_MUTEX_NULL, \ + .m_recursive = 0, \ + .m_lock_debug = 0, \ + .m_lock_file = NULL, \ + .m_lock_line = 0, \ + .m_lock_atomic = OPAL_ATOMIC_LOCK_INIT, \ + } +#else +#define OPAL_MUTEX_STATIC_INIT \ + { \ + .super = OPAL_OBJ_STATIC_INIT(opal_mutex_t), \ + .m_lock_argobots = OPAL_ABT_MUTEX_NULL, \ + .m_recursive = 0, \ + .m_lock_atomic = OPAL_ATOMIC_LOCK_INIT, \ + } +#endif + +#if OPAL_ENABLE_DEBUG +#define OPAL_RECURSIVE_MUTEX_STATIC_INIT \ + { \ + .super = OPAL_OBJ_STATIC_INIT(opal_mutex_t), \ + .m_lock_argobots = OPAL_ABT_MUTEX_NULL, \ + .m_recursive = 1, \ + .m_lock_debug = 0, \ + .m_lock_file = NULL, \ + .m_lock_line = 0, \ + .m_lock_atomic = OPAL_ATOMIC_LOCK_INIT, \ + } +#else +#define OPAL_RECURSIVE_MUTEX_STATIC_INIT \ + { \ + .super = OPAL_OBJ_STATIC_INIT(opal_mutex_t), \ + .m_lock_argobots = OPAL_ABT_MUTEX_NULL, \ + .m_recursive = 1, \ + .m_lock_atomic = OPAL_ATOMIC_LOCK_INIT, \ + } +#endif + +/************************************************************************ + * + * mutex operations (non-atomic versions) + * + ************************************************************************/ + +void opal_mutex_create(struct opal_mutex_t *m); + +static inline int opal_mutex_trylock(opal_mutex_t *m) +{ + if (OPAL_ABT_MUTEX_NULL == m->m_lock_argobots) { + opal_mutex_create(m); + } + int ret = ABT_mutex_trylock(m->m_lock_argobots); + if (ABT_ERR_MUTEX_LOCKED == ret) { + return 1; + } else if (ABT_SUCCESS != ret) { +#if OPAL_ENABLE_DEBUG + opal_output(0, "opal_mutex_trylock()"); +#endif + return 1; + } + return 0; +} + +static inline void opal_mutex_lock(opal_mutex_t *m) +{ + if (OPAL_ABT_MUTEX_NULL == m->m_lock_argobots) { + opal_mutex_create(m); + } +#if OPAL_ENABLE_DEBUG + int ret = ABT_mutex_lock(m->m_lock_argobots); + if (ABT_SUCCESS != ret) { + opal_output(0, "opal_mutex_lock()"); + } +#else + ABT_mutex_lock(m->m_lock_argobots); +#endif +} + +static inline void opal_mutex_unlock(opal_mutex_t *m) +{ + if (OPAL_ABT_MUTEX_NULL == m->m_lock_argobots) { + opal_mutex_create(m); + } +#if OPAL_ENABLE_DEBUG + int ret = ABT_mutex_unlock(m->m_lock_argobots); + if (ABT_SUCCESS != ret) { + opal_output(0, "opal_mutex_unlock()"); + } +#else + ABT_mutex_unlock(m->m_lock_argobots); +#endif + /* For fairness of locking. */ + ABT_thread_yield(); +} + +/************************************************************************ + * + * mutex operations (atomic versions) + * + ************************************************************************/ + +#if OPAL_HAVE_ATOMIC_SPINLOCKS + +/************************************************************************ + * Spin Locks + ************************************************************************/ + +static inline int opal_mutex_atomic_trylock(opal_mutex_t *m) +{ + return opal_atomic_trylock(&m->m_lock_atomic); +} + +static inline void opal_mutex_atomic_lock(opal_mutex_t *m) +{ + opal_atomic_lock(&m->m_lock_atomic); +} + +static inline void opal_mutex_atomic_unlock(opal_mutex_t *m) +{ + opal_atomic_unlock(&m->m_lock_atomic); +} + +#else + +/************************************************************************ + * Standard locking + ************************************************************************/ + +static inline int opal_mutex_atomic_trylock(opal_mutex_t *m) +{ + return opal_mutex_trylock(m); +} + +static inline void opal_mutex_atomic_lock(opal_mutex_t *m) +{ + opal_mutex_lock(m); +} + +static inline void opal_mutex_atomic_unlock(opal_mutex_t *m) +{ + opal_mutex_unlock(m); +} + +#endif + +#define OPAL_ABT_COND_NULL NULL +typedef ABT_cond opal_cond_t; +#define OPAL_CONDITION_STATIC_INIT OPAL_ABT_COND_NULL + +int opal_cond_init(opal_cond_t *cond); +int opal_cond_wait(opal_cond_t *cond, opal_mutex_t *lock); +int opal_cond_broadcast(opal_cond_t *cond); +int opal_cond_signal(opal_cond_t *cond); +int opal_cond_destroy(opal_cond_t *cond); + +END_C_DECLS + +#endif /* OPAL_MCA_THREADS_ARGOBOTS_THREADS_ARGOBOTS_MUTEX_H */ diff --git a/opal/mca/threads/argobots/threads_argobots_threads.h b/opal/mca/threads/argobots/threads_argobots_threads.h new file mode 100644 index 00000000000..5d85369fa98 --- /dev/null +++ b/opal/mca/threads/argobots/threads_argobots_threads.h @@ -0,0 +1,40 @@ +/* -*- 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) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef OPAL_MCA_THREADS_ARGOBOTS_THREADS_ARGOBOTS_THREADS_H +#define OPAL_MCA_THREADS_ARGOBOTS_THREADS_ARGOBOTS_THREADS_H + +#include +#include + +struct opal_thread_t { + opal_object_t super; + opal_thread_fn_t t_run; + void *t_arg; + ABT_thread t_handle; + void *t_ret; +}; + +#endif /* OPAL_MCA_THREADS_ARGOBOTS_THREADS_ARGOBOTS_THREADS_H */ diff --git a/opal/mca/threads/argobots/threads_argobots_tsd.h b/opal/mca/threads/argobots/threads_argobots_tsd.h new file mode 100644 index 00000000000..cbeaa914fba --- /dev/null +++ b/opal/mca/threads/argobots/threads_argobots_tsd.h @@ -0,0 +1,54 @@ +/* -*- 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) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + + +#ifndef OPAL_MCA_THREADS_ARGOBOTS_THREADS_ARGOBOTS_TSD_H +#define OPAL_MCA_THREADS_ARGOBOTS_THREADS_ARGOBOTS_TSD_H + +#include "opal/mca/threads/argobots/threads_argobots.h" +#include + +typedef ABT_key opal_tsd_key_t; + +static inline int opal_tsd_key_delete(opal_tsd_key_t key) +{ + int ret = ABT_key_free(&key); + return ABT_SUCCESS == ret ? OPAL_SUCCESS : OPAL_ERROR; +} + +static inline int opal_tsd_setspecific(opal_tsd_key_t key, void *value) +{ + opal_threads_argobots_ensure_init(); + int ret = ABT_key_set(key, value); + return ABT_SUCCESS == ret ? OPAL_SUCCESS : OPAL_ERROR; +} + +static inline int opal_tsd_getspecific(opal_tsd_key_t key, void **valuep) +{ + int ret = ABT_key_get(key, valuep); + return ABT_SUCCESS == ret ? OPAL_SUCCESS : OPAL_ERROR; +} + +#endif /* OPAL_MCA_THREADS_ARGOBOTS_THREADS_ARGOBOTS_TSD_H */ diff --git a/opal/mca/threads/argobots/threads_argobots_wait_sync.c b/opal/mca/threads/argobots/threads_argobots_wait_sync.c new file mode 100644 index 00000000000..34ec10d5a74 --- /dev/null +++ b/opal/mca/threads/argobots/threads_argobots_wait_sync.c @@ -0,0 +1,116 @@ +/* -*- 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 IBM Corporation. All rights reserved. + * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "opal/mca/threads/argobots/threads_argobots.h" +#include "opal/mca/threads/wait_sync.h" + +static opal_mutex_t wait_sync_lock = OPAL_MUTEX_STATIC_INIT; +static ompi_wait_sync_t *wait_sync_list = NULL; + +static opal_atomic_int32_t num_thread_in_progress = 0; + +#define WAIT_SYNC_PASS_OWNERSHIP(who) \ + do { \ + ABT_mutex_lock((who)->lock); \ + ABT_cond_signal((who)->condition ); \ + ABT_mutex_unlock((who)->lock); \ + } while (0) + +int ompi_sync_wait_mt(ompi_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) ? OPAL_SUCCESS : OPAL_ERROR; + } + + /* lock so nobody can signal us during the list updating */ + ABT_mutex_lock(sync->lock); + + /* Now that we hold the lock make sure another thread has not already + * call cond_signal. + */ + if (sync->count <= 0) { + ABT_mutex_unlock(sync->lock); + return (0 == sync->status) ? OPAL_SUCCESS : OPAL_ERROR; + } + + /* Insert sync on the list of pending synchronization constructs */ + OPAL_THREAD_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; + } + OPAL_THREAD_UNLOCK(&wait_sync_lock); + + /** + * If we are not responsible for progressing, 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 && + num_thread_in_progress >= opal_max_thread_in_progress) { + ABT_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? */ + ABT_mutex_unlock(sync->lock); + goto i_am_done; + } + /* either promoted, or spurious wakeup ! */ + goto check_status; + } + ABT_mutex_unlock(sync->lock); + + OPAL_THREAD_ADD_FETCH32(&num_thread_in_progress, 1); + while (sync->count > 0) { /* progress till completion */ + /* don't progress with the sync lock locked or you'll deadlock */ + opal_progress(); + ABT_thread_yield(); + } + OPAL_THREAD_ADD_FETCH32(&num_thread_in_progress, -1); + + i_am_done: + /* My sync is now complete. Trim the list: remove self, wake next */ + OPAL_THREAD_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) { + WAIT_SYNC_PASS_OWNERSHIP(wait_sync_list); + } + } + OPAL_THREAD_UNLOCK(&wait_sync_lock); + + return (0 == sync->status) ? OPAL_SUCCESS : OPAL_ERROR; +} diff --git a/opal/mca/threads/argobots/threads_argobots_wait_sync.h b/opal/mca/threads/argobots/threads_argobots_wait_sync.h new file mode 100644 index 00000000000..b5aec54d02a --- /dev/null +++ b/opal/mca/threads/argobots/threads_argobots_wait_sync.h @@ -0,0 +1,107 @@ +/* -*- 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) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef OPAL_MCA_THREADS_ARGOBOTS_THREADS_ARGOBOTS_WAIT_SYNC_H +#define OPAL_MCA_THREADS_ARGOBOTS_THREADS_ARGOBOTS_WAIT_SYNC_H + +#include "opal/mca/threads/argobots/threads_argobots.h" +#include + +typedef struct ompi_wait_sync_t { + opal_atomic_int32_t count; + int32_t status; + ABT_cond condition; + ABT_mutex lock; + struct ompi_wait_sync_t *next; + struct ompi_wait_sync_t *prev; + volatile bool signaling; +} ompi_wait_sync_t; + +#define SYNC_WAIT(sync) \ + (opal_using_threads() ? ompi_sync_wait_mt (sync) : sync_wait_st (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 WAIT_SYNC_RELEASE(sync) \ + if (opal_using_threads()) { \ + while ((sync)->signaling) { \ + ABT_thread_yield(); \ + continue; \ + } \ + ABT_cond_free(&(sync)->condition); \ + ABT_mutex_free(&(sync)->lock); \ + } + +#define WAIT_SYNC_RELEASE_NOWAIT(sync) \ + if (opal_using_threads()) { \ + ABT_cond_free(&(sync)->condition); \ + ABT_mutex_free(&(sync)->lock); \ + } + + +#define WAIT_SYNC_SIGNAL(sync) \ + if (opal_using_threads()) { \ + ABT_mutex_lock(sync->lock); \ + ABT_cond_signal(sync->condition); \ + ABT_mutex_unlock(sync->lock); \ + sync->signaling = false; \ + } + +#define WAIT_SYNC_SIGNALLED(sync) \ + { \ + (sync)->signaling = false; \ + } + +OPAL_DECLSPEC int ompi_sync_wait_mt(ompi_wait_sync_t *sync); +static inline int sync_wait_st(ompi_wait_sync_t *sync) +{ + while (sync->count > 0) { + opal_progress(); + ABT_thread_yield(); + } + return sync->status; +} + + +#define WAIT_SYNC_INIT(sync,c) \ + do { \ + (sync)->count = (c); \ + (sync)->next = NULL; \ + (sync)->prev = NULL; \ + (sync)->status = 0; \ + (sync)->signaling = (0 != (c)); \ + if (opal_using_threads()) { \ + ABT_cond_create(&(sync)->condition); \ + ABT_mutex_create(&(sync)->lock); \ + } \ + } while (0) + +#endif /* OPAL_MCA_THREADS_ARGOBOTS_THREADS_ARGOBOTS_WAIT_SYNC_H */ diff --git a/opal/mca/threads/base/Makefile.am b/opal/mca/threads/base/Makefile.am new file mode 100644 index 00000000000..5b0e0b328ea --- /dev/null +++ b/opal/mca/threads/base/Makefile.am @@ -0,0 +1,25 @@ +# +# 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) 2019 Sandia National Laboratories. All rights reserved. +# +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +headers += \ + base/base.h + +libmca_threads_la_SOURCES += \ + base/threads_base.c diff --git a/opal/mca/threads/base/base.h b/opal/mca/threads/base/base.h new file mode 100644 index 00000000000..dd774005068 --- /dev/null +++ b/opal/mca/threads/base/base.h @@ -0,0 +1,48 @@ +/* -*- 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) 2014 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + */ + +#ifndef OPAL_MCA_THREADS_BASE_BASE_H +#define OPAL_MCA_THREADS_BASE_BASE_H + +#include "opal_config.h" +#include "opal/mca/base/mca_base_framework.h" +#include "opal/mca/threads/threads.h" + + +/* + * Global functions for MCA overall threads open and close + */ + +BEGIN_C_DECLS + +/** + * Framework structure declaration + */ +OPAL_DECLSPEC extern mca_base_framework_t opal_threads_base_framework; + +END_C_DECLS + +/* include implementation to call */ +#include MCA_threads_base_include_HEADER + +#endif /* OPAL_MCA_THREADS_BASE_BASE_H */ diff --git a/opal/mca/threads/base/owner.txt b/opal/mca/threads/base/owner.txt new file mode 100644 index 00000000000..340dd610b4f --- /dev/null +++ b/opal/mca/threads/base/owner.txt @@ -0,0 +1,7 @@ +# +# owner/status file +# owner: institution that is responsible for this package +# status: e.g. active, maintenance, unmaintained +# +owner: SNL +status: maintenance diff --git a/opal/mca/threads/base/threads_base.c b/opal/mca/threads/base/threads_base.c new file mode 100644 index 00000000000..a0611da1900 --- /dev/null +++ b/opal/mca/threads/base/threads_base.c @@ -0,0 +1,50 @@ +/* -*- 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) 2014 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "opal_config.h" + +#include "opal/constants.h" +#include "opal/mca/threads/base/base.h" + +#if OPAL_ENABLE_DEBUG +bool opal_debug_threads = false; +#endif + +/* + * The following file was created by configure. It contains extern + * statements and the definition of an array of pointers to each + * component's public mca_base_component_t struct. + */ +#include "opal/mca/threads/base/static-components.h" + +static int mca_threads_base_register(mca_base_register_flag_t flags) +{ + return OPAL_SUCCESS; +} + +/* + * Globals + */ +/* Use default register/open/close functions */ +MCA_BASE_FRAMEWORK_DECLARE(opal, threads, "OPAL threads", + mca_threads_base_register, NULL, NULL, + mca_threads_base_static_components, 0); diff --git a/opal/threads/condition.h b/opal/mca/threads/condition.h similarity index 68% rename from opal/threads/condition.h rename to opal/mca/threads/condition.h index 4c61fd64ac9..234e61634fe 100644 --- a/opal/threads/condition.h +++ b/opal/mca/threads/condition.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 @@ -13,14 +14,19 @@ * reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. + * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. + * Copyright (c) 2019 Triad National Security, LLC. All rights + * reserved. + * * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */ -#ifndef OPAL_CONDITION_SPINLOCK_H -#define OPAL_CONDITION_SPINLOCK_H + +#ifndef OPAL_MCA_THREADS_CONDITION_H +#define OPAL_MCA_THREADS_CONDITION_H #include "opal_config.h" #ifdef HAVE_SYS_TIME_H @@ -29,7 +35,7 @@ #include #include -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/runtime/opal_progress.h" #include "opal/runtime/opal_cr.h" @@ -53,7 +59,7 @@ OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_condition_t); static inline int opal_condition_wait(opal_condition_t *c, opal_mutex_t *m) { - int rc = 0; + int rc = OPAL_SUCCESS; c->c_waiting++; if (opal_using_threads()) { @@ -63,16 +69,16 @@ static inline int opal_condition_wait(opal_condition_t *c, opal_mutex_t *m) opal_progress(); OPAL_CR_TEST_CHECKPOINT_READY_STALL(); opal_mutex_lock(m); - return 0; + return rc; } - while (c->c_signaled == 0) { + while (0 == c->c_signaled) { opal_mutex_unlock(m); opal_progress(); OPAL_CR_TEST_CHECKPOINT_READY_STALL(); opal_mutex_lock(m); } } else { - while (c->c_signaled == 0) { + while (0 == c->c_signaled) { opal_progress(); OPAL_CR_TEST_CHECKPOINT_READY_STALL(); } @@ -83,44 +89,45 @@ static inline int opal_condition_wait(opal_condition_t *c, opal_mutex_t *m) return rc; } -static inline int opal_condition_timedwait(opal_condition_t *c, - opal_mutex_t *m, +static inline int opal_condition_timedwait(opal_condition_t *c, opal_mutex_t *m, const struct timespec *abstime) { struct timeval tv; struct timeval absolute; - int rc = 0; + int rc = OPAL_SUCCESS; c->c_waiting++; if (opal_using_threads()) { absolute.tv_sec = abstime->tv_sec; absolute.tv_usec = abstime->tv_nsec / 1000; - gettimeofday(&tv,NULL); - if (c->c_signaled == 0) { + gettimeofday(&tv, NULL); + if (0 == c->c_signaled) { do { opal_mutex_unlock(m); opal_progress(); - gettimeofday(&tv,NULL); + gettimeofday(&tv, NULL); opal_mutex_lock(m); - } while (c->c_signaled == 0 && - (tv.tv_sec <= absolute.tv_sec || - (tv.tv_sec == absolute.tv_sec && tv.tv_usec < absolute.tv_usec))); + } while (0 == c->c_signaled && (tv.tv_sec <= absolute.tv_sec || + (tv.tv_sec == absolute.tv_sec && + tv.tv_usec < absolute.tv_usec))); } } else { absolute.tv_sec = abstime->tv_sec; absolute.tv_usec = abstime->tv_nsec / 1000; - gettimeofday(&tv,NULL); - if (c->c_signaled == 0) { + gettimeofday(&tv, NULL); + if (0 == c->c_signaled) { do { opal_progress(); - gettimeofday(&tv,NULL); - } while (c->c_signaled == 0 && - (tv.tv_sec <= absolute.tv_sec || - (tv.tv_sec == absolute.tv_sec && tv.tv_usec < absolute.tv_usec))); + gettimeofday(&tv, NULL); + } while (0 == c->c_signaled && (tv.tv_sec <= absolute.tv_sec || + (tv.tv_sec == absolute.tv_sec && + tv.tv_usec < absolute.tv_usec))); } } - if (c->c_signaled != 0) c->c_signaled--; + if (0 != c->c_signaled) { + c->c_signaled--; + } c->c_waiting--; return rc; } @@ -130,16 +137,15 @@ static inline int opal_condition_signal(opal_condition_t *c) if (c->c_waiting) { c->c_signaled++; } - return 0; + return OPAL_SUCCESS; } static inline int opal_condition_broadcast(opal_condition_t *c) { c->c_signaled = c->c_waiting; - return 0; + return OPAL_SUCCESS; } END_C_DECLS -#endif - +#endif /* OPAL_MCA_THREADS_CONDITION_H */ diff --git a/opal/mca/threads/configure.m4 b/opal/mca/threads/configure.m4 new file mode 100644 index 00000000000..dfe24cccd00 --- /dev/null +++ b/opal/mca/threads/configure.m4 @@ -0,0 +1,60 @@ +dnl -*- shell-script -*- +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) 2010 Cisco Systems, Inc. All rights reserved. +dnl Copyright (c) 2019 Sandia National Laboratories. All rights reserved. +dnl Copyright (c) 2019 Triad National Security, LLC. All rights +dnl reserved. +dnl +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ +dnl + +dnl we only want one :) +m4_define(MCA_opal_threads_CONFIGURE_MODE, STOP_AT_FIRST) + +AC_DEFUN([MCA_opal_threads_CONFIG],[ +# +# Arguments: none +# +# Dependencies: None +# +# Modifies: +# none - see called tests +# +# configure threads +# + +# +# First see what kind of threads we are going to use +# + +AC_ARG_WITH([threads], + [AC_HELP_STRING([--with-threads=TYPE], + [Specify thread TYPE to use. default:pthreads. Other options are qthreads and argobots.])]) + +# +# Configure components +# + +MCA_CONFIGURE_FRAMEWORK($1, $2, 1) + +AS_IF([test x"$opal_thread_type_found" = x""], + [AC_MSG_ERROR([Did not find a suitable threads component])]) + +AC_MSG_RESULT([Found thread type $opal_thread_type_found]) + +OPAL_SUMMARY_ADD([[Miscellaneous]],[[Threading Package]],[], [$opal_thread_type_found]) +])dnl diff --git a/opal/threads/mutex.h b/opal/mca/threads/mutex.h similarity index 77% rename from opal/threads/mutex.h rename to opal/mca/threads/mutex.h index 694c23d988a..a81e94cb6e8 100644 --- a/opal/threads/mutex.h +++ b/opal/mca/threads/mutex.h @@ -15,6 +15,7 @@ * reserved. * Copyright (c) 2007 Voltaire. All rights reserved. * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. * * $COPYRIGHT$ * @@ -23,13 +24,11 @@ * $HEADER$ */ -#ifndef OPAL_MUTEX_H -#define OPAL_MUTEX_H 1 +#ifndef OPAL_MCA_THREADS_MUTEX_H +#define OPAL_MCA_THREADS_MUTEX_H #include "opal_config.h" -#include "opal/threads/thread_usage.h" - BEGIN_C_DECLS /** @@ -43,9 +42,16 @@ BEGIN_C_DECLS /** * Opaque mutex object */ + typedef struct opal_mutex_t opal_mutex_t; typedef struct opal_mutex_t opal_recursive_mutex_t; +#include MCA_threads_mutex_base_include_HEADER + +OBJ_CLASS_DECLARATION(opal_mutex_t); +OBJ_CLASS_DECLARATION(opal_recursive_mutex_t); + + /** * Try to acquire a mutex. * @@ -95,11 +101,6 @@ static inline void opal_mutex_atomic_lock(opal_mutex_t *mutex); */ static inline void opal_mutex_atomic_unlock(opal_mutex_t *mutex); -END_C_DECLS - -#include "mutex_unix.h" - -BEGIN_C_DECLS /** * Lock a mutex if opal_using_threads() says that multiple threads may @@ -114,11 +115,11 @@ BEGIN_C_DECLS * If there is no possibility that multiple threads are running in the * process, return immediately. */ -#define OPAL_THREAD_LOCK(mutex) \ - do { \ - if (OPAL_UNLIKELY(opal_using_threads())) { \ - opal_mutex_lock(mutex); \ - } \ +#define OPAL_THREAD_LOCK(mutex) \ + do { \ + if (OPAL_UNLIKELY(opal_using_threads())) { \ + opal_mutex_lock(mutex); \ + } \ } while (0) @@ -137,7 +138,7 @@ BEGIN_C_DECLS * * Returns 0 if mutex was locked, non-zero otherwise. */ -#define OPAL_THREAD_TRYLOCK(mutex) \ +#define OPAL_THREAD_TRYLOCK(mutex) \ (OPAL_UNLIKELY(opal_using_threads()) ? opal_mutex_trylock(mutex) : 0) /** @@ -153,11 +154,11 @@ BEGIN_C_DECLS * If there is no possibility that multiple threads are running in the * process, return immediately without modifying the mutex. */ -#define OPAL_THREAD_UNLOCK(mutex) \ - do { \ - if (OPAL_UNLIKELY(opal_using_threads())) { \ - opal_mutex_unlock(mutex); \ - } \ +#define OPAL_THREAD_UNLOCK(mutex) \ + do { \ + if (OPAL_UNLIKELY(opal_using_threads())) { \ + opal_mutex_unlock(mutex); \ + } \ } while (0) @@ -176,17 +177,17 @@ BEGIN_C_DECLS * If there is no possibility that multiple threads are running in the * process, invoke the action without acquiring the lock. */ -#define OPAL_THREAD_SCOPED_LOCK(mutex, action) \ - do { \ - if(OPAL_UNLIKELY(opal_using_threads())) { \ - opal_mutex_lock(mutex); \ - action; \ - opal_mutex_unlock(mutex); \ - } else { \ - action; \ - } \ +#define OPAL_THREAD_SCOPED_LOCK(mutex, action) \ + do { \ + if (OPAL_UNLIKELY(opal_using_threads())) { \ + opal_mutex_lock(mutex); \ + action; \ + opal_mutex_unlock(mutex); \ + } else { \ + action; \ + } \ } while (0) END_C_DECLS -#endif /* OPAL_MUTEX_H */ +#endif /* OPAL_MCA_THREADS_MUTEX_H */ diff --git a/opal/mca/threads/pthreads/Makefile.am b/opal/mca/threads/pthreads/Makefile.am new file mode 100644 index 00000000000..833950d5e17 --- /dev/null +++ b/opal/mca/threads/pthreads/Makefile.am @@ -0,0 +1,32 @@ +# +# 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) 2008 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2019 Sandia National Laboratories. All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +noinst_LTLIBRARIES = libmca_threads_pthreads.la + +libmca_threads_pthreads_la_SOURCES = \ + threads_pthreads_component.c \ + threads_pthreads_condition.c \ + threads_pthreads_module.c \ + threads_pthreads_mutex.c \ + threads_pthreads_mutex.h \ + threads_pthreads_threads.h \ + threads_pthreads_tsd.h \ + threads_pthreads_wait_sync.c \ + threads_pthreads_wait_sync.h diff --git a/config/opal_config_pthreads.m4 b/opal/mca/threads/pthreads/configure.m4 similarity index 63% rename from config/opal_config_pthreads.m4 rename to opal/mca/threads/pthreads/configure.m4 index b2d9c7aaece..4c250493c74 100644 --- a/config/opal_config_pthreads.m4 +++ b/opal/mca/threads/pthreads/configure.m4 @@ -1,28 +1,27 @@ -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 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 OPAL_CONFIG_POSIX_THREADS() -dnl -dnl Configure posix threads, setting the following variables (but -dnl not calling AC_SUBST on them). +# -*- shell-script -*- +# +# Copyright (c) 2004-2006 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) 2008-2020 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2015 Research Organization for Information Science +# and Technology (RIST). All rights reserved. +# Copyright (c) 2019 Sandia National Laboratories. All rights reserved. +# Copyright (c) 2019 Triad National Security, LLC. All rights +# reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# # ******************************************************************** # @@ -31,6 +30,101 @@ dnl not calling AC_SUBST on them). # ******************************************************************** +AC_DEFUN([OPAL_CHECK_PTHREAD_PIDS],[ +# +# Arguments: none +# +# Dependencies: None +# +# Sets: +# OPAL_THREADS_HAVE_DIFFERENT_PIDS (variable) +# +# Test for Linux-like threads in the system. OPAL no longer supports +# 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)]) + +OPAL_VAR_SCOPE_PUSH([CFLAGS_save CPPFLAGS_save LDFLAGS_save LIBS_save MSG]) +CFLAGS_save="$CFLAGS" +CFLAGS="$CFLAGS $THREAD_CFLAGS" +CPPFLAGS_save="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $THREAD_CPPFLAGS" +LDFLAGS_save="$LDFLAGS" +LDFLAGS="$LDFLAGS $THREAD_LDFLAGS" +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); +}])], +[MSG=no OPAL_THREADS_HAVE_DIFFERENT_PIDS=0], +[MSG=yes OPAL_THREADS_HAVE_DIFFERENT_PIDS=1], +[ + # If we're cross compiling, we can't do another AC_* function here because + # it we haven't displayed the result from the last one yet. So defer + # another test until below. + OPAL_THREADS_HAVE_DIFFERENT_PIDS= + MSG="cross compiling (need another test)"]) + +CFLAGS="$CFLAGS_save" +CPPFLAGS="$CPPFLAGS_save" +LDFLAGS="$LDFLAGS_save" +LIBS="$LIBS_save" + +AC_MSG_RESULT([$MSG]) + +AS_IF([test "x$OPAL_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], + [OPAL_THREADS_HAVE_DIFFERENT_PIDS=1])]) + +AS_IF([test "$OPAL_THREADS_HAVE_DIFFERENT_PIDS" = "1"], + [AC_MSG_WARN([This version of Open MPI only supports environments where]) + AC_MSG_WARN([threads have the same PID. Please use an older version of]) + AC_MSG_WARN([Open MPI if you need support on systems with different]) + AC_MSG_WARN([PIDs for threads in the same process. Open MPI 1.4.x]) + AC_MSG_WARN([supports such systems, as does at least some versions the]) + AC_MSG_WARN([Open MPI 1.5.x series.]) + AC_MSG_ERROR([Cannot continue]) + ]) + +# +# if pthreads is not available, then the system does not have an insane threads +# model +# +OPAL_VAR_SCOPE_POP +])dnl + AC_DEFUN([OPAL_INTL_PTHREAD_TRY_LINK], [ # BEGIN: OPAL_INTL_PTHREAD_TRY_LINK # @@ -78,6 +172,8 @@ AC_DEFUN([OPAL_INTL_PTHREAD_TRY_LINK_FORTRAN], [ # Make sure that we can run a small application in Fortran, with # pthreads living in a C object file +OPAL_VAR_SCOPE_PUSH([HAPPY opal_conftest_h]) + # Fortran module cat > conftestf.f <]], [[pthread_mutexattr_settype(NULL, PTHREAD_MUTEX_ERRORCHECK_NP);]])], - [result="yes" defval=1], [result="no" defval=0]) -AC_MSG_RESULT([$result]) + [opal_pthreads_result="yes" defval=1], [opal_pthreads_result="no" defval=0]) +AC_MSG_RESULT([$opal_pthreads_result]) AC_DEFINE_UNQUOTED([OPAL_HAVE_PTHREAD_MUTEX_ERRORCHECK_NP], [$defval], [If PTHREADS implementation supports PTHREAD_MUTEX_ERRORCHECK_NP]) @@ -643,8 +750,8 @@ 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]) + [opal_pthreads_result="yes" defval=1], [opal_pthreads_result="no" defval=0]) +AC_MSG_RESULT([$opal_pthreads_result]) AC_DEFINE_UNQUOTED([OPAL_HAVE_PTHREAD_MUTEX_ERRORCHECK], [$defval], [If PTHREADS implementation supports PTHREAD_MUTEX_ERRORCHECK]) @@ -656,21 +763,91 @@ CXXCPPFLAGS="$orig_CXXCPPFLAGS" LDFLAGS="$orig_LDFLAGS" LIBS="$orig_LIBS" +THREAD_CFLAGS="$TPKG_CFLAGS" +THREAD_FCFLAGS="$TPKG_FCFLAGS" +THREAD_CXXFLAGS="$TPKG_CXXFLAGS" +THREAD_CPPFLAGS="$TPKG_CPPFLAGS" +THREAD_CXXCPPFLAGS="$TPKG_CXXCPPFLAGS" +THREAD_LDFLAGS="$TPKG_LDFLAGS" +THREAD_LIBS="$TPKG_LIBS" + +OPAL_CHECK_PTHREAD_PIDS + if test "$OMPI_TRY_FORTRAN_BINDINGS" = "$OMPI_FORTRAN_NO_BINDINGS" || \ test $ompi_fortran_happy -ne 1; then - opal_pthread_fortran_success=1 + opal_pthread_fortran_success=1 fi -if test "$opal_pthread_c_success" = "1" && \ - test "$opal_pthread_cxx_success" = "1" && \ - test "$opal_pthread_fortran_success" = "1"; then - internal_useless=1 - $1 +AC_MSG_CHECKING([if POSIX threads work]) +if test $opal_pthread_c_success -eq 1 && \ + test $opal_pthread_cxx_success -eq 1 && \ + test $opal_pthread_fortran_success -eq 1; then + AC_MSG_RESULT([yes]) + $1 else - internal_useless=1 - $2 + AC_MSG_RESULT([no]) + $2 fi -unset opal_pthread_c_success opal_pthread_fortran_success opal_pthread_cxx_success -unset internal_useless +OPAL_VAR_SCOPE_POP ])dnl + +AC_DEFUN([MCA_opal_threads_pthreads_PRIORITY], [30]) + +AC_DEFUN([MCA_opal_threads_pthreads_COMPILE_MODE], [ + AC_MSG_CHECKING([for MCA component $2:$3 compile mode]) + $4="static" + AC_MSG_RESULT([$$4]) +]) + + +# If component was selected, $1 will be 1 and we should set the base header +AC_DEFUN([MCA_opal_threads_pthreads_POST_CONFIG],[ + AS_IF([test "$1" = "1"], + [opal_thread_type_found="pthreads" + AC_DEFINE_UNQUOTED([MCA_threads_base_include_HEADER], + ["opal/mca/threads/pthreads/threads_pthreads_threads.h"], + [Header to include for threads implementation]) + AC_DEFINE_UNQUOTED([MCA_threads_mutex_base_include_HEADER], + ["opal/mca/threads/pthreads/threads_pthreads_mutex.h"], + [Header to include for mutex implementation]) + AC_DEFINE_UNQUOTED([MCA_threads_tsd_base_include_HEADER], + ["opal/mca/threads/pthreads/threads_pthreads_tsd.h"], + [Header to include for tsd implementation]) + AC_DEFINE_UNQUOTED([MCA_threads_wait_sync_base_include_HEADER], + ["opal/mca/threads/pthreads/threads_pthreads_wait_sync.h"], + [Header to include for wait_sync implementation]) + THREAD_CFLAGS="$TPKG_CFLAGS" + THREAD_FCFLAGS="$TPKG_FCFLAGS" + THREAD_CXXFLAGS="$TPKG_CXXFLAGS" + THREAD_CPPFLAGS="$TPKG_CPPFLAGS" + THREAD_CXXCPPFLAGS="$TPKG_CXXCPPFLAGS" + THREAD_LDFLAGS="$TPKG_LDFLAGS" + THREAD_LIBS="$TPKG_LIBS" + AC_SUBST(THREAD_CFLAGS) + AC_SUBST(THREAD_FCFLAGS) + AC_SUBST(THREAD_CXXFLAGS) + AC_SUBST(THREAD_CPPFLAGS) + AC_SUBST(THREAD_LDFLAGS) + AC_SUBST(THREAD_LIBS) + ]) +])dnl + +# MCA_threads_pthreads_CONFIG(action-if-can-compile, +# [action-if-cant-compile]) +# ------------------------------------------------ +AC_DEFUN([MCA_opal_threads_pthreads_CONFIG],[ + AC_CONFIG_FILES([opal/mca/threads/pthreads/Makefile]) + OPAL_VAR_SCOPE_PUSH([posix_thread_works]) + + AS_IF([test -z "$with_threads" || test "$with_threads" = "pthreads" || test "$with_threads" = "yes"], + [OPAL_CONFIG_POSIX_THREADS([posix_threads_works=1],[posix_threads_works=0])], + [posix_threads_works=0]) + + AS_IF([test $posix_threads_works -eq 1], + [$1], + [$2]) + + OPAL_VAR_SCOPE_POP +]) + diff --git a/opal/mca/threads/pthreads/owner.txt b/opal/mca/threads/pthreads/owner.txt new file mode 100644 index 00000000000..1cd89be1e87 --- /dev/null +++ b/opal/mca/threads/pthreads/owner.txt @@ -0,0 +1,7 @@ +# +# owner/status file +# owner: institution that is responsible for this package +# status: e.g. active, maintenance, unmaintained +# +owner: SNL +status: active diff --git a/opal/mca/threads/pthreads/threads_pthreads_component.c b/opal/mca/threads/pthreads/threads_pthreads_component.c new file mode 100644 index 00000000000..fcd00368831 --- /dev/null +++ b/opal/mca/threads/pthreads/threads_pthreads_component.c @@ -0,0 +1,54 @@ +/* -*- 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 + * 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) 2007-2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "opal_config.h" + +#include "opal/mca/threads/thread.h" +#include "opal/mca/threads/threads.h" +#include "opal/constants.h" + +static int opal_threads_pthreads_open(void); + +const opal_threads_base_component_1_0_0_t mca_threads_pthreads_component = { + /* First, the mca_component_t struct containing meta information + * about the component itself */ + .threadsc_version = { + OPAL_THREADS_BASE_VERSION_1_0_0, + + /* Component name and version */ + .mca_component_name = "pthreads", + MCA_BASE_MAKE_VERSION(component, OPAL_MAJOR_VERSION, OPAL_MINOR_VERSION, + OPAL_RELEASE_VERSION), + + .mca_open_component = opal_threads_pthreads_open, + }, + .threadsc_data = { + /* The component is checkpoint ready */ + MCA_BASE_METADATA_PARAM_CHECKPOINT + }, +}; + +int opal_threads_pthreads_open(void) +{ + return OPAL_SUCCESS; +} diff --git a/opal/threads/condition.c b/opal/mca/threads/pthreads/threads_pthreads_condition.c similarity index 85% rename from opal/threads/condition.c rename to opal/mca/threads/pthreads/threads_pthreads_condition.c index 7745d316544..f685a24cef5 100644 --- a/opal/threads/condition.c +++ b/opal/mca/threads/pthreads/threads_pthreads_condition.c @@ -1,3 +1,4 @@ +/* -*- 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 @@ -9,6 +10,8 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. + * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. + * * $COPYRIGHT$ * * Additional copyrights may follow @@ -18,7 +21,7 @@ #include "opal_config.h" -#include "opal/threads/condition.h" +#include "opal/mca/threads/condition.h" static void opal_condition_construct(opal_condition_t *c) @@ -27,7 +30,6 @@ static void opal_condition_construct(opal_condition_t *c) c->c_signaled = 0; } - static void opal_condition_destruct(opal_condition_t *c) { } diff --git a/opal/threads/thread.c b/opal/mca/threads/pthreads/threads_pthreads_module.c similarity index 57% rename from opal/threads/thread.c rename to opal/mca/threads/pthreads/threads_pthreads_module.c index 2d67fa2d693..8d67d4d5708 100644 --- a/opal/threads/thread.c +++ b/opal/mca/threads/pthreads/threads_pthreads_module.c @@ -1,17 +1,21 @@ +/* -*- 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 + * 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) 2010 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2015-2017 Research Organization for Information Science + * Copyright (c) 2007-2018 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) 2019 Sandia National Laboratories. All rights reserved. + * * $COPYRIGHT$ * * Additional copyrights may follow @@ -19,102 +23,101 @@ * $HEADER$ */ -#include "opal_config.h" +#include -#include "opal/threads/threads.h" -#include "opal/threads/tsd.h" #include "opal/constants.h" - -bool opal_debug_threads = false; - -static void opal_thread_construct(opal_thread_t *t); - -static pthread_t opal_main_thread; +#include "opal/util/sys_limits.h" +#include "opal/util/output.h" +#include "opal/prefetch.h" +#include "opal/mca/threads/threads.h" +#include "opal/mca/threads/tsd.h" struct opal_tsd_key_value { opal_tsd_key_t key; opal_tsd_destructor_t destructor; }; -static struct opal_tsd_key_value *opal_tsd_key_values = NULL; +static pthread_t opal_main_thread; +struct opal_tsd_key_value *opal_tsd_key_values = NULL; static int opal_tsd_key_values_count = 0; -OBJ_CLASS_INSTANCE(opal_thread_t, - opal_object_t, - opal_thread_construct, NULL); - - /* * Constructor */ static void opal_thread_construct(opal_thread_t *t) { t->t_run = 0; - t->t_handle = (pthread_t) -1; + t->t_handle = (pthread_t)-1; } -int opal_thread_start(opal_thread_t *t) -{ - int rc; - - if (OPAL_ENABLE_DEBUG) { - if (NULL == t->t_run || t->t_handle != (pthread_t) -1) { - return OPAL_ERR_BAD_PARAM; - } - } +OBJ_CLASS_INSTANCE(opal_thread_t, + opal_object_t, + opal_thread_construct, NULL); - rc = pthread_create(&t->t_handle, NULL, (void*(*)(void*)) t->t_run, t); - return (rc == 0) ? OPAL_SUCCESS : OPAL_ERROR; +opal_thread_t *opal_thread_get_self(void) +{ + opal_thread_t *t = OBJ_NEW(opal_thread_t); + t->t_handle = pthread_self(); + return t; } +bool opal_thread_self_compare(opal_thread_t *t) +{ + return pthread_self() == t->t_handle; +} int opal_thread_join(opal_thread_t *t, void **thr_return) { int rc = pthread_join(t->t_handle, thr_return); - t->t_handle = (pthread_t) -1; - return (rc == 0) ? OPAL_SUCCESS : OPAL_ERROR; + t->t_handle = (pthread_t)-1; + return 0 == rc ? OPAL_SUCCESS : OPAL_ERR_IN_ERRNO; } - -bool opal_thread_self_compare(opal_thread_t *t) +void opal_thread_set_main(void) { - return t->t_handle == pthread_self(); + opal_main_thread = pthread_self(); } - -opal_thread_t *opal_thread_get_self(void) +int opal_thread_start(opal_thread_t *t) { - opal_thread_t *t = OBJ_NEW(opal_thread_t); - t->t_handle = pthread_self(); - return t; -} + int rc; -void opal_thread_kill(opal_thread_t *t, int sig) -{ - pthread_kill(t->t_handle, sig); + if (OPAL_ENABLE_DEBUG) { + if (NULL == t->t_run || (pthread_t)-1 != t->t_handle) { + return OPAL_ERR_BAD_PARAM; + } + } + + rc = pthread_create(&t->t_handle, NULL, (void *(*)(void *))t->t_run, t); + + return 0 == rc ? OPAL_SUCCESS : OPAL_ERR_IN_ERRNO; } -int opal_tsd_key_create(opal_tsd_key_t *key, - opal_tsd_destructor_t destructor) +OBJ_CLASS_DECLARATION(opal_thread_t); + +int opal_tsd_key_create(opal_tsd_key_t *key, opal_tsd_destructor_t destructor) { int rc; rc = pthread_key_create(key, destructor); if ((0 == rc) && (pthread_self() == opal_main_thread)) { - opal_tsd_key_values = (struct opal_tsd_key_value *)realloc(opal_tsd_key_values, (opal_tsd_key_values_count+1) * sizeof(struct opal_tsd_key_value)); + opal_tsd_key_values = (struct opal_tsd_key_value *) + realloc(opal_tsd_key_values, (opal_tsd_key_values_count + 1) * + sizeof(struct opal_tsd_key_value)); opal_tsd_key_values[opal_tsd_key_values_count].key = *key; opal_tsd_key_values[opal_tsd_key_values_count].destructor = destructor; - opal_tsd_key_values_count ++; + opal_tsd_key_values_count++; } - return rc; + return 0 == rc ? OPAL_SUCCESS : OPAL_ERR_IN_ERRNO; } -int opal_tsd_keys_destruct() +int opal_tsd_keys_destruct(void) { int i; - void * ptr; - for (i=0; i +#include + +#include "opal/mca/threads/mutex.h" +#include "opal/mca/threads/pthreads/threads_pthreads_mutex.h" +#include "opal/constants.h" + +/* + * Wait and see if some upper layer wants to use threads, if support + * exists. + */ +bool opal_uses_threads = false; + +struct opal_pthread_mutex_t { + opal_object_t super; + + pthread_mutex_t m_lock_pthread; + opal_atomic_lock_t m_lock_atomic; + +#if OPAL_ENABLE_DEBUG + int m_lock_debug; + const char *m_lock_file; + int m_lock_line; +#endif +}; + +typedef struct opal_pthread_mutex_t opal_pthread_mutex_t; +typedef struct opal_pthread_mutex_t opal_pthread_recursive_mutex_t; + +static void mca_threads_pthreads_mutex_constructor(opal_mutex_t *p_mutex) +{ + pthread_mutex_init(&p_mutex->m_lock_pthread, NULL); +#if OPAL_ENABLE_DEBUG + p_mutex->m_lock_debug = 0; + p_mutex->m_lock_file = NULL; + p_mutex->m_lock_line = 0; +#endif + opal_atomic_lock_init(&p_mutex->m_lock_atomic, 0); +} + +static void mca_threads_pthreads_mutex_destructor(opal_mutex_t *p_mutex) +{ + pthread_mutex_destroy(&p_mutex->m_lock_pthread); +} + +static void mca_threads_pthreads_recursive_mutex_constructor + (opal_recursive_mutex_t *p_mutex) +{ + pthread_mutexattr_t mutex_attr; + pthread_mutexattr_init(&mutex_attr); + pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&p_mutex->m_lock_pthread, &mutex_attr); + pthread_mutexattr_destroy(&mutex_attr); +#if OPAL_ENABLE_DEBUG + p_mutex->m_lock_debug = 0; + p_mutex->m_lock_file = NULL; + p_mutex->m_lock_line = 0; +#endif + opal_atomic_lock_init(&p_mutex->m_lock_atomic, 0); +} + +static void mca_threads_pthreads_recursive_mutex_destructor + (opal_recursive_mutex_t *p_mutex) +{ + pthread_mutex_destroy(&p_mutex->m_lock_pthread); +} + +OBJ_CLASS_INSTANCE(opal_mutex_t, + opal_object_t, + mca_threads_pthreads_mutex_constructor, + mca_threads_pthreads_mutex_destructor); + +OBJ_CLASS_INSTANCE(opal_recursive_mutex_t, + opal_object_t, + mca_threads_pthreads_recursive_mutex_constructor, + mca_threads_pthreads_recursive_mutex_destructor); + +int opal_cond_init(opal_cond_t *cond) +{ + int ret = pthread_cond_init(cond, NULL); + return 0 == ret ? OPAL_SUCCESS : OPAL_ERR_IN_ERRNO; +} + +int opal_cond_wait(opal_cond_t *cond, opal_mutex_t *lock) +{ + int ret = pthread_cond_wait(cond, &lock->m_lock_pthread); + return 0 == ret ? OPAL_SUCCESS : OPAL_ERR_IN_ERRNO; +} + +int opal_cond_broadcast(opal_cond_t *cond) +{ + int ret = pthread_cond_broadcast(cond); + return 0 == ret ? OPAL_SUCCESS : OPAL_ERR_IN_ERRNO; +} + +int opal_cond_signal(opal_cond_t *cond) +{ + int ret = pthread_cond_signal(cond); + return 0 == ret ? OPAL_SUCCESS : OPAL_ERR_IN_ERRNO; +} + +int opal_cond_destroy(opal_cond_t *cond) +{ + int ret = pthread_cond_destroy(cond); + return 0 == ret ? OPAL_SUCCESS : OPAL_ERR_IN_ERRNO; +} diff --git a/opal/threads/mutex_unix.h b/opal/mca/threads/pthreads/threads_pthreads_mutex.h similarity index 83% rename from opal/threads/mutex_unix.h rename to opal/mca/threads/pthreads/threads_pthreads_mutex.h index 1cafdedd4e1..1547426d209 100644 --- a/opal/threads/mutex_unix.h +++ b/opal/mca/threads/pthreads/threads_pthreads_mutex.h @@ -14,6 +14,10 @@ * reserved. * Copyright (c) 2015-2016 Research Organization for Information Science * and Technology (RIST). All rights reserved. + * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. + * Copyright (c) 2020 Triad National Security, LLC. All rights + * reserved. + * * $COPYRIGHT$ * * Additional copyrights may follow @@ -21,8 +25,8 @@ * $HEADER$ */ -#ifndef OPAL_MUTEX_UNIX_H -#define OPAL_MUTEX_UNIX_H 1 +#ifndef OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_MUTEX_H +#define OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_MUTEX_H /** * @file: @@ -43,6 +47,7 @@ #include "opal/class/opal_object.h" #include "opal/sys/atomic.h" +#include "opal/util/output.h" BEGIN_C_DECLS @@ -63,9 +68,11 @@ OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_mutex_t); OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_recursive_mutex_t); #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) -#define OPAL_PTHREAD_RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP +#define OPAL_PTHREAD_RECURSIVE_MUTEX_INITIALIZER \ + PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) -#define OPAL_PTHREAD_RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER +#define OPAL_PTHREAD_RECURSIVE_MUTEX_INITIALIZER \ + PTHREAD_RECURSIVE_MUTEX_INITIALIZER #endif #if OPAL_ENABLE_DEBUG @@ -118,27 +125,23 @@ OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_recursive_mutex_t); static inline int opal_mutex_trylock(opal_mutex_t *m) { -#if OPAL_ENABLE_DEBUG int ret = pthread_mutex_trylock(&m->m_lock_pthread); - if (ret == EDEADLK) { - errno = ret; - perror("opal_mutex_trylock()"); - abort(); - } - return ret; -#else - return pthread_mutex_trylock(&m->m_lock_pthread); + if (EDEADLK == ret) { +#if OPAL_ENABLE_DEBUG + opal_output(0, "opal_mutex_trylock() %d",ret); #endif + return 1; + } + return 0 == ret ? 0 : 1; } static inline void opal_mutex_lock(opal_mutex_t *m) { #if OPAL_ENABLE_DEBUG int ret = pthread_mutex_lock(&m->m_lock_pthread); - if (ret == EDEADLK) { + if (EDEADLK == ret) { errno = ret; - perror("opal_mutex_lock()"); - abort(); + opal_output(0, "opal_mutex_lock() %d", ret); } #else pthread_mutex_lock(&m->m_lock_pthread); @@ -149,10 +152,9 @@ static inline void opal_mutex_unlock(opal_mutex_t *m) { #if OPAL_ENABLE_DEBUG int ret = pthread_mutex_unlock(&m->m_lock_pthread); - if (ret == EPERM) { + if (EPERM == ret) { errno = ret; - perror("opal_mutex_unlock"); - abort(); + opal_output(0, "opal_mutex_unlock() %d", ret); } #else pthread_mutex_unlock(&m->m_lock_pthread); @@ -209,6 +211,15 @@ static inline void opal_mutex_atomic_unlock(opal_mutex_t *m) #endif +typedef pthread_cond_t opal_cond_t; +#define OPAL_CONDITION_STATIC_INIT PTHREAD_COND_INITIALIZER + +int opal_cond_init(opal_cond_t *cond); +int opal_cond_wait(opal_cond_t *cond, opal_mutex_t *lock); +int opal_cond_broadcast(opal_cond_t *cond); +int opal_cond_signal(opal_cond_t *cond); +int opal_cond_destroy(opal_cond_t *cond); + END_C_DECLS -#endif /* OPAL_MUTEX_UNIX_H */ +#endif /* OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_MUTEX_H */ diff --git a/opal/mca/threads/pthreads/threads_pthreads_threads.h b/opal/mca/threads/pthreads/threads_pthreads_threads.h new file mode 100644 index 00000000000..27ad13e8e1d --- /dev/null +++ b/opal/mca/threads/pthreads/threads_pthreads_threads.h @@ -0,0 +1,40 @@ +/* -*- 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-2018 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) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + + +#ifndef OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_THREADS_H +#define OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_THREADS_H + +#include +#include + +struct opal_thread_t { + opal_object_t super; + opal_thread_fn_t t_run; + void *t_arg; + pthread_t t_handle; +}; + +#endif /* OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_THREADS_H */ diff --git a/opal/mca/threads/pthreads/threads_pthreads_tsd.h b/opal/mca/threads/pthreads/threads_pthreads_tsd.h new file mode 100644 index 00000000000..ccc0ba0981d --- /dev/null +++ b/opal/mca/threads/pthreads/threads_pthreads_tsd.h @@ -0,0 +1,53 @@ +/* -*- 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-2018 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) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + + +#ifndef OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_TSD_H +#define OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_TSD_H + +#include +#include + +typedef pthread_key_t opal_tsd_key_t; + +static inline int opal_tsd_key_delete(opal_tsd_key_t key) +{ + int ret = pthread_key_delete(key); + return 0 == ret ? OPAL_SUCCESS : OPAL_ERR_IN_ERRNO; +} + +static inline int opal_tsd_setspecific(opal_tsd_key_t key, void *value) +{ + int ret = pthread_setspecific(key, value); + return 0 == ret ? OPAL_SUCCESS : OPAL_ERR_IN_ERRNO; +} + +static inline int opal_tsd_getspecific(opal_tsd_key_t key, void **valuep) +{ + *valuep = pthread_getspecific(key); + return OPAL_SUCCESS; +} + +#endif /* OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_TSD_H */ diff --git a/opal/threads/wait_sync.c b/opal/mca/threads/pthreads/threads_pthreads_wait_sync.c similarity index 72% rename from opal/threads/wait_sync.c rename to opal/mca/threads/pthreads/threads_pthreads_wait_sync.c index 1f73f7c8ad4..622efdfe1df 100644 --- a/opal/threads/wait_sync.c +++ b/opal/mca/threads/pthreads/threads_pthreads_wait_sync.c @@ -6,25 +6,28 @@ * Copyright (c) 2016 Los Alamos National Security, LLC. All rights * reserved. * Copyright (c) 2017 IBM Corporation. All rights reserved. + * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. + * * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */ -#include "wait_sync.h" + +#include "opal/mca/threads/wait_sync.h" static opal_mutex_t wait_sync_lock = OPAL_MUTEX_STATIC_INIT; -static ompi_wait_sync_t* wait_sync_list = NULL; +static ompi_wait_sync_t *wait_sync_list = NULL; static opal_atomic_int32_t num_thread_in_progress = 0; -#define WAIT_SYNC_PASS_OWNERSHIP(who) \ - do { \ - pthread_mutex_lock( &(who)->lock); \ - pthread_cond_signal( &(who)->condition ); \ - pthread_mutex_unlock( &(who)->lock); \ - } while(0) +#define WAIT_SYNC_PASS_OWNERSHIP(who) \ + do { \ + pthread_mutex_lock(&(who)->lock); \ + pthread_cond_signal(&(who)->condition); \ + pthread_mutex_unlock(&(who)->lock); \ + } while (0) int ompi_sync_wait_mt(ompi_wait_sync_t *sync) { @@ -32,8 +35,9 @@ int ompi_sync_wait_mt(ompi_wait_sync_t *sync) * race condition around the release of the synchronization using the * signaling field. */ - if(sync->count <= 0) + if (sync->count <= 0) { return (0 == sync->status) ? OPAL_SUCCESS : OPAL_ERROR; + } /* lock so nobody can signal us during the list updating */ pthread_mutex_lock(&sync->lock); @@ -41,14 +45,14 @@ int ompi_sync_wait_mt(ompi_wait_sync_t *sync) /* Now that we hold the lock make sure another thread has not already * call cond_signal. */ - if(sync->count <= 0) { + if (sync->count <= 0) { pthread_mutex_unlock(&sync->lock); return (0 == sync->status) ? OPAL_SUCCESS : OPAL_ERROR; } /* Insert sync on the list of pending synchronization constructs */ OPAL_THREAD_LOCK(&wait_sync_lock); - if( NULL == wait_sync_list ) { + if (NULL == wait_sync_list) { sync->next = sync->prev = sync; wait_sync_list = sync; } else { @@ -60,12 +64,14 @@ int ompi_sync_wait_mt(ompi_wait_sync_t *sync) OPAL_THREAD_UNLOCK(&wait_sync_lock); /** - * If we are not responsible for progresing, go silent until something worth noticing happen: + * If we are not responsible for progressing, 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 && num_thread_in_progress >= opal_max_thread_in_progress) { + check_status: + if (sync != wait_sync_list && + num_thread_in_progress >= opal_max_thread_in_progress) { pthread_cond_wait(&sync->condition, &sync->lock); /** @@ -74,7 +80,7 @@ int ompi_sync_wait_mt(ompi_wait_sync_t *sync) * promoted as the progress manager. */ - if( sync->count <= 0 ) { /* Completed? */ + if (sync->count <= 0) { /* Completed? */ pthread_mutex_unlock(&sync->lock); goto i_am_done; } @@ -84,21 +90,23 @@ int ompi_sync_wait_mt(ompi_wait_sync_t *sync) pthread_mutex_unlock(&sync->lock); OPAL_THREAD_ADD_FETCH32(&num_thread_in_progress, 1); - while(sync->count > 0) { /* progress till completion */ - opal_progress(); /* don't progress with the sync lock locked or you'll deadlock */ + while (sync->count > 0) { /* progress till completion */ + /* don't progress with the sync lock locked or you'll deadlock */ + opal_progress(); } OPAL_THREAD_ADD_FETCH32(&num_thread_in_progress, -1); - i_am_done: + i_am_done: /* My sync is now complete. Trim the list: remove self, wake next */ OPAL_THREAD_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 ) { + if (sync == wait_sync_list) { wait_sync_list = (sync == sync->next) ? NULL : sync->next; - if( NULL != wait_sync_list ) + if (NULL != wait_sync_list) { WAIT_SYNC_PASS_OWNERSHIP(wait_sync_list); + } } OPAL_THREAD_UNLOCK(&wait_sync_lock); diff --git a/opal/threads/wait_sync.h b/opal/mca/threads/pthreads/threads_pthreads_wait_sync.h similarity index 62% rename from opal/threads/wait_sync.h rename to opal/mca/threads/pthreads/threads_pthreads_wait_sync.h index 3e6c8f1949f..d34b9fcd3c7 100644 --- a/opal/threads/wait_sync.h +++ b/opal/mca/threads/pthreads/threads_pthreads_wait_sync.h @@ -1,14 +1,21 @@ /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* - * Copyright (c) 2014-2016 The University of Tennessee and The University + * 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) 2016 Los Alamos National Security, LLC. All rights + * 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-2018 Los Alamos National Security, LLC. All rights * reserved. - * Copyright (c) 2016 Mellanox Technologies. All rights reserved. - * Copyright (c) 2016 Research Organization for Information Science + * Copyright (c) 2015-2016 Research Organization for Information Science * and Technology (RIST). All rights reserved. - * Copyright (c) 2017 IBM Corporation. All rights reserved. + * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. + * * $COPYRIGHT$ * * Additional copyrights may follow @@ -16,16 +23,9 @@ * $HEADER$ */ -#if !defined(OPAL_THREADS_WAIT_SYNC_H) -#define OPAL_THREADS_WAIT_SYNC_H - -#include "opal/sys/atomic.h" -#include "opal/threads/condition.h" -#include -BEGIN_C_DECLS - -extern int opal_max_thread_in_progress; +#ifndef OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_WAIT_SYNC_H +#define OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_WAIT_SYNC_H typedef struct ompi_wait_sync_t { opal_atomic_int32_t count; @@ -37,10 +37,8 @@ typedef struct ompi_wait_sync_t { volatile bool signaling; } ompi_wait_sync_t; -#define REQUEST_PENDING (void*)0L -#define REQUEST_COMPLETED (void*)1L - -#define SYNC_WAIT(sync) (opal_using_threads() ? ompi_sync_wait_mt (sync) : sync_wait_st (sync)) +#define SYNC_WAIT(sync) \ + (opal_using_threads() ? ompi_sync_wait_mt(sync) : sync_wait_st(sync)) /* The loop in release handles a race condition between the signaling * thread and the destruction of the condition variable. The signaling @@ -74,21 +72,20 @@ typedef struct ompi_wait_sync_t { sync->signaling = false; \ } -#define WAIT_SYNC_SIGNALLED(sync){ \ +#define WAIT_SYNC_SIGNALLED(sync) \ + { \ (sync)->signaling = false; \ -} + } OPAL_DECLSPEC int ompi_sync_wait_mt(ompi_wait_sync_t *sync); -static inline int sync_wait_st (ompi_wait_sync_t *sync) +static inline int sync_wait_st(ompi_wait_sync_t *sync) { while (sync->count > 0) { opal_progress(); } - return sync->status; } - #define WAIT_SYNC_INIT(sync,c) \ do { \ (sync)->count = (c); \ @@ -97,32 +94,9 @@ static inline int sync_wait_st (ompi_wait_sync_t *sync) (sync)->status = 0; \ (sync)->signaling = (0 != (c)); \ if (opal_using_threads()) { \ - pthread_cond_init (&(sync)->condition, NULL); \ - pthread_mutex_init (&(sync)->lock, NULL); \ + 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 wait_sync_update(ompi_wait_sync_t *sync, int updates, int status) -{ - if( OPAL_LIKELY(OPAL_SUCCESS == status) ) { - if( 0 != (OPAL_THREAD_ADD_FETCH32(&sync->count, -updates)) ) { - return; - } - } else { - /* this is an error path so just use the atomic */ - sync->status = OPAL_ERROR; - opal_atomic_wmb (); - opal_atomic_swap_32 (&sync->count, 0); - } - WAIT_SYNC_SIGNAL(sync); -} - -END_C_DECLS + } while (0) -#endif /* defined(OPAL_THREADS_WAIT_SYNC_H) */ +#endif /* OPAL_MCA_THREADS_PTHREADS_THREADS_PTHREADS_WAIT_SYNC_H */ diff --git a/opal/mca/threads/qthreads/Makefile.am b/opal/mca/threads/qthreads/Makefile.am new file mode 100644 index 00000000000..287ad637619 --- /dev/null +++ b/opal/mca/threads/qthreads/Makefile.am @@ -0,0 +1,30 @@ +# +# 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) 2008 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2019 Sandia National Laboratories. All rights reserved. +# +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +noinst_LTLIBRARIES = libmca_threads_qthreads.la + +libmca_threads_qthreads_la_SOURCES = \ + threads_qthreads_component.c \ + threads_qthreads_mutex.c \ + threads_qthreads_condition.c \ + threads_qthreads_module.c + +AM_LDFLAGS = -lqthread diff --git a/opal/mca/threads/qthreads/configure.m4 b/opal/mca/threads/qthreads/configure.m4 new file mode 100644 index 00000000000..7248ad4d708 --- /dev/null +++ b/opal/mca/threads/qthreads/configure.m4 @@ -0,0 +1,81 @@ +# -*- shell-script -*- +# +# 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 Research Organization for Information Science +# and Technology (RIST). All rights reserved. +# Copyright (c) 2019 Triad National Security, LLC. All rights +# reserved. +# +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +AC_DEFUN([OPAL_CONFIG_QTHREADS],[ + + AC_CHECK_HEADERS([qthread/qthread.h], + [AC_CHECK_LIB([qthread],[qthread_initialize], + [threads_qthreads_happy="yes"], + [threads_qthreads_happy="no"])], + [threads_qthreads_happy="no"]) + + AS_IF([test "$threads_qthreads_happy" = "yes"], + [$1], + [$2]) +])dnl + +AC_DEFUN([MCA_opal_threads_qthreads_PRIORITY], [30]) + +AC_DEFUN([MCA_opal_threads_qthreads_COMPILE_MODE], [ + AC_MSG_CHECKING([for MCA component $2:$3 compile mode]) + $4="static" + AC_MSG_RESULT([$$4]) +]) + +# If component was selected, $1 will be 1 and we should set the base header +AC_DEFUN([MCA_opal_threads_qthreads_POST_CONFIG],[ + AS_IF([test "$1" = "1"], + [opal_thread_type_found="qthreads" + AC_DEFINE_UNQUOTED([MCA_threads_base_include_HEADER], + ["opal/mca/threads/qthreads/threads_qthreads_threads.h"], + [Header to include for threads implementation]) + AC_DEFINE_UNQUOTED([MCA_threads_mutex_base_include_HEADER], + ["opal/mca/threads/qthreads/threads_qthreads_mutex.h"], + [Header to include for mutex implementation]) + AC_DEFINE_UNQUOTED([MCA_threads_tsd_base_include_HEADER], + ["opal/mca/threads/qthreads/threads_qthreads_tsd.h"], + [Header to include for tsd implementation]) + AC_DEFINE_UNQUOTED([MCA_threads_wait_sync_base_include_HEADER], + ["opal/mca/threads/qthreads/threads_qthreads_wait_sync.h"], + [Header to include for wait_sync implementation]) + ]) +])dnl + + +# MCA_threads_qthreads_CONFIG(action-if-can-compile, +# [action-if-cant-compile]) +# ------------------------------------------------ +AC_DEFUN([MCA_opal_threads_qthreads_CONFIG],[ + AC_CONFIG_FILES([opal/mca/threads/qthreads/Makefile]) + + AS_IF([test "$with_threads" = "qthreads"], + [OPAL_CONFIG_QTHREADS([qthreads_works=1],[qthreads_works=0])], + [qthreads_works=0]) + + AS_IF([test "$qthreads_works" = "1"], + [$1 + opal_thread_type_found="qthreads"], + [$2]) +]) diff --git a/opal/mca/threads/qthreads/owner.txt b/opal/mca/threads/qthreads/owner.txt new file mode 100644 index 00000000000..1cd89be1e87 --- /dev/null +++ b/opal/mca/threads/qthreads/owner.txt @@ -0,0 +1,7 @@ +# +# owner/status file +# owner: institution that is responsible for this package +# status: e.g. active, maintenance, unmaintained +# +owner: SNL +status: active diff --git a/opal/mca/threads/qthreads/threads_qthreads.h b/opal/mca/threads/qthreads/threads_qthreads.h new file mode 100644 index 00000000000..7c654aa84ec --- /dev/null +++ b/opal/mca/threads/qthreads/threads_qthreads.h @@ -0,0 +1,36 @@ +/* -*- 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) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef OPAL_MCA_THREADS_QTHREADS_THREADS_QTHREADS_H +#define OPAL_MCA_THREADS_QTHREADS_THREADS_QTHREADS_H 1 + +#include + +static inline void ensure_init_qthreads(void) +{ + qthread_initialize(); +} + +#endif /* OPAL_MCA_THREADS_QTHREADS_THREADS_QTHREADS_H */ diff --git a/opal/mca/threads/qthreads/threads_qthreads_component.c b/opal/mca/threads/qthreads/threads_qthreads_component.c new file mode 100644 index 00000000000..bae4cc18983 --- /dev/null +++ b/opal/mca/threads/qthreads/threads_qthreads_component.c @@ -0,0 +1,54 @@ +/* -*- 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 + * 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) 2007-2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "opal_config.h" + +#include "opal/mca/threads/thread.h" +#include "opal/mca/threads/threads.h" +#include "opal/constants.h" + +static int opal_threads_qthreads_open(void); + +const opal_threads_base_component_1_0_0_t mca_threads_qthreads_component = { + /* First, the mca_component_t struct containing meta information + * about the component itself */ + .threadsc_version = { + OPAL_THREADS_BASE_VERSION_1_0_0, + + /* Component name and version */ + .mca_component_name = "qthreads", + MCA_BASE_MAKE_VERSION(component, OPAL_MAJOR_VERSION, OPAL_MINOR_VERSION, + OPAL_RELEASE_VERSION), + + .mca_open_component = opal_threads_qthreads_open, + }, + .threadsc_data = { + /* The component is checkpoint ready */ + MCA_BASE_METADATA_PARAM_CHECKPOINT + }, +}; + +int opal_threads_qthreads_open(void) +{ + return OPAL_SUCCESS; +} diff --git a/opal/mca/threads/qthreads/threads_qthreads_condition.c b/opal/mca/threads/qthreads/threads_qthreads_condition.c new file mode 100644 index 00000000000..7c569b3898a --- /dev/null +++ b/opal/mca/threads/qthreads/threads_qthreads_condition.c @@ -0,0 +1,42 @@ +/* -*- 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) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "opal_config.h" + +#include "opal/mca/threads/condition.h" + + +static void opal_condition_construct(opal_condition_t *c) +{ + c->c_waiting = 0; + c->c_signaled = 0; +} + + + +OBJ_CLASS_INSTANCE(opal_condition_t, + opal_object_t, + opal_condition_construct, + NULL); diff --git a/opal/mca/threads/qthreads/threads_qthreads_module.c b/opal/mca/threads/qthreads/threads_qthreads_module.c new file mode 100644 index 00000000000..8f5690cbd80 --- /dev/null +++ b/opal/mca/threads/qthreads/threads_qthreads_module.c @@ -0,0 +1,92 @@ +/* -*- 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) 2019 Triad National Security, LLC. All rights + * reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include + +#include "opal/mca/threads/qthreads/threads_qthreads.h" +#include "opal/constants.h" +#include "opal/util/sys_limits.h" +#include "opal/util/output.h" +#include "opal/prefetch.h" +#include "opal/mca/threads/threads.h" +#include "opal/mca/threads/tsd.h" + +struct opal_tsd_key_value { + opal_tsd_key_t key; + opal_tsd_destructor_t destructor; +}; + +static int opal_main_thread; +struct opal_tsd_key_value *opal_tsd_key_values = NULL; +static int opal_tsd_key_values_count = 0; + +/* + * Constructor + */ +static void opal_thread_construct(opal_thread_t *t) +{ +} + +OBJ_CLASS_INSTANCE(opal_thread_t, + opal_object_t, + opal_thread_construct, NULL); + + +opal_thread_t *opal_thread_get_self(void) +{ + return NULL; +} + +bool opal_thread_self_compare(opal_thread_t *t) +{ + return OPAL_ERR_NOT_IMPLEMENTED; +} + +int sync_wait_mt(void *p) +{ + return OPAL_ERR_NOT_IMPLEMENTED; +} + +int opal_thread_join(opal_thread_t *t, void **thr_return) +{ + return OPAL_ERR_NOT_IMPLEMENTED; +} + +void opal_thread_set_main(void) +{ +} + +int opal_thread_start(opal_thread_t *t) +{ + return OPAL_ERR_NOT_IMPLEMENTED; +} + +OBJ_CLASS_DECLARATION(opal_thread_t); + +int opal_tsd_key_create(opal_tsd_key_t *key, opal_tsd_destructor_t destructor) +{ + return OPAL_ERR_NOT_IMPLEMENTED; +} + +int opal_tsd_keys_destruct(void) +{ + return OPAL_ERR_NOT_IMPLEMENTED; +} diff --git a/opal/threads/mutex.c b/opal/mca/threads/qthreads/threads_qthreads_mutex.c similarity index 55% rename from opal/threads/mutex.c rename to opal/mca/threads/qthreads/threads_qthreads_mutex.c index bdfb8dd8909..ea1065fc089 100644 --- a/opal/threads/mutex.c +++ b/opal/mca/threads/qthreads/threads_qthreads_mutex.c @@ -14,6 +14,8 @@ * reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. + * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. + * * $COPYRIGHT$ * * Additional copyrights may follow @@ -23,7 +25,8 @@ #include "opal_config.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" +#include "opal/constants.h" /* * Wait and see if some upper layer wants to use threads, if support @@ -33,38 +36,10 @@ bool opal_uses_threads = false; static void opal_mutex_construct(opal_mutex_t *m) { -#if OPAL_ENABLE_DEBUG - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - - /* set type to ERRORCHECK so that we catch recursive locks */ -#if OPAL_HAVE_PTHREAD_MUTEX_ERRORCHECK_NP - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP); -#elif OPAL_HAVE_PTHREAD_MUTEX_ERRORCHECK - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); -#endif /* OPAL_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 /* OPAL_ENABLE_DEBUG */ - -#if OPAL_HAVE_ATOMIC_SPINLOCKS - opal_atomic_lock_init( &m->m_lock_atomic, OPAL_ATOMIC_LOCK_UNLOCKED ); -#endif } static void opal_mutex_destruct(opal_mutex_t *m) { - pthread_mutex_destroy(&m->m_lock_pthread); } OBJ_CLASS_INSTANCE(opal_mutex_t, @@ -74,26 +49,43 @@ OBJ_CLASS_INSTANCE(opal_mutex_t, static void opal_recursive_mutex_construct(opal_recursive_mutex_t *m) { - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - -#if OPAL_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 OPAL_HAVE_ATOMIC_SPINLOCKS - opal_atomic_lock_init( &m->m_lock_atomic, OPAL_ATOMIC_LOCK_UNLOCKED ); -#endif } OBJ_CLASS_INSTANCE(opal_recursive_mutex_t, opal_object_t, opal_recursive_mutex_construct, opal_mutex_destruct); + +static void opal_cond_create(opal_cond_t *cond) +{ + ensure_init_qthreads(); +} + +int opal_cond_init(opal_cond_t *cond) +{ + return OPAL_ERR_NOT_IMPLEMENTED; +} + +int opal_cond_wait(opal_cond_t *cond, opal_mutex_t *lock) +{ + ensure_init_qthreads(); + return 0 == qthread_readFE(*cond, &lock->m_lock_qthreads) ? OPAL_SUCCESS + : OPAL_ERROR; +} + +int opal_cond_broadcast(opal_cond_t *cond) +{ + ensure_init_qthreads(); + return 0 == qthread_fill(*cond) ? OPAL_SUCCESS : OPAL_ERROR; +} + +int opal_cond_signal(opal_cond_t *cond) +{ + ensure_init_qthreads(); + return 0 == qthread_fill(*cond) ? OPAL_SUCCESS : OPAL_ERROR; +} + +int opal_cond_destroy(opal_cond_t *cond) +{ + return OPAL_ERR_NOT_IMPLEMENTED; +} diff --git a/opal/mca/threads/qthreads/threads_qthreads_mutex.h b/opal/mca/threads/qthreads/threads_qthreads_mutex.h new file mode 100644 index 00000000000..87affd223e0 --- /dev/null +++ b/opal/mca/threads/qthreads/threads_qthreads_mutex.h @@ -0,0 +1,210 @@ +/* -*- 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-2018 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) 2019 Sandia National Laboratories. All rights reserved. + * Copyright (c) 2020 Triad National Security, LLC. All rights + * reserved. + * + * Copyright (c) 2020 Cisco Systems, Inc. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef OPAL_MCA_THREADS_QTHREADS_THREADS_QTHREADS_MUTEX_H +#define OPAL_MCA_THREADS_QTHREADS_THREADS_QTHREADS_MUTEX_H 1 + +/** + * @file: + * + * Mutual exclusion functions: Unix implementation. + * + * Functions for locking of critical sections. + * + */ + +#include "opal_config.h" + +#include +#include + +#include "opal/mca/threads/qthreads/threads_qthreads.h" +#include "opal/class/opal_object.h" +#include "opal/sys/atomic.h" +#include "opal/util/output.h" + +#include + +BEGIN_C_DECLS + +struct opal_mutex_t { + opal_object_t super; + + aligned_t m_lock_qthreads; + int m_recursive; + +#if OPAL_ENABLE_DEBUG + int m_lock_debug; + const char *m_lock_file; + int m_lock_line; +#endif + + opal_atomic_lock_t m_lock_atomic; +}; + +OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_mutex_t); +OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_recursive_mutex_t); + +#if OPAL_ENABLE_DEBUG +#define OPAL_MUTEX_STATIC_INIT \ + { \ + .super = OPAL_OBJ_STATIC_INIT(opal_mutex_t), \ + .m_lock_qthreads = 0, \ + .m_recursive = 0, \ + .m_lock_debug = 0, \ + .m_lock_file = NULL, \ + .m_lock_line = 0, \ + .m_lock_atomic = OPAL_ATOMIC_LOCK_INIT, \ + } +#else +#define OPAL_MUTEX_STATIC_INIT \ + { \ + .super = OPAL_OBJ_STATIC_INIT(opal_mutex_t), \ + .m_lock_qthreads = 0, \ + .m_recursive = 0, \ + .m_lock_atomic = OPAL_ATOMIC_LOCK_INIT, \ + } +#endif + +#if OPAL_ENABLE_DEBUG +#define OPAL_RECURSIVE_MUTEX_STATIC_INIT \ + { \ + .super = OPAL_OBJ_STATIC_INIT(opal_mutex_t), \ + .m_lock_qthreads = 0, \ + .m_recursive = 1, \ + .m_lock_debug = 0, \ + .m_lock_file = NULL, \ + .m_lock_line = 0, \ + .m_lock_atomic = OPAL_ATOMIC_LOCK_INIT, \ + } +#else +#define OPAL_RECURSIVE_MUTEX_STATIC_INIT \ + { \ + .super = OPAL_OBJ_STATIC_INIT(opal_mutex_t), \ + .m_lock_qthreads = 0, \ + .m_recursive = 1, \ + .m_lock_atomic = OPAL_ATOMIC_LOCK_INIT, \ + } +#endif + +/************************************************************************ + * + * mutex operations (non-atomic versions) + * + ************************************************************************/ + +static inline void opal_mutex_create(struct opal_mutex_t *m) +{ +} + +static inline int opal_mutex_trylock(opal_mutex_t *m) +{ + ensure_init_qthreads(); + + return 0 == qthread_readFE_nb(NULL, &m->m_lock_qthreads) ? OPAL_SUCCESS + : OPAL_ERROR; +} + +static inline void opal_mutex_lock(opal_mutex_t *m) +{ + ensure_init_qthreads(); + + qthread_lock(&m->m_lock_qthreads); +} + +static inline void opal_mutex_unlock(opal_mutex_t *m) +{ + ensure_init_qthreads(); + + qthread_unlock(&m->m_lock_qthreads); + /* For fairness of locking. */ + qthread_yield(); +} + +/************************************************************************ + * + * mutex operations (atomic versions) + * + ************************************************************************/ + +#if OPAL_HAVE_ATOMIC_SPINLOCKS + +/************************************************************************ + * Spin Locks + ************************************************************************/ + +static inline int opal_mutex_atomic_trylock(opal_mutex_t *m) +{ + return opal_atomic_trylock(&m->m_lock_atomic); +} + +static inline void opal_mutex_atomic_lock(opal_mutex_t *m) +{ + opal_atomic_lock(&m->m_lock_atomic); +} + +static inline void opal_mutex_atomic_unlock(opal_mutex_t *m) +{ + opal_atomic_unlock(&m->m_lock_atomic); +} + +#else + +/************************************************************************ + * Standard locking + ************************************************************************/ + +static inline int opal_mutex_atomic_trylock(opal_mutex_t *m) +{ + return opal_mutex_trylock(m); +} + +static inline void opal_mutex_atomic_lock(opal_mutex_t *m) +{ + opal_mutex_lock(m); +} + +static inline void opal_mutex_atomic_unlock(opal_mutex_t *m) +{ + opal_mutex_unlock(m); +} + +#endif + +typedef aligned_t *opal_cond_t; +#define OPAL_CONDITION_STATIC_INIT 0 + +int opal_cond_init(opal_cond_t *cond); +int opal_cond_wait(opal_cond_t *cond, opal_mutex_t *lock); +int opal_cond_broadcast(opal_cond_t *cond); +int opal_cond_signal(opal_cond_t *cond); +int opal_cond_destroy(opal_cond_t *cond); + +END_C_DECLS + +#endif /* OPAL_MCA_THREADS_QTHREADS_THREADS_QTHREADS_MUTEX_H */ diff --git a/opal/mca/threads/qthreads/threads_qthreads_threads.h b/opal/mca/threads/qthreads/threads_qthreads_threads.h new file mode 100644 index 00000000000..9226c5df1a6 --- /dev/null +++ b/opal/mca/threads/qthreads/threads_qthreads_threads.h @@ -0,0 +1,40 @@ +/* -*- 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) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef OPAL_MCA_THREADS_QTHREADS_THREADS_QTHREADS_THREADS_H +#define OPAL_MCA_THREADS_QTHREADS_THREADS_QTHREADS_THREADS_H 1 + +#include +#include + +struct opal_thread_t { + opal_object_t super; + opal_thread_fn_t t_run; + void *t_arg; + unsigned *t_handle; + void *t_ret; +}; + +#endif /* OPAL_MCA_THREADS_QTHREADS_THREADS_QTHREADS_THREADS_H */ diff --git a/opal/mca/threads/qthreads/threads_qthreads_tsd.h b/opal/mca/threads/qthreads/threads_qthreads_tsd.h new file mode 100644 index 00000000000..8a12d92681c --- /dev/null +++ b/opal/mca/threads/qthreads/threads_qthreads_tsd.h @@ -0,0 +1,52 @@ +/* -*- 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) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + + +#ifndef OPAL_MCA_THREADS_QTHREADS_THREADS_QTHREADS_TSD_H +#define OPAL_MCA_THREADS_QTHREADS_THREADS_QTHREADS_TSD_H 1 + +#include "opal/mca/threads/qthreads/threads_qthreads.h" +#include +#include + +typedef qthread_key_t opal_tsd_key_t; + +static inline int opal_tsd_key_delete(opal_tsd_key_t key) +{ + return 0 == qthread_key_delete(&key) ? OPAL_SUCCESS : OPAL_ERROR; +} + +static inline int opal_tsd_setspecific(opal_tsd_key_t key, void *value) +{ + return 0 == qthread_setspecific(key, value) ? OPAL_SUCCESS : OPAL_ERROR; +} + +static inline int opal_tsd_getspecific(opal_tsd_key_t key, void **valuep) +{ + qthread_getspecific(key); + return OPAL_SUCCESS; +} + +#endif /* OPAL_MCA_THREADS_QTHREADS_THREADS_QTHREADS_TSD_H */ diff --git a/opal/mca/threads/qthreads/threads_qthreads_wait_sync.h b/opal/mca/threads/qthreads/threads_qthreads_wait_sync.h new file mode 100644 index 00000000000..e23ad4fb947 --- /dev/null +++ b/opal/mca/threads/qthreads/threads_qthreads_wait_sync.h @@ -0,0 +1,66 @@ +/* -*- 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) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + + +#ifndef OPAL_MCA_THREADS_QTHREADS_THREADS_QTHREADS_WAIT_SYNC_H +#define OPAL_MCA_THREADS_QTHREADS_THREADS_QTHREADS_WAIT_SYNC_H 1 + +#include "opal/mca/threads/qthreads/threads_qthreads.h" +#include + +typedef struct ompi_wait_sync_t { + opal_atomic_int32_t count; + int32_t status; + ABT_cond condition; + ABT_mutex lock; + struct ompi_wait_sync_t *next; + struct ompi_wait_sync_t *prev; + volatile bool signaling; +} ompi_wait_sync_t; + +#define SYNC_WAIT(sync) (opal_using_threads() ? ompi_sync_wait_mt (sync) : sync_wait_st (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 WAIT_SYNC_RELEASE(sync) do { } while (0) +#define WAIT_SYNC_RELEASE_NOWAIT(sync) do { } while (0) +#define WAIT_SYNC_SIGNAL(sync) do { } while (0) +#define WAIT_SYNC_SIGNALLED(sync) do { } while (0) + +OPAL_DECLSPEC int ompi_sync_wait_mt(ompi_wait_sync_t *sync); +static inline int sync_wait_st (ompi_wait_sync_t *sync) +{ + return sync->status; +} + +#define WAIT_SYNC_INIT(sync,c) do { } while (0) + +#endif /* OPAL_MCA_THREADS_QTHREADS_THREADS_QTHREADS_WAIT_SYNC_H */ diff --git a/opal/mca/threads/thread.h b/opal/mca/threads/thread.h new file mode 100644 index 00000000000..9be62eddb96 --- /dev/null +++ b/opal/mca/threads/thread.h @@ -0,0 +1,55 @@ +/* -*- 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) 2015 Los Alamos National Security, LLC. All rights + * reserved. + * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + + +#ifndef OPAL_MCA_THREADS_THREAD_H +#define OPAL_MCA_THREADS_THREAD_H + +#include "opal_config.h" + +#include "opal/mca/mca.h" +#include "opal/mca/base/base.h" + + +/** + * Structure for threads components. + */ +struct opal_threads_base_component_1_0_0_t { + /** MCA base component */ + mca_base_component_t threadsc_version; + /** MCA base data */ + mca_base_component_data_t threadsc_data; +}; +/** + * Convenience typedef + */ +typedef struct opal_threads_base_component_1_0_0_t + opal_threads_base_component_1_0_0_t; + +/* + * Macro for use in components that are of type threads + */ +#define OPAL_THREADS_BASE_VERSION_1_0_0 \ + OPAL_MCA_BASE_VERSION_2_1_0("threads", 1, 0, 0) + +#endif /* OPAL_MCA_THREADS_THREAD_H */ diff --git a/opal/threads/thread_usage.h b/opal/mca/threads/thread_usage.h similarity index 77% rename from opal/threads/thread_usage.h rename to opal/mca/threads/thread_usage.h index 8ce65362c1c..34a8c9f717f 100644 --- a/opal/threads/thread_usage.h +++ b/opal/mca/threads/thread_usage.h @@ -6,7 +6,7 @@ * Copyright (c) 2004-2007 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. - * Copyright (c) 2004-2006 High Performance Computing Center Stuttgart, + * Copyright (c) 2004-2006 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. @@ -15,15 +15,17 @@ * and Technology (RIST). All rights reserved. * Copyright (c) 2015-2018 Los Alamos National Security, LLC. All rights * reserved. + * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. + * * $COPYRIGHT$ - * + * * Additional copyrights may follow - * + * * $HEADER$ */ -#if !defined(OPAL_THREAD_USAGE_H) -#define OPAL_THREAD_USAGE_H +#ifndef OPAL_MCA_THREADS_THREAD_USAGE_H +#define OPAL_MCA_THREADS_THREAD_USAGE_H #include "opal_config.h" @@ -63,7 +65,7 @@ OPAL_DECLSPEC extern bool opal_uses_threads; * possibility that we may have multiple threads, true will be * returned. */ -#define opal_using_threads() opal_uses_threads +#define opal_using_threads() opal_uses_threads /** * Set whether the process is using multiple threads or not. @@ -78,7 +80,7 @@ OPAL_DECLSPEC extern bool opal_uses_threads; * opal_using_threads(). If configure detected that we have thread * support, the return value of future invocations of * opal_using_threads() will be the parameter's value. If configure - * detected that we have no thread support, then the retuen from + * detected that we have no thread support, then the return from * opal_using_threads() will always be false. */ static inline bool opal_set_using_threads(bool have) @@ -93,56 +95,62 @@ static inline bool opal_set_using_threads(bool have) * indicates that threads are in use by the application or library. */ -#define OPAL_THREAD_DEFINE_ATOMIC_OP(type, name, operator, suffix) \ -static inline type opal_thread_ ## name ## _fetch_ ## suffix (opal_atomic_ ## type *addr, type delta) \ -{ \ - if (OPAL_UNLIKELY(opal_using_threads())) { \ - return opal_atomic_ ## name ## _fetch_ ## suffix (addr, delta); \ - } \ - \ - *addr = *addr operator delta; \ - return *addr; \ -} \ - \ -static inline type opal_thread_fetch_ ## name ## _ ## suffix (opal_atomic_ ## type *addr, type delta) \ -{ \ - if (OPAL_UNLIKELY(opal_using_threads())) { \ - return opal_atomic_fetch_ ## name ## _ ## suffix (addr, delta); \ - } \ - \ - type old = *addr; \ - *addr = old operator delta; \ - return old; \ +#define OPAL_THREAD_DEFINE_ATOMIC_OP(type, name, operator, suffix) \ +static inline type opal_thread_ ## name ## _fetch_ ## suffix \ + (opal_atomic_ ## type *addr, type delta) \ +{ \ + if (OPAL_UNLIKELY(opal_using_threads())) { \ + return opal_atomic_ ## name ## _fetch_ ## suffix (addr, delta); \ + } \ + \ + *addr = *addr operator delta; \ + return *addr; \ +} \ + \ +static inline type opal_thread_fetch_ ## name ## _ ## suffix \ + (opal_atomic_ ## type *addr, type delta) \ +{ \ + if (OPAL_UNLIKELY(opal_using_threads())) { \ + return opal_atomic_fetch_ ## name ## _ ## suffix (addr, delta); \ + } \ + \ + type old = *addr; \ + *addr = old operator delta; \ + return old; \ } -#define OPAL_THREAD_DEFINE_ATOMIC_COMPARE_EXCHANGE(type, addr_type, suffix) \ -static inline bool opal_thread_compare_exchange_strong_ ## suffix (opal_atomic_ ## addr_type *addr, type *compare, type value) \ -{ \ - if (OPAL_UNLIKELY(opal_using_threads())) { \ - return opal_atomic_compare_exchange_strong_ ## suffix (addr, (addr_type *) compare, (addr_type) value); \ - } \ - \ - if ((type) *addr == *compare) { \ - ((type *) addr)[0] = value; \ - return true; \ - } \ - \ - *compare = ((type *) addr)[0]; \ - \ - return false; \ +#define OPAL_THREAD_DEFINE_ATOMIC_COMPARE_EXCHANGE(type, addr_type, suffix) \ +static inline bool opal_thread_compare_exchange_strong_ ## suffix \ + (opal_atomic_ ## addr_type *addr, type *compare, type value) \ +{ \ + if (OPAL_UNLIKELY(opal_using_threads())) { \ + return opal_atomic_compare_exchange_strong_ ## suffix \ + (addr, (addr_type *)compare, (addr_type)value); \ + } \ + \ + if ((type) *addr == *compare) { \ + ((type *)addr)[0] = value; \ + return true; \ + } \ + \ + *compare = ((type *)addr)[0]; \ + \ + return false; \ } -#define OPAL_THREAD_DEFINE_ATOMIC_SWAP(type, addr_type, suffix) \ -static inline type opal_thread_swap_ ## suffix (opal_atomic_ ## addr_type *ptr, type newvalue) \ -{ \ - if (opal_using_threads ()) { \ - return (type) opal_atomic_swap_ ## suffix (ptr, (addr_type) newvalue); \ - } \ - \ - type old = ((type *) ptr)[0]; \ - ((type *) ptr)[0] = newvalue; \ - \ - return old; \ +#define OPAL_THREAD_DEFINE_ATOMIC_SWAP(type, addr_type, suffix) \ +static inline type opal_thread_swap_ ## suffix \ + (opal_atomic_ ## addr_type *ptr, type newvalue) \ +{ \ + if (opal_using_threads ()) { \ + return (type) opal_atomic_swap_ ## suffix \ + (ptr, (addr_type) newvalue); \ + } \ + \ + type old = ((type *)ptr)[0]; \ + ((type *)ptr)[0] = newvalue; \ + \ + return old; \ } OPAL_THREAD_DEFINE_ATOMIC_OP(int32_t, add, +, 32) @@ -194,16 +202,22 @@ OPAL_THREAD_DEFINE_ATOMIC_SWAP(intptr_t, intptr_t, ptr) #define OPAL_THREAD_FETCH_SUB_SIZE_T opal_thread_fetch_sub_size_t #define OPAL_ATOMIC_FETCH_SUB_SIZE_T opal_thread_fetch_sub_size_t -#define OPAL_THREAD_COMPARE_EXCHANGE_STRONG_32 opal_thread_compare_exchange_strong_32 -#define OPAL_ATOMIC_COMPARE_EXCHANGE_STRONG_32 opal_thread_compare_exchange_strong_32 +#define OPAL_THREAD_COMPARE_EXCHANGE_STRONG_32 \ + opal_thread_compare_exchange_strong_32 +#define OPAL_ATOMIC_COMPARE_EXCHANGE_STRONG_32 \ + opal_thread_compare_exchange_strong_32 -#define OPAL_THREAD_COMPARE_EXCHANGE_STRONG_PTR(x, y, z) opal_thread_compare_exchange_strong_ptr ((opal_atomic_intptr_t *) x, (intptr_t *) y, (intptr_t) z) -#define OPAL_ATOMIC_COMPARE_EXCHANGE_STRONG_PTR OPAL_THREAD_COMPARE_EXCHANGE_STRONG_PTR +#define OPAL_THREAD_COMPARE_EXCHANGE_STRONG_PTR(x, y, z) \ + opal_thread_compare_exchange_strong_ptr ((opal_atomic_intptr_t *) x, \ + (intptr_t *) y, (intptr_t) z) +#define OPAL_ATOMIC_COMPARE_EXCHANGE_STRONG_PTR \ + OPAL_THREAD_COMPARE_EXCHANGE_STRONG_PTR #define OPAL_THREAD_SWAP_32 opal_thread_swap_32 #define OPAL_ATOMIC_SWAP_32 opal_thread_swap_32 -#define OPAL_THREAD_SWAP_PTR(x, y) opal_thread_swap_ptr ((opal_atomic_intptr_t *) x, (intptr_t) y) +#define OPAL_THREAD_SWAP_PTR(x, y) \ + opal_thread_swap_ptr ((opal_atomic_intptr_t *) x, (intptr_t) y) #define OPAL_ATOMIC_SWAP_PTR OPAL_THREAD_SWAP_PTR /* define 64-bit macros is 64-bit atomic math is available */ @@ -241,8 +255,10 @@ OPAL_THREAD_DEFINE_ATOMIC_SWAP(int64_t, int64_t, 64) #define OPAL_THREAD_FETCH_XOR64 opal_thread_fetch_xor_64 #define OPAL_ATOMIC_FETCH_XOR64 opal_thread_fetch_xor_64 -#define OPAL_THREAD_COMPARE_EXCHANGE_STRONG_64 opal_thread_compare_exchange_strong_64 -#define OPAL_ATOMIC_COMPARE_EXCHANGE_STRONG_64 opal_thread_compare_exchange_strong_64 +#define OPAL_THREAD_COMPARE_EXCHANGE_STRONG_64 \ + opal_thread_compare_exchange_strong_64 +#define OPAL_ATOMIC_COMPARE_EXCHANGE_STRONG_64 \ + opal_thread_compare_exchange_strong_64 #define OPAL_THREAD_SWAP_64 opal_thread_swap_64 #define OPAL_ATOMIC_SWAP_64 opal_thread_swap_64 @@ -263,4 +279,4 @@ OPAL_THREAD_DEFINE_ATOMIC_SWAP(int64_t, int64_t, 64) #define OPAL_HAVE_THREAD_LOCAL 0 #endif /* !defined(OPAL_HAVE_THREAD_LOCAL) */ -#endif /* !defined(OPAL_THREAD_USAGE_H) */ +#endif /* OPAL_MCA_THREADS_THREAD_USAGE_H */ diff --git a/opal/threads/threads.h b/opal/mca/threads/threads.h similarity index 87% rename from opal/threads/threads.h rename to opal/mca/threads/threads.h index 661d6b00ee0..bcbfa88197d 100644 --- a/opal/threads/threads.h +++ b/opal/mca/threads/threads.h @@ -1,3 +1,4 @@ +/* -*- 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 @@ -14,6 +15,8 @@ * Copyright (c) 2015-2017 Research Organization for Information Science * and Technology (RIST). All rights reserved. * Copyright (c) 2017 Intel, Inc. All rights reserved. + * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. + * * $COPYRIGHT$ * * Additional copyrights may follow @@ -21,14 +24,11 @@ * $HEADER$ */ -#ifndef OPAL_THREAD_H -#define OPAL_THREAD_H 1 +#ifndef OPAL_MCA_THREADS_THREADS_H +#define OPAL_MCA_THREADS_THREADS_H #include "opal_config.h" -#include -#include - #include "opal/class/opal_object.h" #if OPAL_ENABLE_DEBUG #include "opal/util/output.h" @@ -39,19 +39,16 @@ BEGIN_C_DECLS -typedef void *(*opal_thread_fn_t) (opal_object_t *); +typedef void *(*opal_thread_fn_t)(opal_object_t *); -#define OPAL_THREAD_CANCELLED ((void*)1); +#define OPAL_THREAD_CANCELLED ((void *)1); -struct opal_thread_t { - opal_object_t super; - opal_thread_fn_t t_run; - void* t_arg; - pthread_t t_handle; -}; +#include MCA_threads_base_include_HEADER typedef struct opal_thread_t opal_thread_t; +OBJ_CLASS_DECLARATION(opal_thread_t); + #if OPAL_ENABLE_DEBUG OPAL_DECLSPEC extern bool opal_debug_threads; #endif @@ -75,7 +72,7 @@ OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_thread_t); __FILE__, __LINE__); \ } \ *(act) = true; \ - } while(0); + } while (0); #else #define OPAL_ACQUIRE_THREAD(lck, cnd, act) \ do { \ @@ -84,7 +81,7 @@ OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_thread_t); opal_condition_wait((cnd), (lck)); \ } \ *(act) = true; \ - } while(0); + } while (0); #endif @@ -98,14 +95,14 @@ OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_thread_t); *(act) = false; \ opal_condition_broadcast((cnd)); \ OPAL_THREAD_UNLOCK((lck)); \ - } while(0); + } while (0); #else #define OPAL_RELEASE_THREAD(lck, cnd, act) \ do { \ *(act) = false; \ opal_condition_broadcast((cnd)); \ OPAL_THREAD_UNLOCK((lck)); \ - } while(0); + } while (0); #endif @@ -113,7 +110,7 @@ OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_thread_t); do { \ *(act) = false; \ opal_condition_broadcast((cnd)); \ - } while(0); + } while (0); /* provide a macro for forward-proofing the shifting * of objects between libevent threads - at some point, we @@ -131,11 +128,12 @@ OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_thread_t); OPAL_DECLSPEC int opal_thread_start(opal_thread_t *); OPAL_DECLSPEC int opal_thread_join(opal_thread_t *, void **thread_return); -OPAL_DECLSPEC bool opal_thread_self_compare(opal_thread_t*); +OPAL_DECLSPEC bool opal_thread_self_compare(opal_thread_t *); OPAL_DECLSPEC opal_thread_t *opal_thread_get_self(void); OPAL_DECLSPEC void opal_thread_kill(opal_thread_t *, int sig); OPAL_DECLSPEC void opal_thread_set_main(void); +OPAL_DECLSPEC void opal_event_use_threads(void); END_C_DECLS -#endif /* OPAL_THREAD_H */ +#endif /* OPAL_MCA_THREADS_THREADS_H */ diff --git a/opal/threads/tsd.h b/opal/mca/threads/tsd.h similarity index 75% rename from opal/threads/tsd.h rename to opal/mca/threads/tsd.h index e49c08dd96e..da3ab09e254 100644 --- a/opal/threads/tsd.h +++ b/opal/mca/threads/tsd.h @@ -1,9 +1,12 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* * 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) 2019 Sandia National Laboratories. All rights reserved. + * * $COPYRIGHT$ * * Additional copyrights may follow @@ -12,8 +15,8 @@ */ -#ifndef OPAL_THREADS_TSD_H -#define OPAL_THREADS_TSD_H +#ifndef OPAL_MCA_THREADS_TSD_H +#define OPAL_MCA_THREADS_TSD_H #include "opal_config.h" @@ -42,7 +45,7 @@ typedef void (*opal_tsd_destructor_t)(void *value); /** * Typedef for thread-specific data key */ -typedef void* opal_tsd_key_t; +typedef void *opal_tsd_key_t; /** @@ -59,8 +62,9 @@ typedef void* opal_tsd_key_t; * * @param key[in] The key for accessing thread-specific data * - * @retval OPAL_SUCCESS Success - * @retval EINVAL Invalid key + * @retval OPAL_SUCCESS Success + * @retval OPAL_ERROR Error + * @retval OPAL_ERR_IN_ERRNO Error */ OPAL_DECLSPEC int opal_tsd_key_delete(opal_tsd_key_t key); @@ -78,10 +82,9 @@ OPAL_DECLSPEC int opal_tsd_key_delete(opal_tsd_key_t key); * @param key[in] Thread specific data key to modify * @param value[in] Value to associate with key * - * @retval OPAL_SUCCESS Success - * @retval ENOMEM Insufficient memory exists to associate the - * value with the key - * @retval EINVAL Invalid key + * @retval OPAL_SUCCESS Success + * @retval OPAL_ERR Error + * @retval OPAL_ERR_IN_ERRNO Error */ OPAL_DECLSPEC int opal_tsd_setspecific(opal_tsd_key_t key, void *value); @@ -94,38 +97,18 @@ OPAL_DECLSPEC int opal_tsd_setspecific(opal_tsd_key_t key, void *value); * called in the current thread with the given key, NULL is returned * in valuep. * - * @param key[in] Thread specific data key to modify + * @param key[in] Thread specific data key to modify * @param value[out] Value to associate with key * - * @retval OPAL_SUCCESS Success - * @retval ENOMEM Insufficient memory exists to associate the - * value with the key - * @retval EINVAL Invalid key + * @retval OPAL_SUCCESS Success + * @retval OPAL_ERR Error + * @retval OPAL_ERR_IN_ERRNO Error */ OPAL_DECLSPEC int opal_tsd_getspecific(opal_tsd_key_t key, void **valuep); #else -typedef pthread_key_t opal_tsd_key_t; - -static inline int -opal_tsd_key_delete(opal_tsd_key_t key) -{ - return pthread_key_delete(key); -} - -static inline int -opal_tsd_setspecific(opal_tsd_key_t key, void *value) -{ - return pthread_setspecific(key, value); -} - -static inline int -opal_tsd_getspecific(opal_tsd_key_t key, void **valuep) -{ - *valuep = pthread_getspecific(key); - return OPAL_SUCCESS; -} +#include MCA_threads_tsd_base_include_HEADER #endif @@ -150,10 +133,9 @@ opal_tsd_getspecific(opal_tsd_key_t key, void **valuep) * @param key[out] The key for accessing thread-specific data * @param destructor[in] Cleanup function to call when a thread exits * - * @retval OPAL_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 + * @retval OPAL_SUCCESS Success + * @retval OPAL_ERR Error + * @retval OPAL_ERR_IN_ERRNO Error */ OPAL_DECLSPEC int opal_tsd_key_create(opal_tsd_key_t *key, opal_tsd_destructor_t destructor); @@ -175,4 +157,4 @@ OPAL_DECLSPEC int opal_tsd_keys_destruct(void); END_C_DECLS -#endif /* OPAL_MTHREADS_TSD_H */ +#endif /* OPAL_MCA_THREADS_TSD_H */ diff --git a/opal/mca/threads/wait_sync.h b/opal/mca/threads/wait_sync.h new file mode 100644 index 00000000000..c600a3d0e95 --- /dev/null +++ b/opal/mca/threads/wait_sync.h @@ -0,0 +1,60 @@ +/* -*- 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 IBM Corporation. All rights reserved. + * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. + * + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef OPAL_MCA_THREADS_WAIT_SYNC_H +#define OPAL_MCA_THREADS_WAIT_SYNC_H + +#include "opal/sys/atomic.h" +#include "opal/mca/threads/condition.h" + +BEGIN_C_DECLS + +extern int opal_max_thread_in_progress; + +#include MCA_threads_wait_sync_base_include_HEADER + +#define REQUEST_PENDING (void *)0L +#define REQUEST_COMPLETED (void *)1L + +/** + * 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 wait_sync_update(ompi_wait_sync_t *sync, int updates, + int status) +{ + if (OPAL_LIKELY(OPAL_SUCCESS == status)) { + if (0 != (OPAL_THREAD_ADD_FETCH32(&sync->count, -updates))) { + return; + } + } else { + /* this is an error path so just use the atomic */ + sync->status = OPAL_ERROR; + opal_atomic_wmb(); + opal_atomic_swap_32(&sync->count, 0); + } + WAIT_SYNC_SIGNAL(sync); +} + +END_C_DECLS + +#endif /* OPAL_MCA_THREADS_WAIT_SYNC_H */ diff --git a/opal/mca/timer/linux/timer_linux_component.c b/opal/mca/timer/linux/timer_linux_component.c index 15d1cbec263..a969dabc632 100644 --- a/opal/mca/timer/linux/timer_linux_component.c +++ b/opal/mca/timer/linux/timer_linux_component.c @@ -26,6 +26,7 @@ #include "opal_config.h" #include +#include #include "opal/mca/timer/timer.h" #include "opal/mca/timer/base/base.h" diff --git a/opal/runtime/opal_cr.c b/opal/runtime/opal_cr.c index 11f938edd98..33b94434b8e 100644 --- a/opal/runtime/opal_cr.c +++ b/opal/runtime/opal_cr.c @@ -69,8 +69,8 @@ #include "opal/mca/memory/base/base.h" #include "opal/mca/timer/base/base.h" -#include "opal/threads/mutex.h" -#include "opal/threads/threads.h" +#include "opal/mca/threads/mutex.h" +#include "opal/mca/threads/threads.h" #include "opal/mca/crs/base/base.h" /****************** diff --git a/opal/runtime/opal_finalize.c b/opal/runtime/opal_finalize.c index 7c7e37c310a..33138b453a6 100644 --- a/opal/runtime/opal_finalize.c +++ b/opal/runtime/opal_finalize.c @@ -39,7 +39,7 @@ #include "opal/memoryhooks/memory.h" #include "opal/runtime/opal.h" #include "opal/constants.h" -#include "opal/threads/tsd.h" +#include "opal/mca/threads/tsd.h" #include "opal/runtime/opal_cr.h" #include "opal/runtime/opal_progress.h" diff --git a/opal/runtime/opal_init.c b/opal/runtime/opal_init.c index ab17e8e9bb7..bfdf37b5448 100644 --- a/opal/runtime/opal_init.c +++ b/opal/runtime/opal_init.c @@ -62,14 +62,15 @@ #include "opal/mca/if/base/base.h" #include "opal/dss/dss.h" #include "opal/mca/shmem/base/base.h" -#include "opal/threads/threads.h" -#include "opal/threads/tsd.h" +#include "opal/mca/threads/threads.h" +#include "opal/mca/threads/tsd.h" #include "opal/runtime/opal_cr.h" #include "opal/mca/crs/base/base.h" #include "opal/runtime/opal_progress.h" #include "opal/mca/event/base/base.h" +#include "opal/mca/threads/base/base.h" #include "opal/mca/backtrace/base/base.h" #include "opal/constants.h" @@ -628,7 +629,7 @@ opal_init_util(int* pargc, char*** pargv) * versions of memcpy correctly configured. */ static mca_base_framework_t *opal_init_frameworks[] = { - &opal_hwloc_base_framework, &opal_memcpy_base_framework, &opal_memchecker_base_framework, + &opal_threads_base_framework, &opal_hwloc_base_framework, &opal_memcpy_base_framework, &opal_memchecker_base_framework, &opal_backtrace_base_framework, &opal_timer_base_framework, &opal_event_base_framework, &opal_shmem_base_framework, &opal_reachable_base_framework, NULL, diff --git a/opal/runtime/opal_params.c b/opal/runtime/opal_params.c index 2897b64737f..b1e2e74c06d 100644 --- a/opal/runtime/opal_params.c +++ b/opal/runtime/opal_params.c @@ -39,8 +39,8 @@ #include "opal/runtime/opal.h" #include "opal/datatype/opal_datatype.h" #include "opal/mca/base/mca_base_var.h" -#include "opal/threads/mutex.h" -#include "opal/threads/threads.h" +#include "opal/mca/threads/mutex.h" +#include "opal/mca/threads/threads.h" #include "opal/mca/shmem/base/base.h" #include "opal/mca/base/mca_base_var.h" #include "opal/runtime/opal_params.h" diff --git a/opal/runtime/opal_progress.h b/opal/runtime/opal_progress.h index 1d25905569d..13bb9ead954 100644 --- a/opal/runtime/opal_progress.h +++ b/opal/runtime/opal_progress.h @@ -33,7 +33,7 @@ BEGIN_C_DECLS #include "opal_config.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/runtime/opal.h" /** diff --git a/opal/runtime/opal_progress_threads.c b/opal/runtime/opal_progress_threads.c index 4c53fa35b67..a675405dc53 100644 --- a/opal/runtime/opal_progress_threads.c +++ b/opal/runtime/opal_progress_threads.c @@ -17,7 +17,7 @@ #include "opal/class/opal_list.h" #include "opal/mca/event/event.h" -#include "opal/threads/threads.h" +#include "opal/mca/threads/threads.h" #include "opal/util/error.h" #include "opal/util/fd.h" diff --git a/opal/threads/Makefile.am b/opal/threads/Makefile.am deleted file mode 100644 index a4a084038ca..00000000000 --- a/opal/threads/Makefile.am +++ /dev/null @@ -1,39 +0,0 @@ -# -*- 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$ -# -# Additional copyrights may follow -# -# $HEADER$ -# - -# This makefile.am does not stand on its own - it is included from opal/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 - -lib@OPAL_LIB_PREFIX@open_pal_la_SOURCES += \ - threads/condition.c \ - threads/mutex.c \ - threads/thread.c \ - threads/wait_sync.c diff --git a/opal/util/cmd_line.c b/opal/util/cmd_line.c index bce8e7ad17f..ce901a66ff7 100644 --- a/opal/util/cmd_line.c +++ b/opal/util/cmd_line.c @@ -32,7 +32,7 @@ #include "opal/class/opal_object.h" #include "opal/class/opal_list.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/util/argv.h" #include "opal/util/cmd_line.h" #include "opal/util/output.h" diff --git a/opal/util/cmd_line.h b/opal/util/cmd_line.h index 546e49200b9..9c49bc25360 100644 --- a/opal/util/cmd_line.h +++ b/opal/util/cmd_line.h @@ -120,7 +120,7 @@ #include "opal/class/opal_object.h" #include "opal/class/opal_list.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" BEGIN_C_DECLS /** diff --git a/opal/util/info.h b/opal/util/info.h index 8f8cc686686..bbab7c35ab9 100644 --- a/opal/util/info.h +++ b/opal/util/info.h @@ -29,7 +29,7 @@ #include "opal/class/opal_list.h" #include "opal/class/opal_pointer_array.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/mca/base/mca_base_var_enum.h" /** diff --git a/opal/util/info_subscriber.h b/opal/util/info_subscriber.h index c676ab0338e..c7ce58f95d7 100644 --- a/opal/util/info_subscriber.h +++ b/opal/util/info_subscriber.h @@ -30,7 +30,7 @@ #include "opal/class/opal_list.h" #include "opal/class/opal_pointer_array.h" #include "opal/class/opal_hash_table.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/util/info.h" #include "opal/mca/base/mca_base_var_enum.h" diff --git a/opal/util/keyval_parse.c b/opal/util/keyval_parse.c index 212773f0e43..fe947131b63 100644 --- a/opal/util/keyval_parse.c +++ b/opal/util/keyval_parse.c @@ -29,7 +29,7 @@ #include "opal/util/keyval/keyval_lex.h" #include "opal/util/output.h" #include "opal/util/string_copy.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include #include diff --git a/opal/util/net.c b/opal/util/net.c index 2ec734aee0b..3f14d524b89 100644 --- a/opal/util/net.c +++ b/opal/util/net.c @@ -69,7 +69,7 @@ #include "opal/util/argv.h" #include "opal/util/show_help.h" #include "opal/constants.h" -#include "opal/threads/tsd.h" +#include "opal/mca/threads/tsd.h" #include "opal/runtime/opal_params.h" /* this function doesn't depend on sockaddr_h */ diff --git a/opal/util/output.c b/opal/util/output.c index 9b6ddbeb3cb..b09c21c87cd 100644 --- a/opal/util/output.c +++ b/opal/util/output.c @@ -51,7 +51,7 @@ #include "opal/util/output.h" #include "opal/util/string_copy.h" #include "opal/util/printf.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/constants.h" #include "opal/mca/pmix/pmix-internal.h" diff --git a/oshmem/mca/memheap/buddy/memheap_buddy.h b/oshmem/mca/memheap/buddy/memheap_buddy.h index ab7e16b4b3c..246e598453f 100644 --- a/oshmem/mca/memheap/buddy/memheap_buddy.h +++ b/oshmem/mca/memheap/buddy/memheap_buddy.h @@ -17,7 +17,7 @@ #include "oshmem_config.h" #include "oshmem/mca/mca.h" #include "opal/class/opal_list.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "oshmem/mca/memheap/memheap.h" #include "oshmem/mca/memheap/base/base.h" #include "oshmem/mca/spml/spml.h" diff --git a/oshmem/mca/memheap/ptmalloc/memheap_ptmalloc.h b/oshmem/mca/memheap/ptmalloc/memheap_ptmalloc.h index dba1ed55f7d..9f1a95959a8 100644 --- a/oshmem/mca/memheap/ptmalloc/memheap_ptmalloc.h +++ b/oshmem/mca/memheap/ptmalloc/memheap_ptmalloc.h @@ -17,7 +17,7 @@ #include "oshmem_config.h" #include "oshmem/mca/mca.h" #include "opal/class/opal_list.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "oshmem/mca/memheap/memheap.h" #include "oshmem/mca/memheap/base/base.h" #include "oshmem/mca/spml/spml.h" diff --git a/oshmem/proc/proc.c b/oshmem/proc/proc.c index 92c60d97149..da84e4d9c8b 100644 --- a/oshmem/proc/proc.c +++ b/oshmem/proc/proc.c @@ -24,7 +24,7 @@ #endif #include "opal/datatype/opal_convertor.h" -#include "opal/threads/mutex.h" +#include "opal/mca/threads/mutex.h" #include "opal/dss/dss.h" #include "opal/util/arch.h" #include "opal/class/opal_list.h" diff --git a/oshmem/request/request.h b/oshmem/request/request.h index 8d90bd922cf..97c6c2630ee 100644 --- a/oshmem/request/request.h +++ b/oshmem/request/request.h @@ -24,7 +24,7 @@ #include "opal/class/opal_free_list.h" #include "opal/class/opal_pointer_array.h" -#include "opal/threads/condition.h" +#include "opal/mca/threads/condition.h" BEGIN_C_DECLS diff --git a/oshmem/runtime/oshmem_shmem_init.c b/oshmem/runtime/oshmem_shmem_init.c index 75b4007b565..355d0995b05 100644 --- a/oshmem/runtime/oshmem_shmem_init.c +++ b/oshmem/runtime/oshmem_shmem_init.c @@ -27,7 +27,7 @@ #include "opal/class/opal_list.h" #include "opal/mca/base/base.h" #include "opal/runtime/opal_progress.h" -#include "opal/threads/threads.h" +#include "opal/mca/threads/threads.h" #include "opal/util/argv.h" #include "opal/util/output.h" #include "opal/util/error.h" diff --git a/test/asm/Makefile.am b/test/asm/Makefile.am index 17f222bbd9d..d8f0e4ccc3b 100644 --- a/test/asm/Makefile.am +++ b/test/asm/Makefile.am @@ -34,6 +34,7 @@ TESTS = \ $(check_PROGRAMS) EXTRA_DIST = run_tests +AM_CFLAGS = $(THREAD_CFLAGS) ###################################################################### @@ -47,35 +48,38 @@ atomic_barrier_noinline_CFLAGS = $(AM_CFLAGS) -DOMPI_DISABLE_INLINE_ASM ###################################################################### atomic_spinlock_SOURCES = atomic_spinlock.c +atomic_spinlock_CFLAGS = $(AM_CFLAGS) atomic_spinlock_LDADD = $(libs) atomic_spinlock_noinline.c: ln -s $(top_srcdir)/test/asm/atomic_spinlock.c atomic_spinlock_noinline.c atomic_spinlock_noinline_SOURCES = atomic_spinlock_noinline.c atomic_spinlock_noinline_CFLAGS = $(AM_CFLAGS) -DOMPI_DISABLE_INLINE_ASM -atomic_spinlock_noinline_LDADD = $(libs) +atomic_spinlock_noinline_LDADD = $(THREAD_LDFLAGS) $(THREAD_LIBS) $(libs) ###################################################################### atomic_math_SOURCES = atomic_math.c -atomic_math_LDADD = $(libs) +atomic_math_CFLAGS = $(AM_CFLAGS) +atomic_math_LDADD = $(THREAD_LDFLAGS) $(THREAD_LIBS) $(libs) atomic_math_noinline.c: ln -s $(top_srcdir)/test/asm/atomic_math.c atomic_math_noinline.c atomic_math_noinline_SOURCES = atomic_math_noinline.c atomic_math_noinline_CFLAGS = $(AM_CFLAGS) -DOMPI_DISABLE_INLINE_ASM -atomic_math_noinline_LDADD = $(libs) +atomic_math_noinline_LDADD = $(THREAD_LDFLAGS) $(THREAD_LIBS) $(libs) ###################################################################### atomic_cmpset_SOURCES = atomic_cmpset.c -atomic_cmpset_LDADD = $(libs) +atomic_cmpset_CFLAGS = $(AM_CFLAGS) +atomic_cmpset_LDADD = $(THREAD_LDFLAGS) $(THREAD_LIBS) $(libs) atomic_cmpset_noinline.c: ln -s $(top_srcdir)/test/asm/atomic_cmpset.c atomic_cmpset_noinline.c atomic_cmpset_noinline_SOURCES = atomic_cmpset_noinline.c atomic_cmpset_noinline_CFLAGS = $(AM_CFLAGS) -DOMPI_DISABLE_INLINE_ASM -atomic_cmpset_noinline_LDADD = $(libs) +atomic_cmpset_noinline_LDADD = $(THREAD_LDFLAGS) $(THREAD_LIBS) $(libs) ###################################################################### diff --git a/test/class/opal_fifo.c b/test/class/opal_fifo.c index 122524a8d9f..73950c912a6 100644 --- a/test/class/opal_fifo.c +++ b/test/class/opal_fifo.c @@ -17,6 +17,7 @@ #include "opal/class/opal_fifo.h" #include "opal/runtime/opal.h" #include "opal/constants.h" +#include "opal/mca/threads/threads.h" #include #include @@ -41,8 +42,8 @@ } while (0) #endif -static void *thread_test (void *arg) { - opal_fifo_t *fifo = (opal_fifo_t *) arg; +static void *thread_test (opal_thread_t *arg) { + opal_fifo_t *fifo = (opal_fifo_t *) arg->t_arg; opal_list_item_t *item; struct timeval start, stop, total; double timing; @@ -66,8 +67,8 @@ static void *thread_test (void *arg) { return NULL; } -static void *thread_test_exhaust (void *arg) { - opal_fifo_t *fifo = (opal_fifo_t *) arg; +static void *thread_test_exhaust (opal_thread_t *arg) { + opal_fifo_t *fifo = (opal_fifo_t *) arg->t_arg; opal_list_item_t *items[ITEMS_PER_LOOP]; struct timeval start, stop, total; int item_count = 0; @@ -114,7 +115,7 @@ static bool check_fifo_consistency (opal_fifo_t *fifo, int expected_count) } int main (int argc, char *argv[]) { - pthread_t threads[OPAL_FIFO_TEST_THREAD_COUNT]; + opal_thread_t threads[OPAL_FIFO_TEST_THREAD_COUNT]; opal_list_item_t *item, *prev, *item2; struct timeval start, stop, total; opal_fifo_t fifo; @@ -182,7 +183,8 @@ int main (int argc, char *argv[]) { printf ("Single thread test. Time: %d s %d us %d nsec/poppush\n", (int) total.tv_sec, (int)total.tv_usec, (int)(timing / 1e-9)); - thread_test (&fifo); + threads[0].t_arg = &fifo; + thread_test (&threads[0]); if (check_fifo_consistency (&fifo, ITEM_COUNT)) { test_success (); @@ -192,13 +194,15 @@ int main (int argc, char *argv[]) { gettimeofday (&start, NULL); for (int i = 0 ; i < OPAL_FIFO_TEST_THREAD_COUNT ; ++i) { - pthread_create (threads + i, NULL, thread_test, &fifo); + threads[i].t_run = (opal_thread_fn_t) thread_test; + threads[i].t_arg = &fifo; + opal_thread_start (threads + i); } for (int i = 0 ; i < OPAL_FIFO_TEST_THREAD_COUNT ; ++i) { void *ret; - pthread_join (threads[i], &ret); + opal_thread_join (threads + i, &ret); } gettimeofday (&stop, NULL); @@ -218,13 +222,15 @@ int main (int argc, char *argv[]) { gettimeofday (&start, NULL); for (int i = 0 ; i < OPAL_FIFO_TEST_THREAD_COUNT ; ++i) { - pthread_create (threads + i, NULL, thread_test_exhaust, &fifo); + threads[i].t_run = (opal_thread_fn_t) thread_test_exhaust; + threads[i].t_arg = &fifo; + opal_thread_start (threads + i); } for (int i = 0 ; i < OPAL_FIFO_TEST_THREAD_COUNT ; ++i) { void *ret; - pthread_join (threads[i], &ret); + opal_thread_join (threads + i, &ret); } gettimeofday (&stop, NULL); diff --git a/test/class/opal_lifo.c b/test/class/opal_lifo.c index 521bb4e5d97..28fe2533a6d 100644 --- a/test/class/opal_lifo.c +++ b/test/class/opal_lifo.c @@ -16,11 +16,11 @@ #include "opal/class/opal_lifo.h" #include "opal/runtime/opal.h" #include "opal/constants.h" +#include "opal/mca/threads/threads.h" #include #include #include - #include #define OPAL_LIFO_TEST_THREAD_COUNT 8 @@ -39,8 +39,8 @@ } while (0) #endif -static void *thread_test (void *arg) { - opal_lifo_t *lifo = (opal_lifo_t *) arg; +static void *thread_test (opal_thread_t *arg) { + opal_lifo_t *lifo = (opal_lifo_t *) arg->t_arg; opal_list_item_t *item; struct timeval start, stop, total; double timing; @@ -76,7 +76,7 @@ static bool check_lifo_consistency (opal_lifo_t *lifo, int expected_count) } int main (int argc, char *argv[]) { - pthread_t threads[OPAL_LIFO_TEST_THREAD_COUNT]; + opal_thread_t threads[OPAL_LIFO_TEST_THREAD_COUNT]; opal_list_item_t *item, *prev, *item2; struct timeval start, stop, total; opal_lifo_t lifo; @@ -144,7 +144,8 @@ int main (int argc, char *argv[]) { printf ("Single thread test. Time: %d s %d us %d nsec/poppush\n", (int) total.tv_sec, (int)total.tv_usec, (int)(timing / 1e-9)); - thread_test (&lifo); + threads[0].t_arg = &lifo; + thread_test (&threads[0]); if (check_lifo_consistency (&lifo, ITEM_COUNT)) { test_success (); @@ -154,13 +155,15 @@ int main (int argc, char *argv[]) { gettimeofday (&start, NULL); for (int i = 0 ; i < OPAL_LIFO_TEST_THREAD_COUNT ; ++i) { - pthread_create (threads + i, NULL, thread_test, &lifo); + threads[i].t_run = (opal_thread_fn_t) thread_test; + threads[i].t_arg = &lifo; + opal_thread_start (threads + i); } for (int i = 0 ; i < OPAL_LIFO_TEST_THREAD_COUNT ; ++i) { void *ret; - pthread_join (threads[i], &ret); + opal_thread_join (threads + i, &ret); } gettimeofday (&stop, NULL); diff --git a/test/threads/opal_condition.c b/test/threads/opal_condition.c index e163dcb83e4..cacb3acc5f1 100644 --- a/test/threads/opal_condition.c +++ b/test/threads/opal_condition.c @@ -25,8 +25,8 @@ #include "support.h" #include "opal/runtime/opal.h" #include "opal/constants.h" -#include "opal/threads/threads.h" -#include "opal/threads/condition.h" +#include "opal/mca/threads/threads.h" +#include "opal/mca/threads/condition.h" #include "opal/sys/atomic.h" static opal_mutex_t mutex; diff --git a/test/threads/opal_thread.c b/test/threads/opal_thread.c index e795190c5a1..f7f66130d8d 100644 --- a/test/threads/opal_thread.c +++ b/test/threads/opal_thread.c @@ -15,7 +15,7 @@ #include "support.h" #include "opal/constants.h" -#include "opal/threads/threads.h" +#include "opal/mca/threads/threads.h" #include "opal/sys/atomic.h" From 8cab081770973b7de4e477a2f5e2c9f6fcdc69c8 Mon Sep 17 00:00:00 2001 From: Shintaro Iwasaki Date: Wed, 25 Mar 2020 07:01:49 -0500 Subject: [PATCH 2/5] test/class: fix opal_fifo and opal_lifo Signed-off-by: Shintaro Iwasaki --- .../argobots/threads_argobots_module.c | 2 +- .../pthreads/threads_pthreads_module.c | 52 +++++++++---------- test/class/opal_fifo.c | 18 ++++--- test/class/opal_lifo.c | 10 ++-- 4 files changed, 43 insertions(+), 39 deletions(-) diff --git a/opal/mca/threads/argobots/threads_argobots_module.c b/opal/mca/threads/argobots/threads_argobots_module.c index 16ab9e1c94f..1124d48ab33 100644 --- a/opal/mca/threads/argobots/threads_argobots_module.c +++ b/opal/mca/threads/argobots/threads_argobots_module.c @@ -40,7 +40,7 @@ struct opal_tsd_key_value { }; static ABT_thread opal_main_thread; -struct opal_tsd_key_value *opal_tsd_key_values = NULL; +static struct opal_tsd_key_value *opal_tsd_key_values = NULL; static int opal_tsd_key_values_count = 0; /* diff --git a/opal/mca/threads/pthreads/threads_pthreads_module.c b/opal/mca/threads/pthreads/threads_pthreads_module.c index 8d67d4d5708..19d4b3ab8f8 100644 --- a/opal/mca/threads/pthreads/threads_pthreads_module.c +++ b/opal/mca/threads/pthreads/threads_pthreads_module.c @@ -32,13 +32,14 @@ #include "opal/mca/threads/threads.h" #include "opal/mca/threads/tsd.h" +static pthread_t opal_main_thread; + struct opal_tsd_key_value { opal_tsd_key_t key; opal_tsd_destructor_t destructor; }; -static pthread_t opal_main_thread; -struct opal_tsd_key_value *opal_tsd_key_values = NULL; +static struct opal_tsd_key_value *opal_tsd_key_values = NULL; static int opal_tsd_key_values_count = 0; /* @@ -54,17 +55,19 @@ OBJ_CLASS_INSTANCE(opal_thread_t, opal_object_t, opal_thread_construct, NULL); - -opal_thread_t *opal_thread_get_self(void) +int opal_thread_start(opal_thread_t *t) { - opal_thread_t *t = OBJ_NEW(opal_thread_t); - t->t_handle = pthread_self(); - return t; -} + int rc; -bool opal_thread_self_compare(opal_thread_t *t) -{ - return pthread_self() == t->t_handle; + if (OPAL_ENABLE_DEBUG) { + if (NULL == t->t_run || (pthread_t)-1 != t->t_handle) { + return OPAL_ERR_BAD_PARAM; + } + } + + rc = pthread_create(&t->t_handle, NULL, (void *(*)(void *))t->t_run, t); + + return 0 == rc ? OPAL_SUCCESS : OPAL_ERR_IN_ERRNO; } int opal_thread_join(opal_thread_t *t, void **thr_return) @@ -74,28 +77,18 @@ int opal_thread_join(opal_thread_t *t, void **thr_return) return 0 == rc ? OPAL_SUCCESS : OPAL_ERR_IN_ERRNO; } -void opal_thread_set_main(void) +bool opal_thread_self_compare(opal_thread_t *t) { - opal_main_thread = pthread_self(); + return pthread_self() == t->t_handle; } -int opal_thread_start(opal_thread_t *t) +opal_thread_t *opal_thread_get_self(void) { - int rc; - - if (OPAL_ENABLE_DEBUG) { - if (NULL == t->t_run || (pthread_t)-1 != t->t_handle) { - return OPAL_ERR_BAD_PARAM; - } - } - - rc = pthread_create(&t->t_handle, NULL, (void *(*)(void *))t->t_run, t); - - return 0 == rc ? OPAL_SUCCESS : OPAL_ERR_IN_ERRNO; + opal_thread_t *t = OBJ_NEW(opal_thread_t); + t->t_handle = pthread_self(); + return t; } -OBJ_CLASS_DECLARATION(opal_thread_t); - int opal_tsd_key_create(opal_tsd_key_t *key, opal_tsd_destructor_t destructor) { int rc; @@ -131,6 +124,11 @@ int opal_tsd_keys_destruct(void) return OPAL_SUCCESS; } +void opal_thread_set_main(void) +{ + opal_main_thread = pthread_self(); +} + void opal_event_use_threads(void) { evthread_use_pthreads(); diff --git a/test/class/opal_fifo.c b/test/class/opal_fifo.c index 73950c912a6..196c84a704d 100644 --- a/test/class/opal_fifo.c +++ b/test/class/opal_fifo.c @@ -42,8 +42,9 @@ } while (0) #endif -static void *thread_test (opal_thread_t *arg) { - opal_fifo_t *fifo = (opal_fifo_t *) arg->t_arg; +static void *thread_test (opal_object_t *arg) { + opal_thread_t *t = (opal_thread_t *) arg; + opal_fifo_t *fifo = (opal_fifo_t *) t->t_arg; opal_list_item_t *item; struct timeval start, stop, total; double timing; @@ -67,8 +68,9 @@ static void *thread_test (opal_thread_t *arg) { return NULL; } -static void *thread_test_exhaust (opal_thread_t *arg) { - opal_fifo_t *fifo = (opal_fifo_t *) arg->t_arg; +static void *thread_test_exhaust (opal_object_t *arg) { + opal_thread_t *t = (opal_thread_t *) arg; + opal_fifo_t *fifo = (opal_fifo_t *) t->t_arg; opal_list_item_t *items[ITEMS_PER_LOOP]; struct timeval start, stop, total; int item_count = 0; @@ -184,7 +186,7 @@ int main (int argc, char *argv[]) { (int)total.tv_usec, (int)(timing / 1e-9)); threads[0].t_arg = &fifo; - thread_test (&threads[0]); + thread_test ((opal_object_t *) &threads[0]); if (check_fifo_consistency (&fifo, ITEM_COUNT)) { test_success (); @@ -194,7 +196,8 @@ int main (int argc, char *argv[]) { gettimeofday (&start, NULL); for (int i = 0 ; i < OPAL_FIFO_TEST_THREAD_COUNT ; ++i) { - threads[i].t_run = (opal_thread_fn_t) thread_test; + OBJ_CONSTRUCT(&threads[i], opal_thread_t); + threads[i].t_run = thread_test; threads[i].t_arg = &fifo; opal_thread_start (threads + i); } @@ -222,7 +225,8 @@ int main (int argc, char *argv[]) { gettimeofday (&start, NULL); for (int i = 0 ; i < OPAL_FIFO_TEST_THREAD_COUNT ; ++i) { - threads[i].t_run = (opal_thread_fn_t) thread_test_exhaust; + OBJ_CONSTRUCT(&threads[i], opal_thread_t); + threads[i].t_run = thread_test_exhaust; threads[i].t_arg = &fifo; opal_thread_start (threads + i); } diff --git a/test/class/opal_lifo.c b/test/class/opal_lifo.c index 28fe2533a6d..8e031b352cf 100644 --- a/test/class/opal_lifo.c +++ b/test/class/opal_lifo.c @@ -39,8 +39,9 @@ } while (0) #endif -static void *thread_test (opal_thread_t *arg) { - opal_lifo_t *lifo = (opal_lifo_t *) arg->t_arg; +static void *thread_test (opal_object_t *arg) { + opal_thread_t *t = (opal_thread_t *) arg; + opal_lifo_t *lifo = (opal_lifo_t *) t->t_arg; opal_list_item_t *item; struct timeval start, stop, total; double timing; @@ -145,7 +146,7 @@ int main (int argc, char *argv[]) { (int)total.tv_usec, (int)(timing / 1e-9)); threads[0].t_arg = &lifo; - thread_test (&threads[0]); + thread_test ((opal_object_t *) &threads[0]); if (check_lifo_consistency (&lifo, ITEM_COUNT)) { test_success (); @@ -155,7 +156,8 @@ int main (int argc, char *argv[]) { gettimeofday (&start, NULL); for (int i = 0 ; i < OPAL_LIFO_TEST_THREAD_COUNT ; ++i) { - threads[i].t_run = (opal_thread_fn_t) thread_test; + OBJ_CONSTRUCT(&threads[i], opal_thread_t); + threads[i].t_run = thread_test; threads[i].t_arg = &lifo; opal_thread_start (threads + i); } From 69e8af536ad1261daffae93572e6766d590f11d2 Mon Sep 17 00:00:00 2001 From: Shintaro Iwasaki Date: Wed, 25 Mar 2020 12:54:07 -0500 Subject: [PATCH 3/5] mca/threads: fix tsd management To suppress Valgrind warnings, opal_tsd_keys_destruct() needs to explicitly release TSD values of the main thread. However, they were not freed if keys are created by non-main threads. This patch fixes it. This patch also optimizes allocation of opal_tsd_key_values by doubling its size when count >= length instead of increasing the size by one. Signed-off-by: Shintaro Iwasaki --- .../argobots/threads_argobots_module.c | 22 +++++++++++++------ .../pthreads/threads_pthreads_module.c | 21 +++++++++++++----- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/opal/mca/threads/argobots/threads_argobots_module.c b/opal/mca/threads/argobots/threads_argobots_module.c index 1124d48ab33..0776b877417 100644 --- a/opal/mca/threads/argobots/threads_argobots_module.c +++ b/opal/mca/threads/argobots/threads_argobots_module.c @@ -39,9 +39,10 @@ struct opal_tsd_key_value { opal_tsd_destructor_t destructor; }; -static ABT_thread opal_main_thread; +static opal_mutex_t opal_tsd_lock = OPAL_MUTEX_STATIC_INIT; static struct opal_tsd_key_value *opal_tsd_key_values = NULL; static int opal_tsd_key_values_count = 0; +static int opal_tsd_key_values_size = 0; /* * Constructor @@ -95,8 +96,6 @@ int opal_thread_join(opal_thread_t *t, void **thr_return) void opal_thread_set_main() { - opal_threads_argobots_ensure_init(); - opal_main_thread = opal_thread_get_argobots_self(); } int opal_thread_start(opal_thread_t *t) @@ -125,14 +124,19 @@ int opal_tsd_key_create(opal_tsd_key_t *key, opal_tsd_destructor_t destructor) opal_threads_argobots_ensure_init(); int rc; rc = ABT_key_create(destructor, key); - if ((ABT_SUCCESS == rc) && - (opal_thread_get_argobots_self() == opal_main_thread)) { - opal_tsd_key_values = (struct opal_tsd_key_value *) - realloc(opal_tsd_key_values, (opal_tsd_key_values_count + 1) * + if (ABT_SUCCESS == rc) { + opal_mutex_lock(&opal_tsd_lock); + if (opal_tsd_key_values_size <= opal_tsd_key_values_count) { + opal_tsd_key_values_size = opal_tsd_key_values_size == 0 + ? 1 : opal_tsd_key_values_size * 2; + opal_tsd_key_values = (struct opal_tsd_key_value *) + realloc(opal_tsd_key_values, opal_tsd_key_values_size * sizeof(struct opal_tsd_key_value)); + } opal_tsd_key_values[opal_tsd_key_values_count].key = *key; opal_tsd_key_values[opal_tsd_key_values_count].destructor = destructor; opal_tsd_key_values_count++; + opal_mutex_unlock(&opal_tsd_lock); } return (ABT_SUCCESS == rc) ? OPAL_SUCCESS : OPAL_ERROR; } @@ -141,6 +145,7 @@ int opal_tsd_keys_destruct(void) { int i; void *ptr; + opal_mutex_lock(&opal_tsd_lock); for (i = 0; i < opal_tsd_key_values_count; i++) { if (OPAL_SUCCESS == opal_tsd_getspecific(opal_tsd_key_values[i].key, &ptr)) { @@ -152,7 +157,10 @@ int opal_tsd_keys_destruct(void) } if (0 < opal_tsd_key_values_count) { free(opal_tsd_key_values); + opal_tsd_key_values = NULL; opal_tsd_key_values_count = 0; + opal_tsd_key_values_size = 0; } + opal_mutex_unlock(&opal_tsd_lock); return OPAL_SUCCESS; } diff --git a/opal/mca/threads/pthreads/threads_pthreads_module.c b/opal/mca/threads/pthreads/threads_pthreads_module.c index 19d4b3ab8f8..5a08836224e 100644 --- a/opal/mca/threads/pthreads/threads_pthreads_module.c +++ b/opal/mca/threads/pthreads/threads_pthreads_module.c @@ -32,15 +32,15 @@ #include "opal/mca/threads/threads.h" #include "opal/mca/threads/tsd.h" -static pthread_t opal_main_thread; - struct opal_tsd_key_value { opal_tsd_key_t key; opal_tsd_destructor_t destructor; }; +static opal_mutex_t opal_tsd_lock = OPAL_MUTEX_STATIC_INIT; static struct opal_tsd_key_value *opal_tsd_key_values = NULL; static int opal_tsd_key_values_count = 0; +static int opal_tsd_key_values_size = 0; /* * Constructor @@ -93,13 +93,19 @@ int opal_tsd_key_create(opal_tsd_key_t *key, opal_tsd_destructor_t destructor) { int rc; rc = pthread_key_create(key, destructor); - if ((0 == rc) && (pthread_self() == opal_main_thread)) { - opal_tsd_key_values = (struct opal_tsd_key_value *) - realloc(opal_tsd_key_values, (opal_tsd_key_values_count + 1) * + if (0 == rc) { + opal_mutex_lock(&opal_tsd_lock); + if (opal_tsd_key_values_size <= opal_tsd_key_values_count) { + opal_tsd_key_values_size = opal_tsd_key_values_size == 0 + ? 1 : opal_tsd_key_values_size * 2; + opal_tsd_key_values = (struct opal_tsd_key_value *) + realloc(opal_tsd_key_values, opal_tsd_key_values_size * sizeof(struct opal_tsd_key_value)); + } opal_tsd_key_values[opal_tsd_key_values_count].key = *key; opal_tsd_key_values[opal_tsd_key_values_count].destructor = destructor; opal_tsd_key_values_count++; + opal_mutex_unlock(&opal_tsd_lock); } return 0 == rc ? OPAL_SUCCESS : OPAL_ERR_IN_ERRNO; } @@ -108,6 +114,7 @@ int opal_tsd_keys_destruct(void) { int i; void *ptr; + opal_mutex_lock(&opal_tsd_lock); for (i = 0; i < opal_tsd_key_values_count; i++) { if (OPAL_SUCCESS == opal_tsd_getspecific(opal_tsd_key_values[i].key, &ptr)) { @@ -119,14 +126,16 @@ int opal_tsd_keys_destruct(void) } if (0 < opal_tsd_key_values_count) { free(opal_tsd_key_values); + opal_tsd_key_values = NULL; opal_tsd_key_values_count = 0; + opal_tsd_key_values_size = 0; } + opal_mutex_unlock(&opal_tsd_lock); return OPAL_SUCCESS; } void opal_thread_set_main(void) { - opal_main_thread = pthread_self(); } void opal_event_use_threads(void) From a7ea0d9bd7a4c7bafb1a6d333a0e822258b766db Mon Sep 17 00:00:00 2001 From: Shintaro Iwasaki Date: Wed, 25 Mar 2020 12:58:44 -0500 Subject: [PATCH 4/5] ompi/request: move REQUEST constants from mca/threads to ompi/request Signed-off-by: Shintaro Iwasaki --- ompi/request/request.h | 3 +++ opal/mca/threads/wait_sync.h | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ompi/request/request.h b/ompi/request/request.h index 4b0c28c4e6e..c0a94a79255 100644 --- a/ompi/request/request.h +++ b/ompi/request/request.h @@ -151,6 +151,9 @@ typedef struct ompi_request_t ompi_request_t; */ #define PREDEFINED_REQUEST_PAD 256 +#define REQUEST_PENDING (void *)0L +#define REQUEST_COMPLETED (void *)1L + struct ompi_predefined_request_t { struct ompi_request_t request; char padding[PREDEFINED_REQUEST_PAD - sizeof(ompi_request_t)]; diff --git a/opal/mca/threads/wait_sync.h b/opal/mca/threads/wait_sync.h index c600a3d0e95..1fae419c75c 100644 --- a/opal/mca/threads/wait_sync.h +++ b/opal/mca/threads/wait_sync.h @@ -30,9 +30,6 @@ extern int opal_max_thread_in_progress; #include MCA_threads_wait_sync_base_include_HEADER -#define REQUEST_PENDING (void *)0L -#define REQUEST_COMPLETED (void *)1L - /** * Update the status of the synchronization primitive. If an error is * reported the synchronization is completed and the signal From d7fba60de8e7ce7d677f46b7ab0be635bdf1250b Mon Sep 17 00:00:00 2001 From: Shintaro Iwasaki Date: Thu, 26 Mar 2020 11:30:31 -0500 Subject: [PATCH 5/5] mca/threads: remove libevent hack Argobots/Qthreads-aware libevent should be used instead. Signed-off-by: Shintaro Iwasaki --- opal/mca/event/event.h | 2 - opal/mca/event/external/external.h | 3 + opal/mca/event/libevent2022/libevent2022.h | 3 + opal/mca/threads/README.md | 4 +- opal/mca/threads/argobots/Makefile.am | 1 - .../threads/argobots/threads_argobots_event.c | 143 ------------------ .../pthreads/threads_pthreads_module.c | 5 - opal/mca/threads/threads.h | 1 - 8 files changed, 7 insertions(+), 155 deletions(-) delete mode 100644 opal/mca/threads/argobots/threads_argobots_event.c diff --git a/opal/mca/event/event.h b/opal/mca/event/event.h index 65f8f69e054..b0958b64e09 100644 --- a/opal/mca/event/event.h +++ b/opal/mca/event/event.h @@ -48,8 +48,6 @@ BEGIN_C_DECLS #define OPAL_TIMEOUT_DEFAULT {1, 0} -OPAL_DECLSPEC void opal_event_use_threads(void); - /** * Structure for event components. */ diff --git a/opal/mca/event/external/external.h b/opal/mca/event/external/external.h index 6fe67feeeab..00378f684fe 100644 --- a/opal/mca/event/external/external.h +++ b/opal/mca/event/external/external.h @@ -71,6 +71,9 @@ OPAL_DECLSPEC int opal_event_finalize(void); #define opal_event_set_priority(x, n) event_priority_set((x), (n)) +/* thread support APIs */ +#define opal_event_use_threads() evthread_use_pthreads() + /* Basic event APIs */ #define opal_event_enable_debug_mode() event_enable_debug_mode() diff --git a/opal/mca/event/libevent2022/libevent2022.h b/opal/mca/event/libevent2022/libevent2022.h index 3b8834d0fb2..5989a486103 100644 --- a/opal/mca/event/libevent2022/libevent2022.h +++ b/opal/mca/event/libevent2022/libevent2022.h @@ -102,6 +102,9 @@ OPAL_DECLSPEC int opal_event_finalize(void); #define opal_event_set_priority(x, n) event_priority_set((x), (n)) +/* thread support APIs */ +#define opal_event_use_threads() evthread_use_pthreads() + /* Basic event APIs */ #define opal_event_enable_debug_mode() event_enable_debug_mode() diff --git a/opal/mca/threads/README.md b/opal/mca/threads/README.md index aaf7911d4ae..8c600ccb019 100644 --- a/opal/mca/threads/README.md +++ b/opal/mca/threads/README.md @@ -26,8 +26,6 @@ The rest of the threading implementation follows the normal MCA model: * `threads__condition.c` defines an instance of `opal_condition_t` which is used by `condition.h` to define Open MPI specific condition variables. -* `threads__event.c` defines an interface to Open MPI's libevent hooks. It allows the threading module to use threading model specific memory allocation and synchronization structures with Open MPI's libevent integration. - * `threads__module.c` defines the interface to opal's thread handle. It provides ways of comparing threads, getting the value of a thread via its handle and the implementation of thread local storage. * `threads__mutex.c` provides a slow path interface to creating and destroying mutices dynamically via mca allocation. They can also be defined statically using the `.h` fast path interface. @@ -36,6 +34,6 @@ The rest of the threading implementation follows the normal MCA model: ## TODO -Libevent integration with lightweight threading models is a work in progress. The current Open MPI libevent library assumes preemption and does not yield by default. Lightweight threading libraries typically require tasks to be cooperative and to voluntarily yield after some time. +Some components in the current Open MPI runtime assume preemption and does not yield by default. Lightweight threading libraries typically require tasks to be cooperative and to voluntarily yield after some time. Open MPI itself needs to be altered to use a common yielding model instead of usleep(3). diff --git a/opal/mca/threads/argobots/Makefile.am b/opal/mca/threads/argobots/Makefile.am index cf8a941fd9b..ba74c728d43 100644 --- a/opal/mca/threads/argobots/Makefile.am +++ b/opal/mca/threads/argobots/Makefile.am @@ -24,7 +24,6 @@ libmca_threads_argobots_la_SOURCES = \ threads_argobots.h \ threads_argobots_component.c \ threads_argobots_condition.c \ - threads_argobots_event.c \ threads_argobots_module.c \ threads_argobots_mutex.c \ threads_argobots_mutex.h \ diff --git a/opal/mca/threads/argobots/threads_argobots_event.c b/opal/mca/threads/argobots/threads_argobots_event.c deleted file mode 100644 index c4c14e1aef2..00000000000 --- a/opal/mca/threads/argobots/threads_argobots_event.c +++ /dev/null @@ -1,143 +0,0 @@ -/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ -/* - * Copyright (c) 2019 Sandia National Laboratories. All rights reserved. - * - * $COPYRIGHT$ - * - * Additional copyrights may follow - * - * $HEADER$ - */ - -#include "opal/mca/threads/threads.h" -#include "opal/mca/threads/argobots/threads_argobots.h" -#include "opal/mca/event/libevent2022/libevent/include/event2/thread.h" -#include "opal/mca/event/libevent2022/libevent/include/event2/event-config.h" -#include "opal/mca/event/libevent2022/libevent/include/event2/util.h" - -#include - -static void *evthread_argobots_lock_alloc(unsigned locktype) -{ - ABT_mutex lock; - if (locktype & EVTHREAD_LOCKTYPE_RECURSIVE) { - ABT_mutex_attr abt_mutex_attr; - ABT_mutex_attr_create(&abt_mutex_attr); - ABT_mutex_attr_set_recursive(abt_mutex_attr, ABT_TRUE); - ABT_mutex_create_with_attr(abt_mutex_attr, &lock); - ABT_mutex_attr_free(&abt_mutex_attr); - } else { - ABT_mutex_create(&lock); - } - return lock; -} - -static void evthread_argobots_lock_free(void *_lock, unsigned locktype) -{ - ABT_mutex lock = _lock; - ABT_mutex_free(&lock); -} - -static int evthread_argobots_lock(unsigned mode, void *_lock) -{ - int ret; - ABT_mutex lock = _lock; - if (mode & EVTHREAD_TRY) { - ret = ABT_mutex_trylock(lock); - } else { - ret = ABT_mutex_lock(lock); - } - return ABT_SUCCESS == ret ? 0 : -1; -} - -static int evthread_argobots_unlock(unsigned mode, void *_lock) -{ - ABT_mutex lock = _lock; - int ret = ABT_mutex_unlock(lock); - /* This yield is necessary to avoid taking a lock consecutively. */ - ABT_thread_yield(); - return ABT_SUCCESS == ret ? 0 : -1; -} - -static unsigned long evthread_argobots_get_id(void) -{ - ABT_thread thr; - ABT_thread_self(&thr); - return (unsigned long)((intptr_t)thr); -} - -static void *evthread_argobots_cond_alloc(unsigned condflags) -{ - ABT_cond cond; - ABT_cond_create(&cond); - return cond; -} - -static void evthread_argobots_cond_free(void *_cond) -{ - ABT_cond cond = _cond; - ABT_cond_free(&cond); -} - -static int evthread_argobots_cond_signal(void *_cond, int broadcast) -{ - ABT_cond cond = _cond; - int ret; - if (broadcast) { - ret = ABT_cond_broadcast(cond); - } else { - ret = ABT_cond_signal(cond); - } - return ABT_SUCCESS == ret ? 0 : -1; -} - -static int evthread_argobots_cond_wait(void *_cond, void *_lock, - const struct timeval *tv) -{ - int ret; - ABT_cond cond = _cond; - ABT_mutex lock = _lock; - - if (tv) { - struct timeval now, abstime; - struct timespec ts; - evutil_gettimeofday(&now, NULL); - evutil_timeradd(&now, tv, &abstime); - ts.tv_sec = abstime.tv_sec; - ts.tv_nsec = abstime.tv_usec * 1000; - ret = ABT_cond_timedwait(cond, lock, &ts); - if (ABT_ERR_COND_TIMEDOUT == ret) { - return 1; - } else if (ABT_SUCCESS != ret) { - return -1; - } else { - return 0; - } - } else { - ret = ABT_cond_wait(cond, lock); - return ABT_SUCCESS == ret ? 0 : -1; - } -} - -void opal_event_use_threads(void) -{ - struct evthread_lock_callbacks cbs = { - EVTHREAD_LOCK_API_VERSION, - EVTHREAD_LOCKTYPE_RECURSIVE, - evthread_argobots_lock_alloc, - evthread_argobots_lock_free, - evthread_argobots_lock, - evthread_argobots_unlock - }; - struct evthread_condition_callbacks cond_cbs = { - EVTHREAD_CONDITION_API_VERSION, - evthread_argobots_cond_alloc, - evthread_argobots_cond_free, - evthread_argobots_cond_signal, - evthread_argobots_cond_wait - }; - opal_threads_argobots_ensure_init(); - evthread_set_lock_callbacks(&cbs); - evthread_set_condition_callbacks(&cond_cbs); - evthread_set_id_callback(evthread_argobots_get_id); -} diff --git a/opal/mca/threads/pthreads/threads_pthreads_module.c b/opal/mca/threads/pthreads/threads_pthreads_module.c index 5a08836224e..aac8a62c862 100644 --- a/opal/mca/threads/pthreads/threads_pthreads_module.c +++ b/opal/mca/threads/pthreads/threads_pthreads_module.c @@ -137,8 +137,3 @@ int opal_tsd_keys_destruct(void) void opal_thread_set_main(void) { } - -void opal_event_use_threads(void) -{ - evthread_use_pthreads(); -} diff --git a/opal/mca/threads/threads.h b/opal/mca/threads/threads.h index bcbfa88197d..21a25db6ac8 100644 --- a/opal/mca/threads/threads.h +++ b/opal/mca/threads/threads.h @@ -132,7 +132,6 @@ OPAL_DECLSPEC bool opal_thread_self_compare(opal_thread_t *); OPAL_DECLSPEC opal_thread_t *opal_thread_get_self(void); OPAL_DECLSPEC void opal_thread_kill(opal_thread_t *, int sig); OPAL_DECLSPEC void opal_thread_set_main(void); -OPAL_DECLSPEC void opal_event_use_threads(void); END_C_DECLS