diff options
Diffstat (limited to 'libs/ode-0.16.1/ode/src/threading_impl.cpp')
-rw-r--r-- | libs/ode-0.16.1/ode/src/threading_impl.cpp | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/libs/ode-0.16.1/ode/src/threading_impl.cpp b/libs/ode-0.16.1/ode/src/threading_impl.cpp new file mode 100644 index 0000000..aa30883 --- /dev/null +++ b/libs/ode-0.16.1/ode/src/threading_impl.cpp @@ -0,0 +1,282 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * Threading subsystem implementation file. * + * Copyright (C) 2011-2019 Oleh Derevenko. All rights reserved. * + * e-mail: odar@eleks.com (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); +} + + |