1
1
openmpi/opal/runtime/opal_progress.h
Nathan Hjelm 31bfeede82 bml/r2: always add btl progress function
This commit changes the behavior of bml/r2 from conditionally
registering btl progress functions to always registering progress
functions. Any progress function beloning to a btl that is not yet in
use is registered as low-priority. As soon as a proc is added that
will make use of the btl is is re-registered normally.

This works around an issue with some btls. In order to progress a
first message from an unknown peer both ugni and openib need to have
their progress functions called. If either btl is not in use after the
first call to add_procs the callback was never happening. This commit
ensures the btl progress function is called at some point but the
number of progress callbacks is reduced from normal to ensure lower
overhead when a btl is not used. The current ratio is 1 low priority
progress callback for every 8 calls to opal_progress().

Fixes open-mpi/ompi#1676

Signed-off-by: Nathan Hjelm <hjelmn@lanl.gov>
2016-05-21 15:54:04 -04:00

205 строки
6.2 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$
*
* 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/threads/mutex.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);
/**
* Shut down the progress engine
*
* Shut down the progress engine. This includes deregistering all
* registered callbacks and freeing all resources. After finalize
* returns, no calls into the progress interface are allowed.
*/
OPAL_DECLSPEC int opal_progress_finalize(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