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