Threaded execution support interface added. Optional built-in threading implementatio...
[ode.git] / ode / src / threading_impl.cpp
blobc993abe4bb0609be8d54344caeb7b62c9cfb06f6
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-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 *************************************************************************/
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(dThreadingImplementationID impl, int *out_summary_fault/*=NULL*/,
51 dCallReleaseeID *out_post_releasee/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/,
52 dCallWaitID call_wait/*=NULL*/,
53 dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index,
54 const char *call_name/*=NULL*/);
55 static void AlterThreadedCallDependenciesCount(dThreadingImplementationID impl, dCallReleaseeID target_releasee,
56 ddependencychange_t dependencies_count_change);
57 static void WaitThreadedCall(dThreadingImplementationID impl, int *out_wait_status/*=NULL*/,
58 dCallWaitID call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/,
59 const char *wait_name/*=NULL*/);
61 static unsigned RetrieveThreadingThreadCount(dThreadingImplementationID impl);
62 static int PreallocateResourcesForThreadedCalls(dThreadingImplementationID impl, ddependencycount_t max_simultaneous_calls_estimate);
65 static const dxThreadingFunctionsInfo g_builtin_threading_functions =
67 sizeof(dxThreadingFunctionsInfo), // unsigned struct_size;
69 &AllocMutexGroup, // dMutexGroupAllocFunction *alloc_mutex_group;
70 &FreeMutexGroup, // dMutexGroupFreeFunction *free_mutex_group;
71 &LockMutexGroupMutex, // dMutexGroupMutexLockFunction *lock_group_mutex;
72 &UnlockMutexGroupMutex, // dMutexGroupMutexUnlockFunction *unlock_group_mutex;
74 &AllocThreadedCallWait, // dThreadedCallWaitAllocFunction *alloc_call_wait;
75 &ResetThreadedCallWait, // dThreadedCallWaitResetFunction *reset_call_wait;
76 &FreeThreadedCallWait, // dThreadedCallWaitFreeFunction *free_call_wait;
78 &PostThreadedCall, // dThreadedCallPostFunction *post_call;
79 &AlterThreadedCallDependenciesCount, // dThreadedCallDependenciesCountAlterFunction *alter_call_dependencies_count;
80 &WaitThreadedCall, // dThreadedCallWaitFunction *wait_call;
82 &RetrieveThreadingThreadCount, // dThreadingImplThreadCountRetrieveFunction *retrieve_thread_count;
83 &PreallocateResourcesForThreadedCalls, // dThreadingImplResourcesForCallsPreallocateFunction *preallocate_resources_for_calls;
85 // &TryLockMutexGroupMutex, // dMutexGroupMutexTryLockFunction *trylock_group_mutex;
89 /*extern */dThreadingImplementationID dThreadingAllocateSelfThreadedImplementation()
91 dxSelfThreadedThreading *threading = new dxSelfThreadedThreading();
93 if (threading != NULL && !threading->InitializeObject())
95 delete threading;
96 threading = NULL;
99 dxIThreadingImplementation *impl = threading;
100 return (dThreadingImplementationID)impl;
103 /*extern */dThreadingImplementationID dThreadingAllocateMultiThreadedImplementation()
105 #if dBUILTIN_THREADING_IMPL_ENABLED
106 dxMultiThreadedThreading *threading = new dxMultiThreadedThreading();
108 if (threading != NULL && !threading->InitializeObject())
110 delete threading;
111 threading = NULL;
113 #else
114 dxIThreadingImplementation *threading = NULL;
115 #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
117 dxIThreadingImplementation *impl = threading;
118 return (dThreadingImplementationID)impl;
121 /*extern */const dThreadingFunctionsInfo *dThreadingImplementationGetFunctions(dThreadingImplementationID impl)
123 #if dBUILTIN_THREADING_IMPL_ENABLED
124 dAASSERT(impl != NULL);
125 #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
127 const dThreadingFunctionsInfo *functions = NULL;
129 #if !dBUILTIN_THREADING_IMPL_ENABLED
130 if (impl != NULL)
131 #endif // #if !dBUILTIN_THREADING_IMPL_ENABLED
133 functions = &g_builtin_threading_functions;
136 return functions;
139 /*extern */void dThreadingImplementationShutdownProcessing(dThreadingImplementationID impl)
141 #if dBUILTIN_THREADING_IMPL_ENABLED
142 dAASSERT(impl != NULL);
143 #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
145 #if !dBUILTIN_THREADING_IMPL_ENABLED
146 if (impl != NULL)
147 #endif // #if !dBUILTIN_THREADING_IMPL_ENABLED
149 ((dxIThreadingImplementation *)impl)->ShutdownProcessing();
153 /*extern */void dThreadingImplementationCleanupForRestart(dThreadingImplementationID impl)
155 #if dBUILTIN_THREADING_IMPL_ENABLED
156 dAASSERT(impl != NULL);
157 #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
159 #if !dBUILTIN_THREADING_IMPL_ENABLED
160 if (impl != NULL)
161 #endif // #if !dBUILTIN_THREADING_IMPL_ENABLED
163 ((dxIThreadingImplementation *)impl)->CleanupForRestart();
167 /*extern */void dThreadingFreeImplementation(dThreadingImplementationID impl)
169 if (impl != NULL)
171 ((dxIThreadingImplementation *)impl)->FreeInstance();
176 /*extern */void dExternalThreadingServeMultiThreadedImplementation(dThreadingImplementationID impl,
177 dThreadReadyToServeCallback *readiness_callback/*=NULL*/, void *callback_context/*=NULL*/)
179 #if dBUILTIN_THREADING_IMPL_ENABLED
180 dAASSERT(impl != NULL);
181 #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
183 #if !dBUILTIN_THREADING_IMPL_ENABLED
184 if (impl != NULL)
185 #endif // #if !dBUILTIN_THREADING_IMPL_ENABLED
187 ((dxIThreadingImplementation *)impl)->StickToJobsProcessing(readiness_callback, callback_context);
192 //////////////////////////////////////////////////////////////////////////
194 static dMutexGroupID AllocMutexGroup(dThreadingImplementationID impl, dmutexindex_t Mutex_count, const char *const *Mutex_names_ptr/*=NULL*/)
196 dIMutexGroup *mutex_group = ((dxIThreadingImplementation *)impl)->AllocMutexGroup(Mutex_count);
197 return (dMutexGroupID)mutex_group;
200 static void FreeMutexGroup(dThreadingImplementationID impl, dMutexGroupID mutex_group)
202 ((dxIThreadingImplementation *)impl)->FreeMutexGroup((dIMutexGroup *)mutex_group);
205 static void LockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index)
207 ((dxIThreadingImplementation *)impl)->LockMutexGroupMutex((dIMutexGroup *)mutex_group, mutex_index);
210 // static int TryLockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index)
211 // {
212 // bool trylock_result = ((dxIThreadingImplementation *)impl)->TryLockMutexGroupMutex((dIMutexGroup *)mutex_group, mutex_index);
213 // return trylock_result;
214 // }
216 static void UnlockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index)
218 ((dxIThreadingImplementation *)impl)->UnlockMutexGroupMutex((dIMutexGroup *)mutex_group, mutex_index);
222 static dCallWaitID AllocThreadedCallWait(dThreadingImplementationID impl)
224 dxICallWait *call_wait = ((dxIThreadingImplementation *)impl)->AllocACallWait();
225 return (dCallWaitID)call_wait;
228 static void ResetThreadedCallWait(dThreadingImplementationID impl, dCallWaitID call_wait)
230 ((dxIThreadingImplementation *)impl)->ResetACallWait((dxICallWait *)call_wait);
233 static void FreeThreadedCallWait(dThreadingImplementationID impl, dCallWaitID call_wait)
235 ((dxIThreadingImplementation *)impl)->FreeACallWait((dxICallWait *)call_wait);
239 static void PostThreadedCall(dThreadingImplementationID impl, int *out_summary_fault/*=NULL*/,
240 dCallReleaseeID *out_post_releasee/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/,
241 dCallWaitID call_wait/*=NULL*/,
242 dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index,
243 const char *call_name/*=NULL*/)
245 ((dxIThreadingImplementation *)impl)->ScheduleNewJob(out_summary_fault, out_post_releasee,
246 dependencies_count, dependent_releasee, (dxICallWait *)call_wait, call_func, call_context, instance_index);
249 static void AlterThreadedCallDependenciesCount(dThreadingImplementationID impl, dCallReleaseeID target_releasee,
250 ddependencychange_t dependencies_count_change)
252 ((dxIThreadingImplementation *)impl)->AlterJobDependenciesCount(target_releasee, dependencies_count_change);
255 static void WaitThreadedCall(dThreadingImplementationID impl, int *out_wait_status/*=NULL*/,
256 dCallWaitID call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/,
257 const char *wait_name/*=NULL*/)
259 ((dxIThreadingImplementation *)impl)->WaitJobCompletion(out_wait_status, (dxICallWait *)call_wait, timeout_time_ptr);
263 static unsigned RetrieveThreadingThreadCount(dThreadingImplementationID impl)
265 return ((dxIThreadingImplementation *)impl)->RetrieveActiveThreadsCount();
268 static int PreallocateResourcesForThreadedCalls(dThreadingImplementationID impl, ddependencycount_t max_simultaneous_calls_estimate)
270 return ((dxIThreadingImplementation *)impl)->PreallocateJobInfos(max_simultaneous_calls_estimate);