1
1
openmpi/opal/runtime/opal_progress.h
Noah Evans ee3517427e 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 <noah.evans@gmail.com>
Signed-off-by: Shintaro Iwasaki <siwasaki@anl.gov>
Signed-off-by: Howard Pritchard <howardp@lanl.gov>
2020-03-27 10:15:45 -06:00

197 строки
6.1 KiB
C

/* -*- 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) 2006-2014 Los Alamos National Security, LLC. All rights
* reserved.
* Copyright (c) 2018 Triad National Security, LLC. All rights
* reserved.
*
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
/**
* @file
*
* Progress engine for Open MPI
*/
#ifndef OPAL_RUNTIME_OPAL_PROGRESS_H
#define OPAL_RUNTIME_OPAL_PROGRESS_H
BEGIN_C_DECLS
#include "opal_config.h"
#include "opal/mca/threads/mutex.h"
#include "opal/runtime/opal.h"
/**
* Initialize the progress engine
*
* Initialize the progress engine, including constructing the
* proper locks and allocating space for the progress registration
* functions. At this point, any function in the progress engine
* interface may be called.
*/
OPAL_DECLSPEC int opal_progress_init(void);
/**
* Progress all pending events
*
* Progress all pending events. All registered event handlers will be
* called every call into opal_progress(). The event library will be
* called if opal_progress_event_users is greater than 0 (adjustments
* can be made by calling opal_progress_event_users_add() and
* opal_progress_event_users_delete()) or the time since the last call
* into the event library is greater than the progress tick rate (by
* default, 10ms).
*/
OPAL_DECLSPEC void opal_progress(void);
/**
* Control how the event library is called
*
* Adjust the flags argument used to call opal_event_loop() from
* opal_progress(). The default argument is OPAL_EVLOOP_ONELOOP,
* meaning that the call to opal_event_loop() will block pending
* events, but may block for a period of time.
*
* @param flags One of the valid vlags argument to
* opal_event_loop().
* @return Previous value of flags used to call
* opal_event_loop().
*/
OPAL_DECLSPEC int opal_progress_set_event_flag(int flags);
/**
* Increase the number of users of the event library
*
* Increase the number of users of the event library. This count is
* used by opal_progress to determine if opal_event_loop() should be
* called every call to opal_progress() or only after a time has
* elapsed since the last call (by default, 10ms). The count defaults
* to 0, meaning that opal_progress_event_users_increment() must be
* called at least once for the event loop to be called on every entry
* to opal_progress().
*
*/
OPAL_DECLSPEC void opal_progress_event_users_increment(void);
/**
* Decrease the number of users of the event library
*
* Decrease the number of users of the event library. This count is
* used by opal_progress to determine if opal_event_loop() should be
* called every call to opal_progress() or only after a time has
* elapsed since the last call (by default, 10ms).
*/
OPAL_DECLSPEC void opal_progress_event_users_decrement(void);
/**
* Set whether opal_progress() should yield when idle
*
* Set whether opal_progress() should yield the processor (either by
* sched_yield() or SwitchToThread()) if no events were progressed
* during the progress loop. The return value of the callback
* functions is used to determine whether or not yielding is required.
* By default, the event loop will yield when the progress function is
* idle.
*
* @param yieldopt Whether to yield when idle.
* @return Previous value of the yield_when_idle option.
*/
OPAL_DECLSPEC bool opal_progress_set_yield_when_idle(bool yieldopt);
/**
* Set time between calls into the event library
*
* Set time between calls into the event library when there are no
* users of the event library (set by
* opal_progress_event_users_increment() and
* opal_progress_event_users_decrement()).
*
* @param polltime Time (in microseconds) between calls to the event
* library
*/
OPAL_DECLSPEC void opal_progress_set_event_poll_rate(int microseconds);
/**
* Progress callback function typedef
*
* Prototype for the a progress function callback. Progress function
* callbacks can be registered with opal_progress_register() and
* deregistered with opal_progress_deregister(). It should be noted
* that either registering or deregistering a function callback is an
* extraordinarily expensive operation and should not be used for
* potentially short callback lifetimes.
*
* @return Number of events progressed during the callback
*/
typedef int (*opal_progress_callback_t)(void);
/**
* Register an event to be progressed
*
* Register an event to be progressed during calls to opal_progress().
* Please read the note in opal_progress_callback_t.
*/
OPAL_DECLSPEC int opal_progress_register(opal_progress_callback_t cb);
OPAL_DECLSPEC int opal_progress_register_lp (opal_progress_callback_t cb);
/**
* Deregister previously registered event
*
* Deregister an event to be progressed during calls to opal_progress().
* Please read the note in opal_progress_callback_t.
*/
OPAL_DECLSPEC int opal_progress_unregister(opal_progress_callback_t cb);
OPAL_DECLSPEC extern int opal_progress_spin_count;
/* do we want to call sched_yield() if nothing happened */
OPAL_DECLSPEC extern bool opal_progress_yield_when_idle;
/**
* Progress until flag is true or poll iterations completed
*/
static inline bool opal_progress_spin(volatile bool* complete)
{
int32_t c;
for (c = 0; c < opal_progress_spin_count; c++) {
if (true == *complete) {
return true;
}
opal_progress();
}
return false;
}
END_C_DECLS
#endif