OpenMPI  0.1.1
opal_progress.h
Go to the documentation of this file.
1 /*
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 Los Alamos National Security, LLC. All rights
13  * reserved.
14  *
15  * $COPYRIGHT$
16  *
17  * Additional copyrights may follow
18  *
19  * $HEADER$
20  */
21 
22 /**
23  * @file
24  *
25  * Progress engine for Open MPI
26  */
27 
28 #ifndef OPAL_RUNTIME_OPAL_PROGRESS_H
29 #define OPAL_RUNTIME_OPAL_PROGRESS_H
30 
31 BEGIN_C_DECLS
32 
33 #include "opal_config.h"
34 #include "opal/threads/mutex.h"
35 
36 /**
37  * Initialize the progress engine
38  *
39  * Initialize the progress engine, including constructing the
40  * proper locks and allocating space for the progress registration
41  * functions. At this point, any function in the progress engine
42  * interface may be called.
43  */
44 OPAL_DECLSPEC int opal_progress_init(void);
45 
46 
47 /**
48  * Shut down the progress engine
49  *
50  * Shut down the progress engine. This includes deregistering all
51  * registered callbacks and freeing all resources. After finalize
52  * returns, no calls into the progress interface are allowed.
53  */
54 OPAL_DECLSPEC int opal_progress_finalize(void);
55 
56 
57 /**
58  * Progress all pending events
59  *
60  * Progress all pending events. All registered event handlers will be
61  * called every call into opal_progress(). The event library will be
62  * called if opal_progress_event_users is greater than 0 (adjustments
63  * can be made by calling opal_progress_event_users_add() and
64  * opal_progress_event_users_delete()) or the time since the last call
65  * into the event library is greater than the progress tick rate (by
66  * default, 10ms).
67  */
68 OPAL_DECLSPEC void opal_progress(void);
69 
70 
71 /**
72  * Control how the event library is called
73  *
74  * Adjust the flags argument used to call opal_event_loop() from
75  * opal_progress(). The default argument is OPAL_EVLOOP_ONELOOP,
76  * meaning that the call to opal_event_loop() will block pending
77  * events, but may block for a period of time.
78  *
79  * @param flags One of the valid vlags argument to
80  * opal_event_loop().
81  * @return Previous value of flags used to call
82  * opal_event_loop().
83  */
84 OPAL_DECLSPEC int opal_progress_set_event_flag(int flags);
85 
86 
87 /**
88  * Increase the number of users of the event library
89  *
90  * Increase the number of users of the event library. This count is
91  * used by opal_progress to determine if opal_event_loop() should be
92  * called every call to opal_progress() or only after a time has
93  * elapsed since the last call (by default, 10ms). The count defaults
94  * to 0, meaning that opal_progress_event_users_increment() must be
95  * called at least once for the event loop to be called on every entry
96  * to opal_progress().
97  *
98  */
99 OPAL_DECLSPEC void opal_progress_event_users_increment(void);
100 
101 
102 /**
103  * Decrease the number of users of the event library
104  *
105  * Decrease the number of users of the event library. This count is
106  * used by opal_progress to determine if opal_event_loop() should be
107  * called every call to opal_progress() or only after a time has
108  * elapsed since the last call (by default, 10ms).
109  */
110 OPAL_DECLSPEC void opal_progress_event_users_decrement(void);
111 
112 
113 /**
114  * Set whether opal_progress() should yield when idle
115  *
116  * Set whether opal_progress() should yield the processor (either by
117  * sched_yield() or SwitchToThread()) if no events were progressed
118  * during the progress loop. The return value of the callback
119  * functions is used to determine whether or not yielding is required.
120  * By default, the event loop will yield when the progress function is
121  * idle.
122  *
123  * @param yieldopt Whether to yield when idle.
124  * @return Previous value of the yield_when_idle option.
125  */
126 OPAL_DECLSPEC bool opal_progress_set_yield_when_idle(bool yieldopt);
127 
128 
129 /**
130  * Set time between calls into the event library
131  *
132  * Set time between calls into the event library when there are no
133  * users of the event library (set by
134  * opal_progress_event_users_increment() and
135  * opal_progress_event_users_decrement()).
136  *
137  * @param polltime Time (in microseconds) between calls to the event
138  * library
139  */
140 OPAL_DECLSPEC void opal_progress_set_event_poll_rate(int microseconds);
141 
142 
143 /**
144  * Progress callback function typedef
145  *
146  * Prototype for the a progress function callback. Progress function
147  * callbacks can be registered with opal_progress_register() and
148  * deregistered with opal_progress_deregister(). It should be noted
149  * that either registering or deregistering a function callback is an
150  * extraordinarily expensive operation and should not be used for
151  * potentially short callback lifetimes.
152  *
153  * @return Number of events progressed during the callback
154  */
155 typedef int (*opal_progress_callback_t)(void);
156 
157 
158 /**
159  * Register an event to be progressed
160  *
161  * Register an event to be progressed during calls to opal_progress().
162  * Please read the note in opal_progress_callback_t.
163  */
165 
166 
167 /**
168  * Deregister previously registered event
169  *
170  * Deregister an event to be progressed during calls to opal_progress().
171  * Please read the note in opal_progress_callback_t.
172  */
174 
175 
176 OPAL_DECLSPEC extern volatile int32_t opal_progress_thread_count;
177 OPAL_DECLSPEC extern int opal_progress_spin_count;
178 
179 static inline bool opal_progress_threads(void)
180 {
181  return (opal_progress_thread_count > 0);
182 }
183 
184 
185 /**
186  * Progress until flag is true or poll iterations completed
187  */
188 static inline bool opal_progress_spin(volatile bool* complete)
189 {
190  int32_t c;
191  OPAL_THREAD_ADD32(&opal_progress_thread_count,1);
192  for (c = 0; c < opal_progress_spin_count; c++) {
193  if (true == *complete) {
194  OPAL_THREAD_ADD32(&opal_progress_thread_count,-1);
195  return true;
196  }
197  opal_progress();
198  }
199  OPAL_THREAD_ADD32(&opal_progress_thread_count,-1);
200  return false;
201 }
202 
203 
204 /**
205  * \internal
206  * Don't use this variable; use the opal_progress_recursion_depth()
207  * function.
208  */
209 OPAL_DECLSPEC extern
210 #if OPAL_ENABLE_MULTI_THREADS
211 volatile
212 #endif
213 uint32_t opal_progress_recursion_depth_counter;
214 
215 /**
216  * Return the current level of recursion -- 0 means that we are not
217  * under an opal_progress() call at all. 1 means that you're in the
218  * top-level opal_progress() function (i.e., not deep in recursion).
219  * Higher values mean that you're that many levels deep in recursion.
220  */
221 static inline uint32_t opal_progress_recursion_depth(void)
222 {
223  return opal_progress_recursion_depth_counter;
224 }
225 
226 
227 END_C_DECLS
228 
229 #endif
230 
OPAL_DECLSPEC int opal_progress_set_event_flag(int flags)
Control how the event library is called.
Definition: opal_progress.c:233
#define OPAL_THREAD_ADD32(x, y)
Use an atomic operation for increment/decrement if opal_using_threads() indicates that threads are in...
Definition: mutex.h:367
OPAL_DECLSPEC int opal_progress_unregister(opal_progress_callback_t cb)
Deregister previously registered event.
Definition: opal_progress.c:372
OPAL_DECLSPEC void opal_progress_event_users_increment(void)
Increase the number of users of the event library.
Definition: opal_progress.c:245
BEGIN_C_DECLS OPAL_DECLSPEC int opal_progress_init(void)
Initialize the progress engine.
Definition: opal_progress.c:95
OPAL_DECLSPEC void opal_progress_set_event_poll_rate(int microseconds)
Set time between calls into the event library.
Definition: opal_progress.c:293
static bool opal_progress_spin(volatile bool *complete)
Progress until flag is true or poll iterations completed.
Definition: opal_progress.h:188
int(* opal_progress_callback_t)(void)
Progress callback function typedef.
Definition: opal_progress.h:155
OPAL_DECLSPEC bool opal_progress_set_yield_when_idle(bool yieldopt)
Set whether opal_progress() should yield when idle.
Definition: opal_progress.c:280
OPAL_DECLSPEC void opal_progress(void)
Progress all pending events.
Definition: opal_progress.c:165
OPAL_DECLSPEC int opal_progress_register(opal_progress_callback_t cb)
Register an event to be progressed.
Definition: opal_progress.c:334
Mutual exclusion functions.
OPAL_DECLSPEC void opal_progress_event_users_decrement(void)
Decrease the number of users of the event library.
Definition: opal_progress.c:263
OPAL_DECLSPEC int opal_progress_finalize(void)
Shut down the progress engine.
Definition: opal_progress.c:131
static uint32_t opal_progress_recursion_depth(void)
Return the current level of recursion – 0 means that we are not under an opal_progress() call at all...
Definition: opal_progress.h:221