1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
|
/* -*- 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 (c) 2020 Intel, Inc. 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"
/**
* 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).
*
* Returns 0 if no progress has been observed, non-zero otherwise.
*/
OPAL_DECLSPEC int 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_NONBLOCK | OPAL_EVLOOP_ONCE
*
* OPAL_EVLOOP_NONBLOCK means that if there is no active events,
* opal_event_loop() should return immediately (instead of
* waiting for active events).
*
* OPAL_EVLOOP_ONCE means opal_event_loop() should onlyrun one
* iteration, which includes poll the event queue and process
* the active events.
*
* @param flags One of the valid flags 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);
#if OPAL_ENABLE_DEBUG
OPAL_DECLSPEC extern bool opal_progress_debug;
#endif
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
|