1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- *//*
2 * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
3 * University Research and Technology
4 * Corporation. All rights reserved.
5 * Copyright (c) 2004-2006 The University of Tennessee and The University
6 * of Tennessee Research Foundation. All rights
7 * reserved.
8 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9 * University of Stuttgart. All rights reserved.
10 * Copyright (c) 2004-2005 The Regents of the University of California.
11 * All rights reserved.
12 * Copyright (c) 2006-2014 Los Alamos National Security, LLC. All rights
13 * reserved.
14 * Copyright (c) 2018 Triad National Security, LLC. All rights
15 * reserved.
16 *
17 * $COPYRIGHT$
18 *
19 * Additional copyrights may follow
20 *
21 * $HEADER$
22 */
23
24 /**
25 * @file
26 *
27 * Progress engine for Open MPI
28 */
29
30 #ifndef OPAL_RUNTIME_OPAL_PROGRESS_H
31 #define OPAL_RUNTIME_OPAL_PROGRESS_H
32
33 BEGIN_C_DECLS
34
35 #include "opal_config.h"
36 #include "opal/threads/mutex.h"
37 #include "opal/runtime/opal.h"
38
39 /**
40 * Initialize the progress engine
41 *
42 * Initialize the progress engine, including constructing the
43 * proper locks and allocating space for the progress registration
44 * functions. At this point, any function in the progress engine
45 * interface may be called.
46 */
47 OPAL_DECLSPEC int opal_progress_init(void);
48
49 /**
50 * Progress all pending events
51 *
52 * Progress all pending events. All registered event handlers will be
53 * called every call into opal_progress(). The event library will be
54 * called if opal_progress_event_users is greater than 0 (adjustments
55 * can be made by calling opal_progress_event_users_add() and
56 * opal_progress_event_users_delete()) or the time since the last call
57 * into the event library is greater than the progress tick rate (by
58 * default, 10ms).
59 */
60 OPAL_DECLSPEC void opal_progress(void);
61
62
63 /**
64 * Control how the event library is called
65 *
66 * Adjust the flags argument used to call opal_event_loop() from
67 * opal_progress(). The default argument is OPAL_EVLOOP_ONELOOP,
68 * meaning that the call to opal_event_loop() will block pending
69 * events, but may block for a period of time.
70 *
71 * @param flags One of the valid vlags argument to
72 * opal_event_loop().
73 * @return Previous value of flags used to call
74 * opal_event_loop().
75 */
76 OPAL_DECLSPEC int opal_progress_set_event_flag(int flags);
77
78
79 /**
80 * Increase the number of users of the event library
81 *
82 * Increase the number of users of the event library. This count is
83 * used by opal_progress to determine if opal_event_loop() should be
84 * called every call to opal_progress() or only after a time has
85 * elapsed since the last call (by default, 10ms). The count defaults
86 * to 0, meaning that opal_progress_event_users_increment() must be
87 * called at least once for the event loop to be called on every entry
88 * to opal_progress().
89 *
90 */
91 OPAL_DECLSPEC void opal_progress_event_users_increment(void);
92
93
94 /**
95 * Decrease the number of users of the event library
96 *
97 * Decrease the number of users of the event library. This count is
98 * used by opal_progress to determine if opal_event_loop() should be
99 * called every call to opal_progress() or only after a time has
100 * elapsed since the last call (by default, 10ms).
101 */
102 OPAL_DECLSPEC void opal_progress_event_users_decrement(void);
103
104
105 /**
106 * Set whether opal_progress() should yield when idle
107 *
108 * Set whether opal_progress() should yield the processor (either by
109 * sched_yield() or SwitchToThread()) if no events were progressed
110 * during the progress loop. The return value of the callback
111 * functions is used to determine whether or not yielding is required.
112 * By default, the event loop will yield when the progress function is
113 * idle.
114 *
115 * @param yieldopt Whether to yield when idle.
116 * @return Previous value of the yield_when_idle option.
117 */
118 OPAL_DECLSPEC bool opal_progress_set_yield_when_idle(bool yieldopt);
119
120
121 /**
122 * Set time between calls into the event library
123 *
124 * Set time between calls into the event library when there are no
125 * users of the event library (set by
126 * opal_progress_event_users_increment() and
127 * opal_progress_event_users_decrement()).
128 *
129 * @param polltime Time (in microseconds) between calls to the event
130 * library
131 */
132 OPAL_DECLSPEC void opal_progress_set_event_poll_rate(int microseconds);
133
134
135 /**
136 * Progress callback function typedef
137 *
138 * Prototype for the a progress function callback. Progress function
139 * callbacks can be registered with opal_progress_register() and
140 * deregistered with opal_progress_deregister(). It should be noted
141 * that either registering or deregistering a function callback is an
142 * extraordinarily expensive operation and should not be used for
143 * potentially short callback lifetimes.
144 *
145 * @return Number of events progressed during the callback
146 */
147 typedef int (*opal_progress_callback_t)(void);
148
149
150 /**
151 * Register an event to be progressed
152 *
153 * Register an event to be progressed during calls to opal_progress().
154 * Please read the note in opal_progress_callback_t.
155 */
156 OPAL_DECLSPEC int opal_progress_register(opal_progress_callback_t cb);
157
158 OPAL_DECLSPEC int opal_progress_register_lp (opal_progress_callback_t cb);
159
160
161 /**
162 * Deregister previously registered event
163 *
164 * Deregister an event to be progressed during calls to opal_progress().
165 * Please read the note in opal_progress_callback_t.
166 */
167 OPAL_DECLSPEC int opal_progress_unregister(opal_progress_callback_t cb);
168
169
170 OPAL_DECLSPEC extern int opal_progress_spin_count;
171
172 /* do we want to call sched_yield() if nothing happened */
173 OPAL_DECLSPEC extern bool opal_progress_yield_when_idle;
174
175 /**
176 * Progress until flag is true or poll iterations completed
177 */
178 static inline bool opal_progress_spin(volatile bool* complete)
179 {
180 int32_t c;
181
182 for (c = 0; c < opal_progress_spin_count; c++) {
183 if (true == *complete) {
184 return true;
185 }
186 opal_progress();
187 }
188
189 return false;
190 }
191
192
193 END_C_DECLS
194
195 #endif
196