86f4bb48be
- C3d aggiornamento delle librerie ( 117960).
634 lines
32 KiB
C++
634 lines
32 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
\file
|
|
\brief \ru Реализация блокировок на базе системных механизмов синхронизации
|
|
и OpenMP блокировок.
|
|
\en Locks implementation on base of system synchronization mechanisms
|
|
and OpenMP locks. \~
|
|
details \ru Реализация блокировок (в том числе блокировки в области видимости)
|
|
на базе системных механизмов синхронизации и OpenMP блокировок.\n
|
|
\en Implementation of locks (including scoped lock) on base of
|
|
system synchronization mechanisms and OpenMP locks.\n \~
|
|
*/
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
#ifndef __TOOL_MUTEX_H
|
|
#define __TOOL_MUTEX_H
|
|
|
|
#include <math_define.h>
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
/**
|
|
\brief \ru Режимы многопоточных вычислений.
|
|
\en Multithreading modes. \~
|
|
\details \ru Режимы многопоточных вычислений. Режим многопоточности ядра управляет механизмом потокобезопасности объектов ядра и определяет, какие операции ядра будут распараллеливаться. \n
|
|
\en Multithreading modes. Multithreading mode of the kernel manages the mechanism of thread-safity of the kernel objects and defines which \n \~
|
|
\ingroup Data_Structures
|
|
*/
|
|
//---
|
|
enum MbeMultithreadedMode
|
|
{
|
|
///< \ru Многопоточность ядра полностью отключена. Не разрешено использовать интерфейсы ядра в многопоточных вычислениях.
|
|
///< \en Kernel multithreading is completely disabled. Using kernel interfaces in parallel computing is prohibited.
|
|
mtm_Off = 0,
|
|
///< \ru Разрешена многопоточная обработка только для объектов, не имеющих общих данных (независимых объектов). Включены внутренние многопоточные вычисления только для независимых объектов.
|
|
///< \en Allowed parallel processing of objects that do not have common data (independent objects). Enabled internal multi-threaded calculations only for independent objects.
|
|
mtm_Standard = 1,
|
|
///< \ru Обеспечивается потокобезопасность интерфейсов ядра. Разрешено использовать все интерфейсы ядра в многопоточных вычислениях. При этом включены внутренние многопоточные вычисления только для независимых объектов.
|
|
///< \en Ensured thread safety of kernel interfaces. Allowed using all kernel interfaces in parallel computing. Enabled internal multithreaded calculations only for independent objects.
|
|
mtm_SafeItems = 2,
|
|
///< \ru Обеспечивается потокобезопасность объектов ядра. Разрешено использовать все интерфейсы ядра в многопоточных вычислениях. Полностью включены внутренние многопоточные вычисления.
|
|
///< \en Ensured thread-safety of kernel interfaces. Allowed using all kernel interfaces in parallel computing. Enabled all internal parallel calculations in the kernel.
|
|
mtm_Items = 3,
|
|
///< \ru Включена максимальная многопоточность ядра. Можно использовать интерфейсы ядра в параллельных вычислениях. Полностью включены внутренние многопоточные вычисления.
|
|
///< \en Maximal kernel multithreading is ON. Allowed using all kernel interfaces in parallel computing. Enabled all internal parallel calculations in the kernel.
|
|
mtm_Max = 31
|
|
};
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// \ru Поддержка многопоточности в пользовательском приложении.
|
|
//
|
|
// \ru Перед запуском параллельных вычислений, необходимо проверить, что установленный режим
|
|
// многопоточности ядра, позволяет использовать параллельные вычисления.
|
|
// \ru Чтобы использовать интерфейсы ядра в нескольких потоках,
|
|
// \ru в ядре должен быть установлен режим многопоточных вычислений не ниже mtm_SafeItems.
|
|
// \ru По умолчанию в ядре установлен режим максимальной многопоточности.
|
|
//
|
|
// \ru При использовании параллельных вычислений необходимо нотифицировать ядро
|
|
// о входе в параллельный регион и выходе из него.
|
|
// \ru Для этого могут быть использованы:
|
|
// либо класс ParallelRegionGuard (защитник параллельного региона в области видимости),
|
|
// либо парные функции EnterParallelRegion и ExitParallelRegion,
|
|
// либо парные макросы ENTER_PARALLEL и EXIT_PARALLEL.
|
|
//
|
|
// \ru Примеры:
|
|
//
|
|
// // Использование класса ParallelRegionGuard.
|
|
// if( Math::CheckMultithreadedMode( mtm_Items ) ){
|
|
// ParallelRegionGuard l;
|
|
// std::thread t1( function1 );
|
|
// std::thread t2( function2 );
|
|
// t1.join();
|
|
// t2.join();
|
|
// }
|
|
//
|
|
// // Использование функций.
|
|
// if( Math::CheckMultithreadedMode( mtm_Items ) ){
|
|
// EnterParallelRegion();
|
|
// std::thread t1( function1 );
|
|
// std::thread t2( function2 );
|
|
// t1.join();
|
|
// t2.join();
|
|
// ExitParallelRegion();
|
|
// }
|
|
//
|
|
// // Использование макросов.
|
|
// bool useParallel = Math::CheckMultithreadedMode( mtm_Items );
|
|
// ENTER_PARALLEL( useParallel );
|
|
// std::thread t1( function1 );
|
|
// std::thread t2( function2 );
|
|
// t1.join();
|
|
// t2.join();
|
|
// EXIT_PARALLEL( useParallel );
|
|
//
|
|
//
|
|
// \en Support of multithreading in user application.
|
|
//
|
|
// \en Before running parallel calculations, you need to check that the kernel multithreading mode
|
|
// \en allows parallel computing.
|
|
// \en For using the kernel interfaces in several threads, the multithreading mode mtm_SafeItems
|
|
// \en or higher should be defined in the kernel.
|
|
// \en By default, the maximal multithreading mode is set in the kernel.
|
|
//
|
|
// \en While using parallel calculations, you need to notify the kernel about entering
|
|
// \en and exiting a parallel region.
|
|
// \en For that, you can use one of the ways:
|
|
// the class ParallelRegionGuard (a scoped guard of parallel region),
|
|
// \en or the pair of the functions EnterParallelRegion and ExitParallelRegion,
|
|
// or the pair of the macros ENTER_PARALLEL and EXIT_PARALLEL.
|
|
//
|
|
// \en Examples:
|
|
//
|
|
// // Using the ParallelRegionGuard class.
|
|
// if( Math::CheckMultithreadedMode( mtm_Items ) )
|
|
// {
|
|
// ParallelRegionGuard l;
|
|
// std::thread t1( function1 );
|
|
// std::thread t2( function2 );
|
|
// t1.join();
|
|
// t2.join();
|
|
// }
|
|
//
|
|
// // Using the pair of the functions.
|
|
// if( Math::CheckMultithreadedMode( mtm_Items ) )
|
|
// {
|
|
// EnterParallelRegion();
|
|
// std::thread t1( function1 );
|
|
// std::thread t2( function2 );
|
|
// t1.join();
|
|
// t2.join();
|
|
// ExitParallelRegion();
|
|
// }
|
|
//
|
|
// // Using the pair of the macros.
|
|
// bool useParallel = Math::CheckMultithreadedMode( mtm_Items );
|
|
// ENTER_PARALLEL( useParallel );
|
|
// std::thread t1( function1 );
|
|
// std::thread t2( function2 );
|
|
// t1.join();
|
|
// t2.join();
|
|
// EXIT_PARALLEL( useParallel );
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// \ru Управление блокировками.
|
|
// \en Locks management. \~
|
|
//
|
|
// \ru Переменная C3D_NATIVE_LOCK включает использование блокировок на базе
|
|
// \ru системных механизмов синхронизации вместо OpenMP,
|
|
// \ru что позволяет использовать механизмы распараллеливания, отличные от OpenMP.
|
|
//
|
|
// \en The variable C3D_NATIVE_LOCK enables using locks on base of system
|
|
// \en synchronization mechanisms instead of OpenMP, that allows
|
|
// \en use of parallelization frameworks, other than OpenMP. \~
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
#define C3D_NATIVE_LOCK
|
|
|
|
|
|
#ifdef C3D_NATIVE_LOCK
|
|
class ToolLock;
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Класс блокировки. \en Lock class. \~
|
|
\details \ru Класс блокировки (реализация на базе системных механизмов синхронизации).
|
|
\en Lock class (implementation on base of system synchronization mechanisms). \~
|
|
\ingroup Base_Tools
|
|
*/
|
|
// ---
|
|
class MATH_CLASS CommonMutex
|
|
{
|
|
ToolLock* m_lock;
|
|
public:
|
|
CommonMutex();
|
|
~CommonMutex();
|
|
|
|
/** \brief \ru Установить блокировку. \en Set a lock. \~
|
|
*/
|
|
void Lock();
|
|
/** \brief \ru Снять блокировку. \en Unset a lock. \~
|
|
*/
|
|
void Unlock();
|
|
|
|
private:
|
|
// \ru Запрет копирования. \en Copy forbidden.
|
|
CommonMutex ( const CommonMutex& );
|
|
CommonMutex& operator = ( const CommonMutex& );
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Одинаковая реализация CommonMutex и CommonRecursiveMutex.
|
|
\en Same implementation of CommonMutex and CommonRecursiveMutex. \~
|
|
\ingroup Base_Tools
|
|
*/
|
|
#define CommonRecursiveMutex CommonMutex
|
|
|
|
#else // C3D_NATIVE_LOCK
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Класс блокировки.
|
|
\en Lock class. \~
|
|
\details \ru Класс блокировки на базе OpenMP lock.
|
|
\en Lock class on base of OpenMP lock. \~
|
|
\ingroup Base_Tools
|
|
*/
|
|
// ---
|
|
class MATH_CLASS CommonMutex
|
|
{
|
|
omp_lock_t m_lock;
|
|
public:
|
|
// For correct work, CommonMutex implementation should be encapsulated in cpp.
|
|
CommonMutex();
|
|
~CommonMutex();
|
|
void lock();
|
|
void unlock();
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Класс блокировки на базе вложенного OpenMP lock.
|
|
\en Wrapper for nested OpenMP lock. \~
|
|
\ingroup Base_Tools
|
|
*/
|
|
// ---
|
|
class MATH_CLASS CommonRecursiveMutex
|
|
{
|
|
omp_nest_lock_t m_lock;
|
|
public:
|
|
// For correct work, CommonRecursiveMutex implementation should be encapsulated in cpp.
|
|
CommonRecursiveMutex();
|
|
~CommonRecursiveMutex();
|
|
void lock();
|
|
void unlock();
|
|
};
|
|
|
|
#endif // C3D_NATIVE_LOCK
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Защитник параллельного региона в области видимости.
|
|
\en Scoped guard of parallel region. \~
|
|
\details \ru Класс защищает регион кода, выполняющийся параллельно. Работает в области видимости.
|
|
Должен использоваться для защиты параллельного кода.
|
|
Пример использования:
|
|
if( Math::CheckMultithreadedMode( mtm_Items ) )
|
|
{
|
|
ParallelRegionGuard l;
|
|
std::thread t1( function1 );
|
|
std::thread t2( function2 );
|
|
t1.join();
|
|
t2.join();
|
|
}
|
|
\en The class guards a code region running in parallel. Works in scope.
|
|
Should be used to protect parallel code.
|
|
Example of use:
|
|
if( Math::CheckMultithreadedMode( mtm_Items ) )
|
|
{
|
|
ParallelRegionGuard l;
|
|
std::thread t1( function1 );
|
|
std::thread t2( function2 );
|
|
t1.join();
|
|
t2.join();
|
|
}
|
|
\ingroup Base_Tools
|
|
*/
|
|
// ---
|
|
class MATH_CLASS ParallelRegionGuard
|
|
{
|
|
public:
|
|
ParallelRegionGuard();
|
|
~ParallelRegionGuard();
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Функция нотифицирует ядро о входе в параллельный блок кода.
|
|
Вызов функции должен стоять перед началом параллельного блока.
|
|
\en The function notifies the kernel about entering a parallel region.
|
|
The function call should be placed before the start of a parallel block
|
|
*/
|
|
// ---
|
|
MATH_FUNC( void ) EnterParallelRegion();
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Функция нотифицирует ядро о выходе из параллельного блока кода.
|
|
Вызов функции должен стоять после окончания параллельного блока.
|
|
\en The function notifies the kernel about exiting a parallel region.
|
|
The function call should be placed after the end of the parallel block.
|
|
*/
|
|
// ---
|
|
MATH_FUNC( void ) ExitParallelRegion();
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// \ru Макросы для нотификации о входе и выходе из параллельного цикла.
|
|
// Вызов макросов при использовании OpenMP не обязателен, однако значительно ускоряет
|
|
// выполнение параллельного цикла.
|
|
// Вызов ENTER_PARALLEL должен стоять перед началом параллельного блока.
|
|
// Вызов EXIT_PARALLEL должен стоять после окончания параллельного блока.
|
|
// Пример использования:
|
|
// bool useParallel = Math::CheckMultithreadedMode( mtm_Items );
|
|
// ENTER_PARALLEL( useParallel );
|
|
// #pragma omp parallel for
|
|
// for ( ptrdiff_t i = 0; i < count; ++i ) {
|
|
// /* Cycle body */
|
|
// }
|
|
// EXIT_PARALLEL( useParallel );
|
|
//
|
|
/// \ru Macros for notification of entering and exiting a parallel block.
|
|
// Calling the macros when using OpenMP is not required, but significantly speeds up
|
|
// the execution of parallel cycle.
|
|
// The call ENTER_PARALLEL should be placed before the start of a parallel block.
|
|
// The call EXIT_PARALLEL should be placed after the end of the parallel block.
|
|
// Example of use:
|
|
// bool useParallel = Math::CheckMultithreadedMode( mtm_Items );
|
|
// ENTER_PARALLEL( useParallel );
|
|
// #pragma omp parallel for
|
|
// for ( ptrdiff_t i = 0; i < count; ++i ) {
|
|
// /* Cycle body */
|
|
// }
|
|
// EXIT_PARALLEL( useParallel );
|
|
// ---
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Если useParallel == true, нотифицирует ядро о входе в параллельный блок кода.
|
|
\en If useParallel == true, notifies the kernel about entering a parallel region.
|
|
\details \ru Если useParallel == true, нотифицирует ядро о входе в параллельный блок кода.
|
|
Вызов должен стоять перед началом параллельного блока (перед прагмой OpenMP).
|
|
Использование макроса значительно ускоряет параллельные циклы OpenMP.
|
|
\en If useParallel == true, notifies the kernel about entering a parallel region.
|
|
The call should be placed before the start of a parallel block (before OpenMP pragma).
|
|
Using a macro speeds up parallel OpenMP cycles significantly.
|
|
*/
|
|
// ---
|
|
#define ENTER_PARALLEL(useParallel) if ( useParallel ) EnterParallelRegion();
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Если useParallel == true, нотифицирует ядро о выходе из параллельного блока кода.
|
|
\en If useParallel == true, notifies the kernel about exiting a parallel region.
|
|
\details \ru Если useParallel == true, нотифицирует ядро о выходе из параллельного блока кода.
|
|
Вызов должен стоять после окончания параллельного блока.
|
|
Использование макроса значительно ускоряет параллельные циклы OpenMP.
|
|
\en If useParallel == true, notifies the kernel about exiting a parallel region.
|
|
The call should be placed after the end of the parallel block.
|
|
Using a macro speeds up parallel OpenMP cycles significantly.
|
|
*/
|
|
// ---
|
|
#define EXIT_PARALLEL(useParallel) if ( useParallel ) ExitParallelRegion();
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Нотифицирует ядро о входе в параллельный блок кода.
|
|
\en Notifies the kernel about entering a parallel region.
|
|
\details \ru Нотифицирует ядро о входе в параллельный блок кода.
|
|
Вызов должен стоять перед началом параллельного блока (перед прагмой OpenMP).
|
|
Использование макроса значительно ускоряет параллельные циклы OpenMP.
|
|
\en Notifies the kernel about entering a parallel region.
|
|
The call should be placed before the start of a parallel block (before OpenMP pragma).
|
|
Using a macro speeds up parallel OpenMP cycles significantly.
|
|
*/
|
|
// ---
|
|
#define ENTER_PARALLEL_FORCED EnterParallelRegion();
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Нотифицирует ядро о выходе из параллельного блока кода.
|
|
\en Notifiesotifies the kernel about exiting a parallel region.
|
|
\details \ru Нотифицирует ядро о выходе из параллельного блока кода.
|
|
Вызов должен стоять после окончания параллельного блока.
|
|
Использование макроса значительно ускоряет параллельные циклы OpenMP.
|
|
\en Notifies the kernel about exiting a parallel region.
|
|
The call should be placed after the end of the parallel block.
|
|
Using a macro speeds up parallel OpenMP cycles significantly.
|
|
*/
|
|
// ---
|
|
#define EXIT_PARALLEL_FORCED ExitParallelRegion();
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Функция определяет, выполняется ли код параллельно.
|
|
\en The function determines whether the code is executed in parallel.
|
|
*/
|
|
// ---
|
|
MATH_FUNC( bool ) IsInParallel();
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Функция определяет, разрешена ли очистка кэшей.
|
|
\en The function determines whether the caches cleanup is allowed.
|
|
*/
|
|
// ---
|
|
MATH_FUNC( bool ) CacheCleanupAllowed();
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// \ru Блокировки и другие средства синхронизации.
|
|
// \en Locks and other synchronization objects. \~
|
|
|
|
// \ru В качестве блокировок должны использоваться CommonMutex и CommonRecursiveMutex
|
|
// \ru (OpenMP lock не должны использоваться напрямую).
|
|
//
|
|
// \en CommonMutex and CommonRecursiveMutex should be used as locks
|
|
// \en (OpenMP locks should not be used directly).
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Блокировка в области видимости. Может принимать нулевой указатель на мьютекс.
|
|
Блокировка происходит, если указатель на мьютекс ненулевой и код выполняется параллельно.
|
|
\en Scoped lock. Can accept a null pointer to a mutex.
|
|
Locking occurs if the pointer to the mutex is nonzero and the code runs in parallel. \~
|
|
\ingroup Base_Tools
|
|
*/
|
|
// ---
|
|
class MATH_CLASS ScopedLock
|
|
{
|
|
CommonMutex* m_mutex;
|
|
public:
|
|
ScopedLock( CommonMutex* mtx, bool parallelCheck = true );
|
|
~ScopedLock();
|
|
|
|
/** \brief \ru Выполнена ли реальная блокировка. \en Whether a real locking performed. \~
|
|
*/
|
|
bool IsLocked();
|
|
|
|
private:
|
|
ScopedLock();
|
|
ScopedLock ( const ScopedLock& );
|
|
ScopedLock& operator = ( const ScopedLock& );
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Рекурсивная блокировка в области видимости. Может принимать нулевой указатель на мьютекс.
|
|
Блокировка происходит, если указатель на мьютекс ненулевой и код выполняется параллельно.
|
|
\en Recursive scoped lock. Can accept a null pointer to a mutex.
|
|
Locking occurs if the pointer to the mutex is nonzero and the code runs in parallel. \~
|
|
\ingroup Base_Tools
|
|
*/
|
|
// ---
|
|
class MATH_CLASS ScopedRecursiveLock
|
|
{
|
|
CommonRecursiveMutex* m_mutex;
|
|
public:
|
|
ScopedRecursiveLock( CommonRecursiveMutex* mtx, bool parallelCheck = true );
|
|
~ScopedRecursiveLock();
|
|
|
|
/** \brief \ru Выполнена ли реальная блокировка. \en Whether a real locking performed. \~
|
|
*/
|
|
bool IsLocked();
|
|
|
|
private:
|
|
ScopedRecursiveLock();
|
|
ScopedRecursiveLock ( const ScopedRecursiveLock& );
|
|
ScopedRecursiveLock& operator = ( const ScopedRecursiveLock& );
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Базовый объект синхронизации с отложенной инициализацией.
|
|
\en Base synchronization object with lazy initialization. \~
|
|
\details \ru Базовый объект, предоставляющий средства синхронизации и создающий блокировку при необходимости. \n
|
|
\en Base object which provides means of synchronization and creates a lock when needed. \n \~
|
|
\ingroup Base_Tools
|
|
*/
|
|
// ---
|
|
class MATH_CLASS MbSyncItem {
|
|
protected:
|
|
mutable CommonMutex * m_comLock; // \ru Критическая секция для монопольного доступа к объекту. \en The critical section for exclusive access to the object.
|
|
mutable int m_locked;
|
|
|
|
public:
|
|
MbSyncItem();
|
|
virtual ~MbSyncItem();
|
|
|
|
/** \brief \ru Включить блокировку (блокировка происходит только при наличии параллельности).
|
|
\en Switch lock on (locking happens only in parallel region).
|
|
*/
|
|
void Lock() const;
|
|
|
|
/** \brief \ru Снять блокировку, если она была установлена.
|
|
\en Switch lock off if locking has been set.
|
|
*/
|
|
void Unlock() const;
|
|
|
|
// \ru Выдать указатель на объект мьютекса. Возращает nullptr, если параллельности нет. Для использования в ScopedLock.
|
|
// \en Get a pointer to the mutex object. Return nullptr if no parallelism. For use in ScopedLock.
|
|
CommonMutex * GetLock() const;
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Базовый объект синхронизации с отложенной инициализацией, поддерживающий множественные блокировки.
|
|
\en Base synchronization object with lazy initialization which supports nested locks. \~
|
|
\details \ru Базовый объект синхронизации, поддерживающий множественные блокировки и создающий блокировку при необходимости. \n
|
|
\en Base synchronization object with support of nested locks which creates a lock if necessary. \n \~
|
|
\ingroup Base_Tools
|
|
*/
|
|
// ---
|
|
class MATH_CLASS MbNestSyncItem {
|
|
protected:
|
|
mutable CommonRecursiveMutex * m_comLock; // \ru Критическая секция для монопольного доступа к объекту. \en The critical section for exclusive access to the object.
|
|
mutable int m_locked;
|
|
|
|
public:
|
|
MbNestSyncItem();
|
|
virtual ~MbNestSyncItem();
|
|
|
|
/** \brief \ru Включить блокировку (блокировка происходит только при наличии параллельности).
|
|
\en Switch lock on (locking happens only in parallel region).
|
|
*/
|
|
void Lock() const;
|
|
|
|
/** \brief \ru Снять блокировку, если она была установлена.
|
|
\en Switch lock off if locking has been set.
|
|
*/
|
|
void Unlock() const;
|
|
|
|
/** \brief \ru Выдать указатель на объект мьютекса. Возращает nullptr, если параллельности нет. Для использования в ScopedLock.
|
|
\en Get a pointer to the mutex object. Return nullptr if no parallelism. For use in ScopedLock.
|
|
*/
|
|
CommonRecursiveMutex * GetLock() const;
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Базовый объект, предоставляющий средства синхронизации.
|
|
\en Base object providing means of synchronization. \~
|
|
\details \ru Базовый объект, предоставляющий средства синхронизации. \n
|
|
\en Base object providing means of synchronization. \n \~
|
|
\ingroup Base_Tools
|
|
*/
|
|
// ---
|
|
class MATH_CLASS MbPersistentSyncItem {
|
|
protected:
|
|
mutable CommonMutex m_comLock; // \ru Критическая секция для монопольного доступа к объекту. \en The critical section for exclusive access to the object.
|
|
mutable int m_locked;
|
|
|
|
public:
|
|
MbPersistentSyncItem();
|
|
virtual ~MbPersistentSyncItem();
|
|
|
|
/** \brief \ru Включить блокировку.
|
|
\en Switch lock on.
|
|
*/
|
|
void Lock() const;
|
|
|
|
/** \brief \ru Снять блокировку, если она была установлена.
|
|
\en Switch lock off if locking has been set.
|
|
*/
|
|
void Unlock() const;
|
|
|
|
/** \brief \ru Выдать указатель на объект мьютекса.
|
|
\en Get a pointer to the mutex object.
|
|
*/
|
|
CommonMutex * GetLock() const;
|
|
|
|
protected:
|
|
MbPersistentSyncItem( const MbPersistentSyncItem & );
|
|
MbPersistentSyncItem & operator = ( const MbPersistentSyncItem & );
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Базовый объект синхронизации, поддерживающий множественные блокировки.
|
|
\en Base synchronization object with support of nested locks. \~
|
|
\details \ru Базовый объект синхронизации, поддерживающий множественные блокировки. \n
|
|
\en Base synchronization object with support of nested locks. \n \~
|
|
\ingroup Base_Tools
|
|
*/
|
|
// ---
|
|
class MATH_CLASS MbPersistentNestSyncItem {
|
|
protected:
|
|
mutable CommonRecursiveMutex m_comLock; // \ru Критическая секция для монопольного доступа к объекту. \en The critical section for exclusive access to the object.
|
|
mutable int m_locked;
|
|
|
|
public:
|
|
MbPersistentNestSyncItem();
|
|
virtual ~MbPersistentNestSyncItem();
|
|
|
|
/** \brief \ru Включить блокировку. \en Switch lock on.
|
|
*/
|
|
void Lock() const;
|
|
|
|
/** \brief \ru Снять блокировку, если она была установлена.
|
|
\en Switch lock off if locking has been set.
|
|
*/
|
|
void Unlock() const;
|
|
|
|
/** \brief \ru Выдать указатель на объект мьютекса.
|
|
\en Get a pointer to the mutex object.
|
|
*/
|
|
CommonRecursiveMutex * GetLock() const;
|
|
|
|
protected:
|
|
MbPersistentNestSyncItem( const MbPersistentNestSyncItem & );
|
|
MbPersistentNestSyncItem & operator = ( const MbPersistentNestSyncItem & );
|
|
};
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Установлен ли режим безопасной многопоточности (используется в CacheManager).
|
|
\en Whether is enabled a safe multithreading mode (used in CacheManager). \~
|
|
\ingroup Base_Tools
|
|
*/
|
|
MATH_FUNC(bool) IsSafeMultithreading();
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Включены ли блокировки (режим многопоточности >= mtm_Standard и код выполняется параллельно).
|
|
\en Whether locks are enabled (multithreading is on and code is executed in parallel). \~
|
|
\ingroup Base_Tools
|
|
*/
|
|
MATH_FUNC( bool ) LocksEnabled();
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Получить псевдо-идентификатор текущего потока.
|
|
\en Get a current thread pseudo-identifier.
|
|
*/
|
|
MATH_FUNC( unsigned int ) GetThreadKey();
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Получить указатель на глобальный мьютекс (используется в CacheManager).
|
|
\en Get a pointer to the global mutex (used in CacheManager).
|
|
*/
|
|
MATH_FUNC( CommonMutex* ) GetGlobalLock();
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Получить указатель на глобальный рекурсивный мьютекс (используется для операций выделения и освобождения памяти).
|
|
\en Get a pointer to the global recursive mutex (used for memory allocation and deallocation operations).
|
|
*/
|
|
MATH_FUNC( CommonRecursiveMutex* ) GetGlobalRecursiveLock();
|
|
|
|
//------------------------------------------------------------------------------
|
|
/** \brief \ru Установить блокировку в области видимости для операций выделения и освобождения памяти.
|
|
\en Set scoped lock for memory allocation and deallocation operations.
|
|
*/
|
|
#define SET_MEMORY_SCOPED_LOCK ScopedRecursiveLock memScopedLock( GetGlobalRecursiveLock() );
|
|
|
|
#endif // __TOOL_MUTEX_H
|