threading_impl.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*************************************************************************
  2. * *
  3. * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. *
  4. * All rights reserved. Email: [email protected] Web: www.q12.org *
  5. * *
  6. * Threading subsystem implementation file. *
  7. * Copyright (C) 2011-2012 Oleh Derevenko. All rights reserved. *
  8. * e-mail: [email protected] (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. * Subsystem APIs implementation for built-in threading support provider.
  28. */
  29. #include <ode/common.h>
  30. #include <ode/threading_impl.h>
  31. #include "config.h"
  32. #include "threading_impl_posix.h"
  33. #include "threading_impl_win.h"
  34. #include "threading_impl.h"
  35. static dMutexGroupID AllocMutexGroup(dThreadingImplementationID impl, dmutexindex_t Mutex_count, const char *const *Mutex_names_ptr/*=NULL*/);
  36. static void FreeMutexGroup(dThreadingImplementationID impl, dMutexGroupID mutex_group);
  37. static void LockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);
  38. // static int TryLockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);
  39. static void UnlockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);
  40. static dCallWaitID AllocThreadedCallWait(dThreadingImplementationID impl);
  41. static void ResetThreadedCallWait(dThreadingImplementationID impl, dCallWaitID call_wait);
  42. static void FreeThreadedCallWait(dThreadingImplementationID impl, dCallWaitID call_wait);
  43. static void PostThreadedCall(
  44. dThreadingImplementationID impl, int *out_summary_fault/*=NULL*/,
  45. dCallReleaseeID *out_post_releasee/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/,
  46. dCallWaitID call_wait/*=NULL*/,
  47. dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index,
  48. const char *call_name/*=NULL*/);
  49. static void AlterThreadedCallDependenciesCount(
  50. dThreadingImplementationID impl, dCallReleaseeID target_releasee,
  51. ddependencychange_t dependencies_count_change);
  52. static void WaitThreadedCall(
  53. dThreadingImplementationID impl, int *out_wait_status/*=NULL*/,
  54. dCallWaitID call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/,
  55. const char *wait_name/*=NULL*/);
  56. static unsigned RetrieveThreadingThreadCount(dThreadingImplementationID impl);
  57. static int PreallocateResourcesForThreadedCalls(dThreadingImplementationID impl, ddependencycount_t max_simultaneous_calls_estimate);
  58. static const dxThreadingFunctionsInfo g_builtin_threading_functions =
  59. {
  60. sizeof(dxThreadingFunctionsInfo), // unsigned struct_size;
  61. &AllocMutexGroup, // dMutexGroupAllocFunction *alloc_mutex_group;
  62. &FreeMutexGroup, // dMutexGroupFreeFunction *free_mutex_group;
  63. &LockMutexGroupMutex, // dMutexGroupMutexLockFunction *lock_group_mutex;
  64. &UnlockMutexGroupMutex, // dMutexGroupMutexUnlockFunction *unlock_group_mutex;
  65. &AllocThreadedCallWait, // dThreadedCallWaitAllocFunction *alloc_call_wait;
  66. &ResetThreadedCallWait, // dThreadedCallWaitResetFunction *reset_call_wait;
  67. &FreeThreadedCallWait, // dThreadedCallWaitFreeFunction *free_call_wait;
  68. &PostThreadedCall, // dThreadedCallPostFunction *post_call;
  69. &AlterThreadedCallDependenciesCount, // dThreadedCallDependenciesCountAlterFunction *alter_call_dependencies_count;
  70. &WaitThreadedCall, // dThreadedCallWaitFunction *wait_call;
  71. &RetrieveThreadingThreadCount, // dThreadingImplThreadCountRetrieveFunction *retrieve_thread_count;
  72. &PreallocateResourcesForThreadedCalls, // dThreadingImplResourcesForCallsPreallocateFunction *preallocate_resources_for_calls;
  73. // &TryLockMutexGroupMutex, // dMutexGroupMutexTryLockFunction *trylock_group_mutex;
  74. };
  75. /*extern */dThreadingImplementationID dThreadingAllocateSelfThreadedImplementation()
  76. {
  77. dxSelfThreadedThreading *threading = new dxSelfThreadedThreading();
  78. if (threading != NULL && !threading->InitializeObject())
  79. {
  80. delete threading;
  81. threading = NULL;
  82. }
  83. dxIThreadingImplementation *impl = threading;
  84. return (dThreadingImplementationID)impl;
  85. }
  86. /*extern */dThreadingImplementationID dThreadingAllocateMultiThreadedImplementation()
  87. {
  88. #if dBUILTIN_THREADING_IMPL_ENABLED
  89. dxMultiThreadedThreading *threading = new dxMultiThreadedThreading();
  90. if (threading != NULL && !threading->InitializeObject())
  91. {
  92. delete threading;
  93. threading = NULL;
  94. }
  95. #else
  96. dxIThreadingImplementation *threading = NULL;
  97. #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
  98. dxIThreadingImplementation *impl = threading;
  99. return (dThreadingImplementationID)impl;
  100. }
  101. /*extern */const dThreadingFunctionsInfo *dThreadingImplementationGetFunctions(dThreadingImplementationID impl)
  102. {
  103. #if dBUILTIN_THREADING_IMPL_ENABLED
  104. dAASSERT(impl != NULL);
  105. #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
  106. const dThreadingFunctionsInfo *functions = NULL;
  107. #if !dBUILTIN_THREADING_IMPL_ENABLED
  108. if (impl != NULL)
  109. #endif // #if !dBUILTIN_THREADING_IMPL_ENABLED
  110. {
  111. functions = &g_builtin_threading_functions;
  112. }
  113. return functions;
  114. }
  115. /*extern */void dThreadingImplementationShutdownProcessing(dThreadingImplementationID impl)
  116. {
  117. #if dBUILTIN_THREADING_IMPL_ENABLED
  118. dAASSERT(impl != NULL);
  119. #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
  120. #if !dBUILTIN_THREADING_IMPL_ENABLED
  121. if (impl != NULL)
  122. #endif // #if !dBUILTIN_THREADING_IMPL_ENABLED
  123. {
  124. ((dxIThreadingImplementation *)impl)->ShutdownProcessing();
  125. }
  126. }
  127. /*extern */void dThreadingImplementationCleanupForRestart(dThreadingImplementationID impl)
  128. {
  129. #if dBUILTIN_THREADING_IMPL_ENABLED
  130. dAASSERT(impl != NULL);
  131. #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
  132. #if !dBUILTIN_THREADING_IMPL_ENABLED
  133. if (impl != NULL)
  134. #endif // #if !dBUILTIN_THREADING_IMPL_ENABLED
  135. {
  136. ((dxIThreadingImplementation *)impl)->CleanupForRestart();
  137. }
  138. }
  139. /*extern */void dThreadingFreeImplementation(dThreadingImplementationID impl)
  140. {
  141. if (impl != NULL)
  142. {
  143. ((dxIThreadingImplementation *)impl)->FreeInstance();
  144. }
  145. }
  146. /*extern */void dExternalThreadingServeMultiThreadedImplementation(dThreadingImplementationID impl,
  147. dThreadReadyToServeCallback *readiness_callback/*=NULL*/, void *callback_context/*=NULL*/)
  148. {
  149. #if dBUILTIN_THREADING_IMPL_ENABLED
  150. dAASSERT(impl != NULL);
  151. #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
  152. #if !dBUILTIN_THREADING_IMPL_ENABLED
  153. if (impl != NULL)
  154. #endif // #if !dBUILTIN_THREADING_IMPL_ENABLED
  155. {
  156. ((dxIThreadingImplementation *)impl)->StickToJobsProcessing(readiness_callback, callback_context);
  157. }
  158. }
  159. //////////////////////////////////////////////////////////////////////////
  160. static dMutexGroupID AllocMutexGroup(dThreadingImplementationID impl, dmutexindex_t Mutex_count, const char *const *Mutex_names_ptr/*=NULL*/)
  161. {
  162. (void)Mutex_names_ptr; // unused
  163. dIMutexGroup *mutex_group = ((dxIThreadingImplementation *)impl)->AllocMutexGroup(Mutex_count);
  164. return (dMutexGroupID)mutex_group;
  165. }
  166. static void FreeMutexGroup(dThreadingImplementationID impl, dMutexGroupID mutex_group)
  167. {
  168. ((dxIThreadingImplementation *)impl)->FreeMutexGroup((dIMutexGroup *)mutex_group);
  169. }
  170. static void LockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index)
  171. {
  172. ((dxIThreadingImplementation *)impl)->LockMutexGroupMutex((dIMutexGroup *)mutex_group, mutex_index);
  173. }
  174. // static int TryLockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index)
  175. // {
  176. // bool trylock_result = ((dxIThreadingImplementation *)impl)->TryLockMutexGroupMutex((dIMutexGroup *)mutex_group, mutex_index);
  177. // return trylock_result;
  178. // }
  179. static void UnlockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index)
  180. {
  181. ((dxIThreadingImplementation *)impl)->UnlockMutexGroupMutex((dIMutexGroup *)mutex_group, mutex_index);
  182. }
  183. static dCallWaitID AllocThreadedCallWait(dThreadingImplementationID impl)
  184. {
  185. dxICallWait *call_wait = ((dxIThreadingImplementation *)impl)->AllocACallWait();
  186. return (dCallWaitID)call_wait;
  187. }
  188. static void ResetThreadedCallWait(dThreadingImplementationID impl, dCallWaitID call_wait)
  189. {
  190. ((dxIThreadingImplementation *)impl)->ResetACallWait((dxICallWait *)call_wait);
  191. }
  192. static void FreeThreadedCallWait(dThreadingImplementationID impl, dCallWaitID call_wait)
  193. {
  194. ((dxIThreadingImplementation *)impl)->FreeACallWait((dxICallWait *)call_wait);
  195. }
  196. static void PostThreadedCall(
  197. dThreadingImplementationID impl, int *out_summary_fault/*=NULL*/,
  198. dCallReleaseeID *out_post_releasee/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/,
  199. dCallWaitID call_wait/*=NULL*/,
  200. dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index,
  201. const char *call_name/*=NULL*/)
  202. {
  203. (void)call_name; // unused
  204. ((dxIThreadingImplementation *)impl)->ScheduleNewJob(out_summary_fault, out_post_releasee,
  205. dependencies_count, dependent_releasee, (dxICallWait *)call_wait, call_func, call_context, instance_index);
  206. }
  207. static void AlterThreadedCallDependenciesCount(
  208. dThreadingImplementationID impl, dCallReleaseeID target_releasee,
  209. ddependencychange_t dependencies_count_change)
  210. {
  211. ((dxIThreadingImplementation *)impl)->AlterJobDependenciesCount(target_releasee, dependencies_count_change);
  212. }
  213. static void WaitThreadedCall(
  214. dThreadingImplementationID impl, int *out_wait_status/*=NULL*/,
  215. dCallWaitID call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/,
  216. const char *wait_name/*=NULL*/)
  217. {
  218. (void)wait_name; // unused
  219. ((dxIThreadingImplementation *)impl)->WaitJobCompletion(out_wait_status, (dxICallWait *)call_wait, timeout_time_ptr);
  220. }
  221. static unsigned RetrieveThreadingThreadCount(dThreadingImplementationID impl)
  222. {
  223. return ((dxIThreadingImplementation *)impl)->RetrieveActiveThreadsCount();
  224. }
  225. static int PreallocateResourcesForThreadedCalls(dThreadingImplementationID impl, ddependencycount_t max_simultaneous_calls_estimate)
  226. {
  227. return ((dxIThreadingImplementation *)impl)->PreallocateJobInfos(max_simultaneous_calls_estimate);
  228. }