| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- /*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. *
- * All rights reserved. Email: [email protected] Web: www.q12.org *
- * *
- * Threading subsystem implementation file. *
- * Copyright (C) 2011-2012 Oleh Derevenko. All rights reserved. *
- * e-mail: [email protected] (change all "a" to "e") *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
- /*
- * Subsystem APIs implementation for built-in threading support provider.
- */
- #include <ode/common.h>
- #include <ode/threading_impl.h>
- #include "config.h"
- #include "threading_impl_posix.h"
- #include "threading_impl_win.h"
- #include "threading_impl.h"
- static dMutexGroupID AllocMutexGroup(dThreadingImplementationID impl, dmutexindex_t Mutex_count, const char *const *Mutex_names_ptr/*=NULL*/);
- static void FreeMutexGroup(dThreadingImplementationID impl, dMutexGroupID mutex_group);
- static void LockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);
- // static int TryLockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);
- static void UnlockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index);
- static dCallWaitID AllocThreadedCallWait(dThreadingImplementationID impl);
- static void ResetThreadedCallWait(dThreadingImplementationID impl, dCallWaitID call_wait);
- static void FreeThreadedCallWait(dThreadingImplementationID impl, dCallWaitID call_wait);
- static void PostThreadedCall(
- dThreadingImplementationID impl, int *out_summary_fault/*=NULL*/,
- dCallReleaseeID *out_post_releasee/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/,
- dCallWaitID call_wait/*=NULL*/,
- dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index,
- const char *call_name/*=NULL*/);
- static void AlterThreadedCallDependenciesCount(
- dThreadingImplementationID impl, dCallReleaseeID target_releasee,
- ddependencychange_t dependencies_count_change);
- static void WaitThreadedCall(
- dThreadingImplementationID impl, int *out_wait_status/*=NULL*/,
- dCallWaitID call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/,
- const char *wait_name/*=NULL*/);
- static unsigned RetrieveThreadingThreadCount(dThreadingImplementationID impl);
- static int PreallocateResourcesForThreadedCalls(dThreadingImplementationID impl, ddependencycount_t max_simultaneous_calls_estimate);
- static const dxThreadingFunctionsInfo g_builtin_threading_functions =
- {
- sizeof(dxThreadingFunctionsInfo), // unsigned struct_size;
- &AllocMutexGroup, // dMutexGroupAllocFunction *alloc_mutex_group;
- &FreeMutexGroup, // dMutexGroupFreeFunction *free_mutex_group;
- &LockMutexGroupMutex, // dMutexGroupMutexLockFunction *lock_group_mutex;
- &UnlockMutexGroupMutex, // dMutexGroupMutexUnlockFunction *unlock_group_mutex;
- &AllocThreadedCallWait, // dThreadedCallWaitAllocFunction *alloc_call_wait;
- &ResetThreadedCallWait, // dThreadedCallWaitResetFunction *reset_call_wait;
- &FreeThreadedCallWait, // dThreadedCallWaitFreeFunction *free_call_wait;
- &PostThreadedCall, // dThreadedCallPostFunction *post_call;
- &AlterThreadedCallDependenciesCount, // dThreadedCallDependenciesCountAlterFunction *alter_call_dependencies_count;
- &WaitThreadedCall, // dThreadedCallWaitFunction *wait_call;
- &RetrieveThreadingThreadCount, // dThreadingImplThreadCountRetrieveFunction *retrieve_thread_count;
- &PreallocateResourcesForThreadedCalls, // dThreadingImplResourcesForCallsPreallocateFunction *preallocate_resources_for_calls;
- // &TryLockMutexGroupMutex, // dMutexGroupMutexTryLockFunction *trylock_group_mutex;
- };
- /*extern */dThreadingImplementationID dThreadingAllocateSelfThreadedImplementation()
- {
- dxSelfThreadedThreading *threading = new dxSelfThreadedThreading();
- if (threading != NULL && !threading->InitializeObject())
- {
- delete threading;
- threading = NULL;
- }
- dxIThreadingImplementation *impl = threading;
- return (dThreadingImplementationID)impl;
- }
- /*extern */dThreadingImplementationID dThreadingAllocateMultiThreadedImplementation()
- {
- #if dBUILTIN_THREADING_IMPL_ENABLED
- dxMultiThreadedThreading *threading = new dxMultiThreadedThreading();
- if (threading != NULL && !threading->InitializeObject())
- {
- delete threading;
- threading = NULL;
- }
- #else
- dxIThreadingImplementation *threading = NULL;
- #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
- dxIThreadingImplementation *impl = threading;
- return (dThreadingImplementationID)impl;
- }
- /*extern */const dThreadingFunctionsInfo *dThreadingImplementationGetFunctions(dThreadingImplementationID impl)
- {
- #if dBUILTIN_THREADING_IMPL_ENABLED
- dAASSERT(impl != NULL);
- #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
- const dThreadingFunctionsInfo *functions = NULL;
- #if !dBUILTIN_THREADING_IMPL_ENABLED
- if (impl != NULL)
- #endif // #if !dBUILTIN_THREADING_IMPL_ENABLED
- {
- functions = &g_builtin_threading_functions;
- }
- return functions;
- }
- /*extern */void dThreadingImplementationShutdownProcessing(dThreadingImplementationID impl)
- {
- #if dBUILTIN_THREADING_IMPL_ENABLED
- dAASSERT(impl != NULL);
- #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
- #if !dBUILTIN_THREADING_IMPL_ENABLED
- if (impl != NULL)
- #endif // #if !dBUILTIN_THREADING_IMPL_ENABLED
- {
- ((dxIThreadingImplementation *)impl)->ShutdownProcessing();
- }
- }
- /*extern */void dThreadingImplementationCleanupForRestart(dThreadingImplementationID impl)
- {
- #if dBUILTIN_THREADING_IMPL_ENABLED
- dAASSERT(impl != NULL);
- #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
- #if !dBUILTIN_THREADING_IMPL_ENABLED
- if (impl != NULL)
- #endif // #if !dBUILTIN_THREADING_IMPL_ENABLED
- {
- ((dxIThreadingImplementation *)impl)->CleanupForRestart();
- }
- }
- /*extern */void dThreadingFreeImplementation(dThreadingImplementationID impl)
- {
- if (impl != NULL)
- {
- ((dxIThreadingImplementation *)impl)->FreeInstance();
- }
- }
- /*extern */void dExternalThreadingServeMultiThreadedImplementation(dThreadingImplementationID impl,
- dThreadReadyToServeCallback *readiness_callback/*=NULL*/, void *callback_context/*=NULL*/)
- {
- #if dBUILTIN_THREADING_IMPL_ENABLED
- dAASSERT(impl != NULL);
- #endif // #if dBUILTIN_THREADING_IMPL_ENABLED
- #if !dBUILTIN_THREADING_IMPL_ENABLED
- if (impl != NULL)
- #endif // #if !dBUILTIN_THREADING_IMPL_ENABLED
- {
- ((dxIThreadingImplementation *)impl)->StickToJobsProcessing(readiness_callback, callback_context);
- }
- }
- //////////////////////////////////////////////////////////////////////////
- static dMutexGroupID AllocMutexGroup(dThreadingImplementationID impl, dmutexindex_t Mutex_count, const char *const *Mutex_names_ptr/*=NULL*/)
- {
- (void)Mutex_names_ptr; // unused
- dIMutexGroup *mutex_group = ((dxIThreadingImplementation *)impl)->AllocMutexGroup(Mutex_count);
- return (dMutexGroupID)mutex_group;
- }
- static void FreeMutexGroup(dThreadingImplementationID impl, dMutexGroupID mutex_group)
- {
- ((dxIThreadingImplementation *)impl)->FreeMutexGroup((dIMutexGroup *)mutex_group);
- }
- static void LockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index)
- {
- ((dxIThreadingImplementation *)impl)->LockMutexGroupMutex((dIMutexGroup *)mutex_group, mutex_index);
- }
- // static int TryLockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index)
- // {
- // bool trylock_result = ((dxIThreadingImplementation *)impl)->TryLockMutexGroupMutex((dIMutexGroup *)mutex_group, mutex_index);
- // return trylock_result;
- // }
- static void UnlockMutexGroupMutex(dThreadingImplementationID impl, dMutexGroupID mutex_group, dmutexindex_t mutex_index)
- {
- ((dxIThreadingImplementation *)impl)->UnlockMutexGroupMutex((dIMutexGroup *)mutex_group, mutex_index);
- }
- static dCallWaitID AllocThreadedCallWait(dThreadingImplementationID impl)
- {
- dxICallWait *call_wait = ((dxIThreadingImplementation *)impl)->AllocACallWait();
- return (dCallWaitID)call_wait;
- }
- static void ResetThreadedCallWait(dThreadingImplementationID impl, dCallWaitID call_wait)
- {
- ((dxIThreadingImplementation *)impl)->ResetACallWait((dxICallWait *)call_wait);
- }
- static void FreeThreadedCallWait(dThreadingImplementationID impl, dCallWaitID call_wait)
- {
- ((dxIThreadingImplementation *)impl)->FreeACallWait((dxICallWait *)call_wait);
- }
- static void PostThreadedCall(
- dThreadingImplementationID impl, int *out_summary_fault/*=NULL*/,
- dCallReleaseeID *out_post_releasee/*=NULL*/, ddependencycount_t dependencies_count, dCallReleaseeID dependent_releasee/*=NULL*/,
- dCallWaitID call_wait/*=NULL*/,
- dThreadedCallFunction *call_func, void *call_context, dcallindex_t instance_index,
- const char *call_name/*=NULL*/)
- {
- (void)call_name; // unused
- ((dxIThreadingImplementation *)impl)->ScheduleNewJob(out_summary_fault, out_post_releasee,
- dependencies_count, dependent_releasee, (dxICallWait *)call_wait, call_func, call_context, instance_index);
- }
- static void AlterThreadedCallDependenciesCount(
- dThreadingImplementationID impl, dCallReleaseeID target_releasee,
- ddependencychange_t dependencies_count_change)
- {
- ((dxIThreadingImplementation *)impl)->AlterJobDependenciesCount(target_releasee, dependencies_count_change);
- }
- static void WaitThreadedCall(
- dThreadingImplementationID impl, int *out_wait_status/*=NULL*/,
- dCallWaitID call_wait, const dThreadedWaitTime *timeout_time_ptr/*=NULL*/,
- const char *wait_name/*=NULL*/)
- {
- (void)wait_name; // unused
- ((dxIThreadingImplementation *)impl)->WaitJobCompletion(out_wait_status, (dxICallWait *)call_wait, timeout_time_ptr);
- }
- static unsigned RetrieveThreadingThreadCount(dThreadingImplementationID impl)
- {
- return ((dxIThreadingImplementation *)impl)->RetrieveActiveThreadsCount();
- }
- static int PreallocateResourcesForThreadedCalls(dThreadingImplementationID impl, ddependencycount_t max_simultaneous_calls_estimate)
- {
- return ((dxIThreadingImplementation *)impl)->PreallocateJobInfos(max_simultaneous_calls_estimate);
- }
|