|
typedef TemplateAutoLock< Mutex > | AutoLock |
|
typedef TemplateAutoLock< RecursiveMutex > | RecursiveAutoLock |
|
template<typename Tp > |
using | TAutoLock = TemplateAutoLock< Tp > |
|
template<typename T > |
using | decay_t = typename std::decay< T >::type |
|
template<bool B, typename T = void> |
using | enable_if_t = typename std::enable_if< B, T >::type |
|
template<typename Tp , typename Arg = Tp> |
using | TBBTaskGroup = TaskGroup< Tp, Arg > |
|
using | tbb_global_control_t = tbb::global_control |
|
using | tbb_task_group_t = tbb::task_group |
|
template<typename Tp > |
using | Future = std::future< Tp > |
|
template<typename Tp > |
using | SharedFuture = std::shared_future< Tp > |
|
template<typename Tp > |
using | Promise = std::promise< Tp > |
|
typedef std::mutex | Mutex |
|
typedef std::recursive_mutex | RecursiveMutex |
|
typedef void * | ThreadFunReturnType |
|
typedef void * | ThreadFunArgType |
|
typedef int(* | thread_lock) (Mutex *) |
|
typedef int(* | thread_unlock) (Mutex *) |
|
typedef std::thread | Thread |
|
typedef std::thread::native_handle_type | NativeThread |
|
typedef std::thread::id | Pid_t |
|
typedef std::condition_variable | Condition |
|
typedef Thread::id | ThreadId |
|
template<typename... Tp> |
using | TypeList = Tuple< Tp... > |
|
template<typename List , typename NewElement > |
using | PushBack = typename PushBackT< List, NewElement >::Type |
|
template<typename List > |
using | PopFront = typename PopFrontT< List >::Type |
|
template<typename List , typename NewElement > |
using | PushFront = typename PushFrontT< List, NewElement >::Type |
|
template<typename List , template< typename T > class MetaFun> |
using | Transform = typename TransformT< List, MetaFun >::Type |
|
template<typename Tp > |
using | EnvChoice = std::tuple< Tp, std::string, std::string > |
|
template<typename Tp > |
using | EnvChoiceList = std::set< EnvChoice< Tp > > |
|
|
template<class T1 , class T2 > |
bool | operator== (const TaskAllocatorImpl< T1 > &, const TaskAllocatorImpl< T2 > &) throw () |
|
template<class T1 , class T2 > |
bool | operator!= (const TaskAllocatorImpl< T1 > &, const TaskAllocatorImpl< T2 > &) throw () |
|
template<typename Tp > |
Mutex & | TypeMutex (const unsigned int &_n=0) |
|
template<typename Tp > |
RecursiveMutex & | TypeRecursiveMutex (const unsigned int &_n=0) |
|
template<typename WorkerT , typename FuncT , typename... Args> |
void | THREADCREATE (WorkerT *&worker, FuncT func, Args... args) |
|
template<unsigned H, typename T > |
T & | get_height (TupleElt< H, T > &te) |
|
template<unsigned I, typename... Elements> |
auto | get (Tuple< Elements... > &t) -> decltype(get_height< sizeof...(Elements) - I - 1 >(t)) |
|
template<typename... Types, typename V > |
PushFront< std::tuple< Types... >, V > | pushFront (std::tuple< Types... > const &tuple, V const &value) |
|
template<typename Func , typename Tuple > |
void | for_each_tuple_arg (Func &&func, Tuple &&_tuple) |
|
template<typename Func , typename Tuple , std::size_t Head> |
auto | InvokeSequence_impl (const Func &func, const Tuple &data) |
|
template<typename Func , typename Tuple , std::size_t Head, std::size_t... Tail> |
auto | InvokeSequence_impl (const Func &func, const Tuple &data) |
|
template<typename Func , typename Tuple , std::size_t N = std::tuple_size<Tuple>::value, typename Indices = std::make_index_sequence<N>> |
auto | InvokeSequence (const Func &func, const Tuple &data) |
|
template<typename Container , std::size_t... N> |
auto | ContainerToTuple_impl (const Container &tasks, std::index_sequence< N... >) |
|
template<std::size_t N, typename Container , typename Indices = std::make_index_sequence<N>> |
auto | ContainerToTuple (const Container &tasks) |
|
template<typename Head > |
void | tuple_transform (const std::function< void(const Head &)> &pred, const std::tuple< Head > &data) |
|
template<typename Head , typename... Tail> |
void | tuple_transform (const std::function< void(const Head &)> &pred, const std::tuple< Head, Tail... > &data) |
|
template<typename Func , typename... Elements, unsigned... Indices> |
auto | applyImpl (Func func, std::tuple< Elements... > const &t, Valuelist< unsigned, Indices... >) -> decltype(func(std::get< Indices >(t)...)) |
|
template<typename Func , typename... Elements, unsigned N = sizeof...(Elements)> |
auto | apply (Func func, std::tuple< Elements... > const &t) -> decltype(applyImpl(func, t, std::make_index_sequence< N >())) |
|
template<typename Tp , typename Tag = api::native, typename Ptr = std::shared_ptr<Tp>, typename Pair = std::pair<Ptr, Ptr>> |
Pair & | GetSharedPointerPair () |
|
template<typename Tp , typename Tag = api::native, typename Ptr = std::shared_ptr<Tp>, typename Pair = std::pair<Ptr, Ptr>> |
Ptr | GetSharedPointerPairInstance () |
|
template<typename Tp , typename Tag = api::native, typename Ptr = std::shared_ptr<Tp>, typename Pair = std::pair<Ptr, Ptr>> |
Ptr | GetSharedPointerPairMasterInstance () |
|
template<typename... Args> |
void | ConsumeParameters (Args...) |
|
template<typename Tp > |
Tp | GetEnv (const std::string &env_id, Tp _default=Tp()) |
|
template<> |
bool | GetEnv (const std::string &env_id, bool _default) |
|
template<typename Tp > |
Tp | GetEnv (const std::string &env_id, Tp _default, const std::string &msg) |
|
template<typename Tp > |
Tp | GetEnv (const std::string &env_id, const EnvChoiceList< Tp > &_choices, Tp _default) |
|
template<typename Tp > |
Tp | GetChoice (const EnvChoiceList< Tp > &_choices, const std::string str_var) |
|
void | PrintEnv (std::ostream &os=std::cout) |
|
Class Description:
This class provides a mechanism to create a mutex and locks/unlocks it. Can be used by applications to implement in a portable way a mutexing logic. Usage Example:
#include "Threading.hh"
#include "AutoLock.hh"
/// defined somewhere -- static so all threads see the same mutex
static Mutex aMutex;
/// somewhere else:
/// The AutoLock instance will automatically unlock the mutex when it
/// goes out of scope. One typically defines the scope within { } if
/// there is thread-safe code following the auto-lock
{
AutoLock l(&aMutex);
ProtectedCode();
}
UnprotectedCode();
/// When ProtectedCode() is calling a function that also tries to lock
/// a normal AutoLock + Mutex will "deadlock". In other words, the
/// the mutex in the ProtectedCode() function will wait forever to
/// acquire the lock that is being held by the function that called
/// ProtectedCode(). In this situation, use a RecursiveAutoLock +
/// RecursiveMutex, e.g.
/// defined somewhere -- static so all threads see the same mutex
static RecursiveMutex aRecursiveMutex;
/// this function is sometimes called directly and sometimes called
/// from SomeFunction_B(), which also locks the mutex
void SomeFunction_A()
{
/// when called from SomeFunction_B(), a Mutex + AutoLock will
/// deadlock
RecursiveAutoLock l(&aRecursiveMutex);
/// do something
}
void SomeFunction_B()
{
{
RecursiveAutoLock l(&aRecursiveMutex);
SomeFunction_A();
}
UnprotectedCode();
}
Author: Andrea Dotti (15 Feb 2013): First Implementation
Update: Jonathan Madsen (9 Feb 2018): Replaced custom implementation with inheritance from C++11 unique_lock, which inherits the following member functions:
- unique_lock(unique_lock&& other) noexcept;
- explicit unique_lock(mutex_type& m);
- unique_lock(mutex_type& m, std::defer_lock_t t) noexcept;
- unique_lock(mutex_type& m, std::try_to_lock_t t);
- unique_lock(mutex_type& m, std::adopt_lock_t t);
- template <typename Rep, typename Period> unique_lock(mutex_type& m,
const std::chrono::duration<Rep,Period>&
timeout_duration);
- template<typename Clock, typename Duration> unique_lock(mutex_type& m,
const std::chrono::time_point<Clock,Duration>& timeout_time);
- void lock();
- void unlock();
- bool try_lock();
- template <typename Rep, typename Period> bool try_lock_for(const std::chrono::duration<Rep,Period>&);
- template <typename Rep, typename Period> bool try_lock_until(const std::chrono::time_point<Clock,Duration>&);
- void swap(unique_lock& other) noexcept;
- mutex_type* release() noexcept;
- mutex_type* mutex() const noexcept;
- bool owns_lock() const noexcept;
- explicit operator bool() const noexcept;
- unique_lock& operator=(unique_lock&& other);
Note that AutoLock is defined also for a sequential Tasking build but below regarding implementation (also found in Threading.hh)
NOTE ON Tasking SERIAL BUILDS AND MUTEX/UNIQUE_LOCK
==================================================
Mutex and RecursiveMutex are always C++11 std::mutex types however, in serial mode, using MUTEXLOCK and MUTEXUNLOCK on these types has no effect – i.e. the mutexes are not actually locked or unlocked
Additionally, when a Mutex or RecursiveMutex is used with AutoLock and RecursiveAutoLock, respectively, these classes also suppressing the locking and unlocking of the mutex. Regardless of the build type, AutoLock and RecursiveAutoLock inherit from std::unique_lock<std::mutex> and std::unique_lock<std::recursive_mutex>, respectively. This means that in situations (such as is needed by the analysis category), the AutoLock and RecursiveAutoLock can be passed to functions requesting a std::unique_lock. Within these functions, since std::unique_lock member functions are not virtual, they will not retain the dummy locking and unlocking behavior --> An example of this behavior can be found below
Jonathan R. Madsen (February 21, 2018)