Cosmetic: Cosmetic code corrections in QuickStep
[ode.git] / ode / src / threading_impl.cpp
blobaa308836a1e5a0aef4cba8da42cb03c7a108670d
1 /*************************************************************************
2 * *
3 * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. *
4 * All rights reserved. Email: russ@q12.org Web: www.q12.org *
5 * *
6 * Threading subsystem implementation file. *
7 * Copyright (C) 2011-2019 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 *************************************************************************/
28 * Subsystem APIs implementation for built-in threading support provider.
32 #include <ode/common.h>
33 #include <ode/threading_impl.h>
34 #include "config.h"
35 #include "threading_impl_posix.h"
36 #include "threading_impl_win.h"
37 #include "threading_impl.h"
40 static dMutexGroupID AllocMutexGroup(dThreadingImplementationID impl, dmutexindex_t Mutex_count, const char *const *Mutex_names_ptr/*=NULL*/);
41 static void FreeMutexGroup(dThreadingImplementationID impl, dMutexGroupID mutex_group);
42 static void LockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);
43 // static int TryLockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);
44 static void UnlockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);
46 static dCallWaitID AllocThreadedCallWait(dThreadingImplementationID impl);
47 static void ResetThreadedCallWait(dThreadingImplementationID impl, dCallWaitID call_wait);
48 static void FreeThreadedCallWait(dThreadingImplementationID impl, dCallWaitID call_wait);
50 static void PostThreadedCall(
51 dThreadingImplementationID impl, int *out_summary_fault/*=NULL*/,
52 dCallReleaseeID *out_post_releasee/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/,
53 dCallWaitID call_wait/*=NULL*/,
54 dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index,
55 const char *call_name/*=NULL*/);
56 static void AlterThreadedCallDependenciesCount(
57 dThreadingImplementationID impl, dCallReleaseeID target_releasee,
58 ddependencychange_t dependencies_count_change);
59 static void WaitThreadedCall(
60 dThreadingImplementationID impl, int *out_wait_status/*=NULL*/,
61 dCallWaitID call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/,
62 const char *wait_name/*=NULL*/);
64 static unsigned RetrieveThreadingThreadCount(dThreadingImplementationID impl);
65 static int PreallocateResourcesForThreadedCalls(dThreadingImplementationID impl, ddependencycount_t max_simultaneous_calls_estimate);
68 static const dxThreadingFunctionsInfo g_builtin_threading_functions =
70 sizeof(dxThreadingFunctionsInfo), // unsigned struct_size;
72 &AllocMutexGroup, // dMutexGroupAllocFunction *alloc_mutex_group;
73 &FreeMutexGroup, // dMutexGroupFreeFunction *free_mutex_group;
74 &LockMutexGroupMutex, // dMutexGroupMutexLockFunction *lock_group_mutex;
75 &UnlockMutexGroupMutex, // dMutexGroupMutexUnlockFunction *unlock_group_mutex;
77 &AllocThreadedCallWait, // dThreadedCallWaitAllocFunction *alloc_call_wait;
78 &ResetThreadedCallWait, // dThreadedCallWaitResetFunction *reset_call_wait;
79 &FreeThreadedCallWait, // dThreadedCallWaitFreeFunction *free_call_wait;
81 &PostThreadedCall, // dThreadedCallPostFunction *post_call;
82 &AlterThreadedCallDependenciesCount, // dThreadedCallDependenciesCountAlterFunction *alter_call_dependencies_count;
83 &WaitThreadedCall, // dThreadedCallWaitFunction *wait_call;
85 &RetrieveThreadingThreadCount, // dThreadingImplThreadCountRetrieveFunction *retrieve_thread_count;
86 &PreallocateResourcesForThreadedCalls, // dThreadingImplResourcesForCallsPreallocateFunction *preallocate_resources_for_calls;
88 // &TryLockMutexGroupMutex, // dMutexGroupMutexTryLockFunction *trylock_group_mutex;
92 /*extern */dThreadingImplementationID dThreadingAllocateSelfThreadedImplementation()
94 dxSelfThreadedThreading *threading = new dxSelfThreadedThreading();
96 if (threading != NULL && !threading->InitializeObject())
98 delete threading;
99 threading = NULL;
102 dxIThreadingImplementation *impl = threading;
103 return (dThreadingImplementationID)impl;
106 /*extern */dThreadingImplementationID dThreadingAllocateMultiThreadedImplementation()
108 #if dBUILTIN_THREADING_IMPL_ENABLED
109 dxMultiThreadedThreading *threading = new dxMultiThreadedThreading();
111 if (threading != NULL && !threading->InitializeObject())
113 delete threading;
114 threading = NULL;
116 #else
117 dxIThreadingImplementation *threading = NULL;
118 #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
120 dxIThreadingImplementation *impl = threading;
121 return (dThreadingImplementationID)impl;
124 /*extern */const dThreadingFunctionsInfo *dThreadingImplementationGetFunctions(dThreadingImplementationID impl)
126 #if dBUILTIN_THREADING_IMPL_ENABLED
127 dAASSERT(impl != NULL);
128 #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
130 const dThreadingFunctionsInfo *functions = NULL;
132 #if !dBUILTIN_THREADING_IMPL_ENABLED
133 if (impl != NULL)
134 #endif // #if !dBUILTIN_THREADING_IMPL_ENABLED
136 functions = &g_builtin_threading_functions;
139 return functions;
142 /*extern */void dThreadingImplementationShutdownProcessing(dThreadingImplementationID impl)
144 #if dBUILTIN_THREADING_IMPL_ENABLED
145 dAASSERT(impl != NULL);
146 #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
148 #if !dBUILTIN_THREADING_IMPL_ENABLED
149 if (impl != NULL)
150 #endif // #if !dBUILTIN_THREADING_IMPL_ENABLED
152 ((dxIThreadingImplementation *)impl)->ShutdownProcessing();
156 /*extern */void dThreadingImplementationCleanupForRestart(dThreadingImplementationID impl)
158 #if dBUILTIN_THREADING_IMPL_ENABLED
159 dAASSERT(impl != NULL);
160 #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
162 #if !dBUILTIN_THREADING_IMPL_ENABLED
163 if (impl != NULL)
164 #endif // #if !dBUILTIN_THREADING_IMPL_ENABLED
166 ((dxIThreadingImplementation *)impl)->CleanupForRestart();
170 /*extern */void dThreadingFreeImplementation(dThreadingImplementationID impl)
172 if (impl != NULL)
174 ((dxIThreadingImplementation *)impl)->FreeInstance();
179 /*extern */void dExternalThreadingServeMultiThreadedImplementation(dThreadingImplementationID impl,
180 dThreadReadyToServeCallback *readiness_callback/*=NULL*/, void *callback_context/*=NULL*/)
182 #if dBUILTIN_THREADING_IMPL_ENABLED
183 dAASSERT(impl != NULL);
184 #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
186 #if !dBUILTIN_THREADING_IMPL_ENABLED
187 if (impl != NULL)
188 #endif // #if !dBUILTIN_THREADING_IMPL_ENABLED
190 ((dxIThreadingImplementation *)impl)->StickToJobsProcessing(readiness_callback, callback_context);
195 //////////////////////////////////////////////////////////////////////////
197 static dMutexGroupID AllocMutexGroup(dThreadingImplementationID impl, dmutexindex_t Mutex_count, const char *const *Mutex_names_ptr/*=NULL*/)
199 (void)Mutex_names_ptr; // unused
200 dIMutexGroup *mutex_group = ((dxIThreadingImplementation *)impl)->AllocMutexGroup(Mutex_count);
201 return (dMutexGroupID)mutex_group;
204 static void FreeMutexGroup(dThreadingImplementationID impl, dMutexGroupID mutex_group)
206 ((dxIThreadingImplementation *)impl)->FreeMutexGroup((dIMutexGroup *)mutex_group);
209 static void LockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index)
211 ((dxIThreadingImplementation *)impl)->LockMutexGroupMutex((dIMutexGroup *)mutex_group, mutex_index);
214 // static int TryLockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index)
215 // {
216 // bool trylock_result = ((dxIThreadingImplementation *)impl)->TryLockMutexGroupMutex((dIMutexGroup *)mutex_group, mutex_index);
217 // return trylock_result;
218 // }
220 static void UnlockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index)
222 ((dxIThreadingImplementation *)impl)->UnlockMutexGroupMutex((dIMutexGroup *)mutex_group, mutex_index);
226 static dCallWaitID AllocThreadedCallWait(dThreadingImplementationID impl)
228 dxICallWait *call_wait = ((dxIThreadingImplementation *)impl)->AllocACallWait();
229 return (dCallWaitID)call_wait;
232 static void ResetThreadedCallWait(dThreadingImplementationID impl, dCallWaitID call_wait)
234 ((dxIThreadingImplementation *)impl)->ResetACallWait((dxICallWait *)call_wait);
237 static void FreeThreadedCallWait(dThreadingImplementationID impl, dCallWaitID call_wait)
239 ((dxIThreadingImplementation *)impl)->FreeACallWait((dxICallWait *)call_wait);
243 static void PostThreadedCall(
244 dThreadingImplementationID impl, int *out_summary_fault/*=NULL*/,
245 dCallReleaseeID *out_post_releasee/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/,
246 dCallWaitID call_wait/*=NULL*/,
247 dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index,
248 const char *call_name/*=NULL*/)
250 (void)call_name; // unused
251 ((dxIThreadingImplementation *)impl)->ScheduleNewJob(out_summary_fault, out_post_releasee,
252 dependencies_count, dependent_releasee, (dxICallWait *)call_wait, call_func, call_context, instance_index);
255 static void AlterThreadedCallDependenciesCount(
256 dThreadingImplementationID impl, dCallReleaseeID target_releasee,
257 ddependencychange_t dependencies_count_change)
259 ((dxIThreadingImplementation *)impl)->AlterJobDependenciesCount(target_releasee, dependencies_count_change);
262 static void WaitThreadedCall(
263 dThreadingImplementationID impl, int *out_wait_status/*=NULL*/,
264 dCallWaitID call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/,
265 const char *wait_name/*=NULL*/)
267 (void)wait_name; // unused
268 ((dxIThreadingImplementation *)impl)->WaitJobCompletion(out_wait_status, (dxICallWait *)call_wait, timeout_time_ptr);
272 static unsigned RetrieveThreadingThreadCount(dThreadingImplementationID impl)
274 return ((dxIThreadingImplementation *)impl)->RetrieveActiveThreadsCount();
277 static int PreallocateResourcesForThreadedCalls(dThreadingImplementationID impl, ddependencycount_t max_simultaneous_calls_estimate)
279 return ((dxIThreadingImplementation *)impl)->PreallocateJobInfos(max_simultaneous_calls_estimate);