1 /************************************************************************* 2 * * 3 * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * 4 * All rights reserved. Email: russ@q12.org Web: www.q12.org * 5 * * 6 * Builtin ODE threading implementation header. * 7 * Copyright (C) 2011-2012 Oleh Derevenko. All rights reserved. * 8 * e-mail: odar@eleks.com (change all "a" to "e") * 9 * * 10 * This library is free software; you can redistribute it and/or * 11 * modify it under the terms of EITHER: * 12 * (1) The GNU Lesser General Public License as published by the Free * 13 * Software Foundation; either version 2.1 of the License, or (at * 14 * your option) any later version. The text of the GNU Lesser * 15 * General Public License is included with this library in the * 16 * file LICENSE.TXT. * 17 * (2) The BSD-style license that is included with this library in * 18 * the file LICENSE-BSD.TXT. * 19 * * 20 * This library is distributed in the hope that it will be useful, * 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 23 * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 24 * * 25 *************************************************************************/ 26 27 /* 28 * A threading implementation built into ODE for those who does not care to 29 * or can't implement an own one. 30 */ 31 32 #ifndef _ODE_THREADING_IMPL_H_ 33 #define _ODE_THREADING_IMPL_H_ 34 35 36 #include <ode/odeconfig.h> 37 #include <ode/threading.h> 38 39 40 #ifdef __cplusplus 41 extern "C" { 42 #endif 43 44 45 struct dxThreadingThreadPool; 46 typedef struct dxThreadingThreadPool *dThreadingThreadPoolID; 47 48 49 /** 50 * @brief Allocates built-in multi-threaded threading implementation object. 51 * 52 * A multi-threaded implementation is a type of implementation that has to be 53 * served with a thread pool. The thread pool can be either the built-in ODE object 54 * or set of external threads that dedicate themselves to this purpose and stay 55 * in ODE until implementation releases them. 56 * 57 * @returns ID of object allocated or NULL on failure 58 * 59 * @ingroup threading 60 * @see dThreadingThreadPoolServeMultiThreadedImplementation 61 * @see dExternalThreadingServeMultiThreadedImplementation 62 * @see dThreadingFreeImplementation 63 */ 64 ODE_API dThreadingImplementationID dThreadingAllocateMultiThreadedImplementation(); 65 66 /** 67 * @brief Retrieves the functions record of a built-in threading implementation. 68 * 69 * The implementation can be the one allocated by ODE (from @c dThreadingAllocateMultiThreadedImplementation). 70 * Do not use this function with self-made custom implementations - 71 * they should be bundled with their own set of functions. 72 * 73 * @param impl Threading implementation ID 74 * @returns Pointer to associated functions structure 75 * 76 * @ingroup threading 77 * @see dThreadingAllocateMultiThreadedImplementation 78 */ 79 ODE_API const dThreadingFunctionsInfo *dThreadingImplementationGetFunctions(dThreadingImplementationID impl); 80 81 /** 82 * @brief Requests a built-in implementation to release threads serving it. 83 * 84 * The function unblocks threads employed in implementation serving and lets them 85 * return to from where they originate. It's the responsibility of external code 86 * to make sure all the calls to ODE that might be dependent on given threading 87 * implementation object had already returned before this call is made. If threading 88 * implementation is still processing some posted calls while this function is 89 * invoked the behavior is implementation dependent. 90 * 91 * This call is to be used to request the threads to be released before waiting 92 * for them in host pool or before waiting for them to exit. Implementation object 93 * must not be destroyed before it is known that all the serving threads have already 94 * returned from it. If implementation needs to be reused after this function is called 95 * and all the threads have exited from it a call to @c dThreadingImplementationCleanupForRestart 96 * must be made to restore internal state of the object. 97 * 98 * If this function is called for self-threaded built-in threading implementation 99 * the call has no effect. 100 * 101 * @param impl Threading implementation ID 102 * 103 * @ingroup threading 104 * @see dThreadingAllocateMultiThreadedImplementation 105 * @see dThreadingImplementationCleanupForRestart 106 */ 107 ODE_API void dThreadingImplementationShutdownProcessing(dThreadingImplementationID impl); 108 109 /** 110 * @brief Restores built-in implementation's state to let it be reused after shutdown. 111 * 112 * If a multi-threaded built-in implementation needs to be reused after a call 113 * to @c dThreadingImplementationShutdownProcessing this call is to be made to 114 * restore object's internal state. After that the implementation can be served again. 115 * 116 * If this function is called for self-threaded built-in threading implementation 117 * the call has no effect. 118 * 119 * @param impl Threading implementation ID 120 * 121 * @ingroup threading 122 * @see dThreadingAllocateMultiThreadedImplementation 123 * @see dThreadingImplementationShutdownProcessing 124 */ 125 ODE_API void dThreadingImplementationCleanupForRestart(dThreadingImplementationID impl); 126 127 /** 128 * @brief Deletes an instance of built-in threading implementation. 129 * 130 * @warning A care must be taken to make sure the implementation is unassigned 131 * from all the objects it was assigned to and that there are no more threads 132 * serving it before attempting to call this function. 133 * 134 * @param impl Threading implementation ID 135 * 136 * @ingroup threading 137 * @see dThreadingAllocateMultiThreadedImplementation 138 */ 139 ODE_API void dThreadingFreeImplementation(dThreadingImplementationID impl); 140 141 142 typedef void (dThreadReadyToServeCallback)(void *callback_context); 143 144 /** 145 * @brief An entry point for external threads that would like to serve a built-in 146 * threading implementation object. 147 * 148 * A thread that calls this function remains blocked in ODE and serves implementation 149 * object @p impl until being released with @c dThreadingImplementationShutdownProcessing call. 150 * This function can be used to provide external threads instead of ODE's built-in 151 * thread pools. 152 * 153 * The optional callback @readiness_callback is called after the thread has reached 154 * and has registered within the implementation. The implementation should not 155 * be used until all dedicated threads register within it as otherwise it will not 156 * have accurate view of the execution resources available. 157 * 158 * @param impl Threading implementation ID 159 * @param readiness_callback Optional readiness callback to be called after thread enters the implementation 160 * @param callback_context A value to be passed as parameter to readiness callback 161 * 162 * @ingroup threading 163 * @see dThreadingAllocateMultiThreadedImplementation 164 * @see dThreadingImplementationShutdownProcessing 165 */ 166 ODE_API void dExternalThreadingServeMultiThreadedImplementation(dThreadingImplementationID impl, 167 dThreadReadyToServeCallback *readiness_callback/*=NULL*/, void *callback_context/*=NULL*/); 168 169 170 /** 171 * @brief Creates an instance of built-in thread pool object that can be used to serve 172 * multi-threaded threading implementations. 173 * 174 * The threads allocated inherit priority of caller thread. Their affinity is not 175 * explicitly adjusted and gets the value the system assigns by default. Threads 176 * have their stack memory fully committed immediately on start. On POSIX platforms 177 * threads are started with all the possible signals blocked. Threads execute 178 * calls to @c dAllocateODEDataForThread with @p ode_data_allocate_flags 179 * on initialization. 180 * 181 * On POSIX platforms this function must be called with signals masked 182 * or other measures must be taken to prevent reception of signals by calling thread 183 * for the duration of the call. 184 * 185 * @param thread_count Number of threads to start in pool 186 * @param stack_size Size of stack to be used for every thread or 0 for system default value 187 * @param ode_data_allocate_flags Flags to be passed to @c dAllocateODEDataForThread on behalf of each thread 188 * @returns ID of object allocated or NULL on failure 189 * 190 * @ingroup threading 191 * @see dThreadingAllocateMultiThreadedImplementation 192 * @see dThreadingImplementationShutdownProcessing 193 * @see dThreadingFreeThreadPool 194 */ 195 ODE_API dThreadingThreadPoolID dThreadingAllocateThreadPool(unsigned thread_count, 196 size_t stack_size, unsigned int ode_data_allocate_flags, void *reserved/*=NULL*/); 197 198 /** 199 * @brief Commands an instance of built-in thread pool to serve a built-in multi-threaded 200 * threading implementation. 201 * 202 * A pool can only serve one threading implementation at a time. 203 * Call @c dThreadingImplementationShutdownProcessing to release pool threads 204 * from implementation serving and make them idle. Pool threads must be released 205 * from any implementations before pool is attempted to be deleted. 206 * 207 * This function waits for threads to register within implementation before returning. 208 * So, after the function call exits the implementation can be used immediately. 209 * 210 * @param pool Thread pool ID to serve the implementation 211 * @param impl Implementation ID of implementation to be served 212 * 213 * @ingroup threading 214 * @see dThreadingAllocateThreadPool 215 * @see dThreadingAllocateMultiThreadedImplementation 216 * @see dThreadingImplementationShutdownProcessing 217 */ 218 ODE_API void dThreadingThreadPoolServeMultiThreadedImplementation(dThreadingThreadPoolID pool, dThreadingImplementationID impl); 219 220 /** 221 * @brief Waits until all pool threads are released from threading implementation 222 * they might be serving. 223 * 224 * The function can be used after a call to @c dThreadingImplementationShutdownProcessing 225 * to make sure all the threads have already been released by threading implementation 226 * and it can be deleted or it can be cleaned up for restart and served by another pool 227 * or this pool's threads can be used to serve another threading implementation. 228 * 229 * Note that is it not necessary to call this function before pool destruction 230 * since @c dThreadingFreeThreadPool performs similar wait operation implicitly on its own. 231 * 232 * It is OK to call this function even if pool was not serving any threading implementation 233 * in which case the call exits immediately with minimal delay. 234 * 235 * @param pool Thread pool ID to wait for 236 * 237 * @ingroup threading 238 * @see dThreadingAllocateThreadPool 239 * @see dThreadingImplementationShutdownProcessing 240 * @see dThreadingFreeThreadPool 241 */ 242 ODE_API void dThreadingThreadPoolWaitIdleState(dThreadingThreadPoolID pool); 243 244 /** 245 * @brief Deletes a built-in thread pool instance. 246 * 247 * The pool threads must be released from any implementations they might be serving 248 * before this function is called. Otherwise the call is going to block 249 * and wait until pool's threads return. 250 * 251 * @param pool Thread pool ID to delete 252 * 253 * @ingroup threading 254 * @see dThreadingAllocateThreadPool 255 * @see dThreadingImplementationShutdownProcessing 256 */ 257 ODE_API void dThreadingFreeThreadPool(dThreadingThreadPoolID pool); 258 259 260 #ifdef __cplusplus 261 } 262 #endif 263 264 #endif /* #ifndef _ODE_THREADING_IMPL_H_ */ 265