Import Geant4 10.7.0 source tree

This commit is contained in:
Gabriele Cosmo
2020-12-04 12:30:43 +01:00
parent 67ba86d073
commit dab42d2018
3770 changed files with 226369 additions and 286486 deletions
+17 -17
View File
@@ -255,15 +255,15 @@ namespace PTL
// Note: Note that TemplateAutoLock by itself is not thread-safe and
// cannot be shared among threads due to the locked switch
//
template <typename _Mutex_t>
class TemplateAutoLock : public std::unique_lock<_Mutex_t>
template <typename MutexT>
class TemplateAutoLock : public std::unique_lock<MutexT>
{
public:
//------------------------------------------------------------------------//
// Some useful typedefs
//------------------------------------------------------------------------//
typedef std::unique_lock<_Mutex_t> unique_lock_t;
typedef TemplateAutoLock<_Mutex_t> this_type;
typedef std::unique_lock<MutexT> unique_lock_t;
typedef TemplateAutoLock<MutexT> this_type;
typedef typename unique_lock_t::mutex_type mutex_type;
public:
@@ -350,26 +350,26 @@ public:
private:
// helpful macros
#define _is_stand_mutex(_Tp) (std::is_same<_Tp, Mutex>::value)
#define _is_recur_mutex(_Tp) (std::is_same<_Tp, RecursiveMutex>::value)
#define _is_other_mutex(_Tp) (!_is_stand_mutex(_Tp) && !_is_recur_mutex(_Tp))
#define _is_stand_mutex(Tp) (std::is_same<Tp, Mutex>::value)
#define _is_recur_mutex(Tp) (std::is_same<Tp, RecursiveMutex>::value)
#define _is_other_mutex(Tp) (!_is_stand_mutex(Tp) && !_is_recur_mutex(Tp))
template <typename _Tp = _Mutex_t,
typename std::enable_if<_is_stand_mutex(_Tp), int>::type = 0>
template <typename Tp = MutexT,
typename std::enable_if<_is_stand_mutex(Tp), int>::type = 0>
std::string GetTypeString()
{
return "AutoLock<Mutex>";
}
template <typename _Tp = _Mutex_t,
typename std::enable_if<_is_recur_mutex(_Tp), int>::type = 0>
template <typename Tp = MutexT,
typename std::enable_if<_is_recur_mutex(Tp), int>::type = 0>
std::string GetTypeString()
{
return "AutoLock<RecursiveMutex>";
}
template <typename _Tp = _Mutex_t,
typename std::enable_if<_is_other_mutex(_Tp), int>::type = 0>
template <typename Tp = MutexT,
typename std::enable_if<_is_other_mutex(Tp), int>::type = 0>
std::string GetTypeString()
{
return "AutoLock<UNKNOWN_MUTEX>";
@@ -381,8 +381,8 @@ private:
#undef _is_other_mutex
// used in _lock_deferred chrono variants to avoid ununsed-variable warning
template <typename _Tp>
void suppress_unused_variable(const _Tp&)
template <typename Tp>
void suppress_unused_variable(const Tp&)
{}
//========================================================================//
@@ -485,7 +485,7 @@ typedef TemplateAutoLock<RecursiveMutex> RecursiveAutoLock;
// provide abbriviated type if another mutex type is desired to be used
// aside from above
template <typename _Tp>
using TAutoLock = TemplateAutoLock<_Tp>;
template <typename Tp>
using TAutoLock = TemplateAutoLock<Tp>;
} // namespace PTL
+55 -57
View File
@@ -42,7 +42,7 @@
#if !defined(PTL_FOLD_EXPRESSION)
# define PTL_FOLD_EXPRESSION(...) \
::PTL::details::consume_parameters( \
::PTL::mpl::consume_parameters( \
::std::initializer_list<int>{ (__VA_ARGS__, 0)... })
#endif
@@ -55,7 +55,7 @@ template <bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type;
// for pre-C++14 tuple expansion to arguments
namespace details
namespace mpl
{
//--------------------------------------------------------------------------------------//
@@ -71,84 +71,83 @@ namespace impl
//--------------------------------------------------------------------------------------//
// Stores a tuple of indices. Used by tuple and pair, and by bind() to
// extract the elements in a tuple.
template <size_t... _Indexes>
struct _Index_tuple
template <size_t... Indexes>
struct Index_tuple
{};
// Concatenates two _Index_tuples.
template <typename _Itup1, typename _Itup2>
struct _Itup_cat;
// Concatenates two Index_tuples.
template <typename Itup1, typename Itup2>
struct Itup_cat;
template <size_t... _Ind1, size_t... _Ind2>
struct _Itup_cat<_Index_tuple<_Ind1...>, _Index_tuple<_Ind2...>>
template <size_t... Ind1, size_t... Ind2>
struct Itup_cat<Index_tuple<Ind1...>, Index_tuple<Ind2...>>
{
using __type = _Index_tuple<_Ind1..., (_Ind2 + sizeof...(_Ind1))...>;
using __type = Index_tuple<Ind1..., (Ind2 + sizeof...(Ind1))...>;
};
// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
template <size_t _Num>
struct _Build_index_tuple
: _Itup_cat<typename _Build_index_tuple<_Num / 2>::__type,
typename _Build_index_tuple<_Num - _Num / 2>::__type>
// Builds an Index_tuple<0, 1, 2, ..., NumT-1>.
template <size_t NumT>
struct Build_index_tuple
: Itup_cat<typename Build_index_tuple<NumT / 2>::__type,
typename Build_index_tuple<NumT - NumT / 2>::__type>
{};
template <>
struct _Build_index_tuple<1>
struct Build_index_tuple<1>
{
typedef _Index_tuple<0> __type;
typedef Index_tuple<0> __type;
};
template <>
struct _Build_index_tuple<0>
struct Build_index_tuple<0>
{
typedef _Index_tuple<> __type;
typedef Index_tuple<> __type;
};
/// Class template integer_sequence
template <typename _Tp, _Tp... _Idx>
template <typename Tp, Tp... Idx>
struct integer_sequence
{
typedef _Tp value_type;
static constexpr size_t size() noexcept { return sizeof...(_Idx); }
typedef Tp value_type;
static constexpr size_t size() noexcept { return sizeof...(Idx); }
};
template <typename _Tp, _Tp _Num,
typename _ISeq = typename _Build_index_tuple<_Num>::__type>
struct _Make_integer_sequence;
template <typename Tp, Tp NumT, typename ISeq = typename Build_index_tuple<NumT>::__type>
struct Make_integer_sequence;
template <typename _Tp, _Tp _Num, size_t... _Idx>
struct _Make_integer_sequence<_Tp, _Num, _Index_tuple<_Idx...>>
template <typename Tp, Tp NumT, size_t... Idx>
struct Make_integer_sequence<Tp, NumT, Index_tuple<Idx...>>
{
static_assert(_Num >= 0, "Cannot make integer sequence of negative length");
static_assert(NumT >= 0, "Cannot make integer sequence of negative length");
typedef integer_sequence<_Tp, static_cast<_Tp>(_Idx)...> __type;
typedef integer_sequence<Tp, static_cast<Tp>(Idx)...> __type;
};
/// Alias template make_integer_sequence
template <typename _Tp, _Tp _Num>
using make_integer_sequence = typename _Make_integer_sequence<_Tp, _Num>::__type;
template <typename Tp, Tp NumT>
using make_integer_sequence = typename Make_integer_sequence<Tp, NumT>::__type;
/// Alias template index_sequence
template <size_t... _Idx>
using index_sequence = integer_sequence<size_t, _Idx...>;
template <size_t... Idx>
using index_sequence = integer_sequence<size_t, Idx...>;
/// Alias template make_index_sequence
template <size_t _Num>
using make_index_sequence = make_integer_sequence<size_t, _Num>;
template <size_t NumT>
using make_index_sequence = make_integer_sequence<size_t, NumT>;
/// Alias template index_sequence_for
template <typename... _Types>
using index_sequence_for = make_index_sequence<sizeof...(_Types)>;
template <typename... Types>
using index_sequence_for = make_index_sequence<sizeof...(Types)>;
template <size_t I, typename Tup>
using index_type_t = decay_t<decltype(std::get<I>(std::declval<Tup>()))>;
template <size_t Idx, typename Tup>
using index_type_t = decay_t<decltype(std::get<Idx>(std::declval<Tup>()))>;
template <typename _Fn, typename _Tuple, size_t... _Idx>
static inline void
apply(_Fn&& __f, _Tuple&& __t, impl::index_sequence<_Idx...>)
template <typename FnT, typename TupleT, size_t... Idx>
static inline auto
apply(FnT&& __f, TupleT&& __t, impl::index_sequence<Idx...>)
-> decltype(std::forward<FnT>(__f)(std::get<Idx>(__t)...))
{
std::forward<_Fn>(__f)(std::get<_Idx>(std::forward<_Tuple>(__t))...);
// __f(std::get<_Idx>(std::forward<_Tuple>(__t))...);
return std::forward<FnT>(__f)(std::get<Idx>(__t)...);
}
//--------------------------------------------------------------------------------------//
@@ -158,29 +157,29 @@ apply(_Fn&& __f, _Tuple&& __t, impl::index_sequence<_Idx...>)
//--------------------------------------------------------------------------------------//
/// Alias template index_sequence
template <size_t... _Idx>
using index_sequence = impl::integer_sequence<size_t, _Idx...>;
template <size_t... Idx>
using index_sequence = impl::integer_sequence<size_t, Idx...>;
/// Alias template make_index_sequence
template <size_t _Num>
using make_index_sequence = impl::make_integer_sequence<size_t, _Num>;
template <size_t NumT>
using make_index_sequence = impl::make_integer_sequence<size_t, NumT>;
/// Alias template index_sequence_for
template <typename... _Types>
using index_sequence_for = impl::make_index_sequence<sizeof...(_Types)>;
template <typename... Types>
using index_sequence_for = impl::make_index_sequence<sizeof...(Types)>;
template <typename _Fn, typename _Tuple>
template <typename FnT, typename TupleT>
static inline void
apply(_Fn&& __f, _Tuple&& __t)
apply(FnT&& __f, TupleT&& __t)
{
constexpr auto _N = std::tuple_size<_Tuple>::value;
impl::apply(std::forward<_Fn>(__f), std::forward<_Tuple>(__t),
impl::make_index_sequence<_N>{});
constexpr auto N = std::tuple_size<TupleT>::value;
impl::apply(std::forward<FnT>(__f), std::forward<TupleT>(__t),
impl::make_index_sequence<N>{});
}
//--------------------------------------------------------------------------------------//
} // namespace details
} // namespace mpl
namespace thread_pool
{
@@ -192,7 +191,6 @@ static const short STOPPED = 2;
static const short NONINIT = 3;
} // namespace state
} // namespace thread_pool
//--------------------------------------------------------------------------------------//
+36 -14
View File
@@ -64,11 +64,11 @@ public:
typedef typename base_type::packaged_task_type packaged_task_type;
typedef typename base_type::future_type future_type;
typedef typename base_type::promise_type promise_type;
typedef typename base_type::template JoinFunction<Tp, Arg>::Type join_type;
typedef typename JoinFunction<Tp, Arg>::Type join_type;
typedef tbb::task_group tbb_task_group_t;
//------------------------------------------------------------------------//
template <typename... Args>
using task_type = Task<ArgTp, Args...>;
using task_type = Task<ArgTp, decay_t<Args>...>;
//------------------------------------------------------------------------//
public:
@@ -119,36 +119,40 @@ public:
public:
//------------------------------------------------------------------------//
template <typename Func, typename... Args>
task_type<Args...>* wrap(Func&& func, Args&&... args)
task_type<Args...>* wrap(Func&& func, Args... args)
{
return operator+=(new task_type<Args...>(this, std::forward<Func>(func),
std::forward<Args>(args)...));
return operator+=(
new task_type<Args...>(this, std::forward<Func>(func), args...));
}
public:
//------------------------------------------------------------------------//
template <typename Func, typename... Args>
void run(Func&& func, Args&&... args)
void run(Func&& func, Args... args)
{
auto _task = wrap(std::forward<Func>(func), std::forward<Args>(args)...);
auto _func = [=]() { return func(args...); };
auto _task = wrap(std::move(_func));
auto _lamb = [=]() { (*_task)(); };
m_tbb_task_group->run(_lamb);
}
//------------------------------------------------------------------------//
template <typename Func, typename... Args>
void exec(Func&& func, Args&&... args)
void exec(Func&& func, Args... args)
{
run(std::forward<Func>(func), std::forward<Args>(args)...);
auto _func = [=]() { return func(args...); };
auto _task = wrap(std::move(_func));
auto _lamb = [=]() { (*_task)(); };
m_tbb_task_group->run(_lamb);
}
//------------------------------------------------------------------------//
template <typename Func, typename... Args, typename Up = Tp,
enable_if_t<std::is_same<Up, void>::value, int> = 0>
void parallel_for(uintmax_t nitr, uintmax_t, Func&& func, Args&&... args)
void parallel_for(uintmax_t nitr, uintmax_t, Func&& func, Args... args)
{
tbb::parallel_for(tbb::blocked_range<size_t>(0, nitr),
[&](const tbb::blocked_range<size_t>& range) {
for(size_t i = range.begin(); i != range.end(); ++i)
func(std::forward<Args>(args)...);
func(args...);
});
}
@@ -175,18 +179,22 @@ public:
//------------------------------------------------------------------------//
// wait to finish
template <typename Up = Tp, enable_if_t<!std::is_same<Up, void>::value, int> = 0>
template <typename Up = Tp, enable_if_t<!std::is_void<Up>::value, int> = 0>
inline Up join(Up accum = {})
{
this->wait();
for(auto& itr : m_task_set)
accum = m_join(std::ref(accum), std::forward<ArgTp>(itr.get()));
{
using RetT = decay_t<decltype(itr.get())>;
accum = m_join(std::ref(accum), std::forward<RetT>(itr.get()));
}
this->clear();
return accum;
}
//------------------------------------------------------------------------//
// wait to finish
template <typename Up = Tp, enable_if_t<std::is_same<Up, void>::value, int> = 0>
template <typename Up = Tp, typename Rp = Arg,
enable_if_t<std::is_void<Up>::value && std::is_void<Rp>::value, int> = 0>
inline void join()
{
this->wait();
@@ -195,6 +203,20 @@ public:
m_join();
this->clear();
}
//------------------------------------------------------------------------//
// wait to finish
template <typename Up = Tp, typename Rp = Arg,
enable_if_t<std::is_void<Up>::value && !std::is_void<Rp>::value, int> = 0>
inline void join()
{
this->wait();
for(auto& itr : m_task_set)
{
using RetT = decay_t<decltype(itr.get())>;
m_join(std::forward<RetT>(itr.get()));
}
this->clear();
}
protected:
// Protected variables
+70 -72
View File
@@ -46,38 +46,38 @@ class ThreadPool;
//======================================================================================//
/// \brief The task class is supplied to thread_pool.
template <typename _Ret, typename... _Args>
template <typename RetT, typename... Args>
class PackagedTask : public VTask
{
public:
typedef PackagedTask<_Ret, _Args...> this_type;
typedef std::promise<_Ret> promise_type;
typedef std::future<_Ret> future_type;
typedef std::packaged_task<_Ret(_Args...)> packaged_task_type;
typedef _Ret result_type;
typedef std::tuple<_Args...> tuple_type;
typedef PackagedTask<RetT, Args...> this_type;
typedef std::promise<RetT> promise_type;
typedef std::future<RetT> future_type;
typedef std::packaged_task<RetT(Args...)> packaged_task_type;
typedef RetT result_type;
typedef std::tuple<Args...> tuple_type;
public:
// pass a free function pointer
template <typename _Func>
PackagedTask(_Func&& func, _Args&&... args)
template <typename FuncT>
PackagedTask(FuncT&& func, Args... args)
: VTask()
, m_ptask(std::forward<_Func>(func))
, m_args(std::forward<_Args>(args)...)
, m_ptask(std::forward<FuncT>(func))
, m_args(args...)
{}
template <typename _Func>
PackagedTask(VTaskGroup* tg, _Func&& func, _Args&&... args)
template <typename FuncT>
PackagedTask(VTaskGroup* tg, FuncT&& func, Args... args)
: VTask(tg)
, m_ptask(std::forward<_Func>(func))
, m_args(std::forward<_Args>(args)...)
, m_ptask(std::forward<FuncT>(func))
, m_args(args...)
{}
template <typename _Func>
PackagedTask(ThreadPool* _pool, _Func&& func, _Args&&... args)
template <typename FuncT>
PackagedTask(ThreadPool* _pool, FuncT&& func, Args... args)
: VTask(_pool)
, m_ptask(std::forward<_Func>(func))
, m_args(std::forward<_Args>(args)...)
, m_ptask(std::forward<FuncT>(func))
, m_args(args...)
{}
virtual ~PackagedTask() {}
@@ -86,8 +86,7 @@ public:
// execution operator
virtual void operator()() override
{
details::apply(std::forward<packaged_task_type>(m_ptask),
std::forward<tuple_type>(m_args));
mpl::apply(std::move(m_ptask), std::move(m_args));
}
future_type get_future() { return m_ptask.get_future(); }
virtual bool is_native_task() const override { return true; }
@@ -100,37 +99,37 @@ private:
//======================================================================================//
/// \brief The task class is supplied to thread_pool.
template <typename _Ret, typename... _Args>
template <typename RetT, typename... Args>
class Task : public VTask
{
public:
typedef Task<_Ret, _Args...> this_type;
typedef std::promise<_Ret> promise_type;
typedef std::future<_Ret> future_type;
typedef std::packaged_task<_Ret(_Args...)> packaged_task_type;
typedef _Ret result_type;
typedef std::tuple<_Args...> tuple_type;
typedef Task<RetT, Args...> this_type;
typedef std::promise<RetT> promise_type;
typedef std::future<RetT> future_type;
typedef std::packaged_task<RetT(Args...)> packaged_task_type;
typedef RetT result_type;
typedef std::tuple<Args...> tuple_type;
public:
template <typename _Func>
Task(_Func&& func, _Args&&... args)
template <typename FuncT>
Task(FuncT&& func, Args... args)
: VTask()
, m_ptask(std::forward<_Func>(func))
, m_args(std::forward<_Args>(args)...)
, m_ptask(std::forward<FuncT>(func))
, m_args(args...)
{}
template <typename _Func>
Task(VTaskGroup* tg, _Func&& func, _Args&&... args)
template <typename FuncT>
Task(VTaskGroup* tg, FuncT&& func, Args... args)
: VTask(tg)
, m_ptask(std::forward<_Func>(func))
, m_args(std::forward<_Args>(args)...)
, m_ptask(std::forward<FuncT>(func))
, m_args(args...)
{}
template <typename _Func>
Task(ThreadPool* tp, _Func&& func, _Args&&... args)
template <typename FuncT>
Task(ThreadPool* tp, FuncT&& func, Args... args)
: VTask(tp)
, m_ptask(std::forward<_Func>(func))
, m_args(std::forward<_Args>(args)...)
, m_ptask(std::forward<FuncT>(func))
, m_args(args...)
{}
virtual ~Task() {}
@@ -139,8 +138,7 @@ public:
// execution operator
virtual void operator()() final
{
details::apply(std::forward<packaged_task_type>(m_ptask),
std::forward<tuple_type>(m_args));
mpl::apply(std::move(m_ptask), std::move(m_args));
// decrements the task-group counter on active tasks
// when the counter is < 2, if the thread owning the task group is
// sleeping at the TaskGroup::wait(), it signals the thread to wake
@@ -160,33 +158,33 @@ private:
//======================================================================================//
/// \brief The task class is supplied to thread_pool.
template <typename _Ret>
class Task<_Ret, void> : public VTask
template <typename RetT>
class Task<RetT, void> : public VTask
{
public:
typedef Task<_Ret> this_type;
typedef std::promise<_Ret> promise_type;
typedef std::future<_Ret> future_type;
typedef std::packaged_task<_Ret()> packaged_task_type;
typedef _Ret result_type;
typedef Task<RetT> this_type;
typedef std::promise<RetT> promise_type;
typedef std::future<RetT> future_type;
typedef std::packaged_task<RetT()> packaged_task_type;
typedef RetT result_type;
public:
template <typename _Func>
Task(_Func&& func)
template <typename FuncT>
Task(FuncT&& func)
: VTask()
, m_ptask(std::forward<_Func>(func))
, m_ptask(std::forward<FuncT>(func))
{}
template <typename _Func>
Task(VTaskGroup* tg, _Func&& func)
template <typename FuncT>
Task(VTaskGroup* tg, FuncT&& func)
: VTask(tg)
, m_ptask(std::forward<_Func>(func))
, m_ptask(std::forward<FuncT>(func))
{}
template <typename _Func>
Task(ThreadPool* tp, _Func&& func)
template <typename FuncT>
Task(ThreadPool* tp, FuncT&& func)
: VTask(tp)
, m_ptask(std::forward<_Func>(func))
, m_ptask(std::forward<FuncT>(func))
{}
virtual ~Task() {}
@@ -218,30 +216,30 @@ template <>
class Task<void, void> : public VTask
{
public:
typedef void _Ret;
typedef void RetT;
typedef Task<void, void> this_type;
typedef std::promise<_Ret> promise_type;
typedef std::future<_Ret> future_type;
typedef std::packaged_task<_Ret()> packaged_task_type;
typedef _Ret result_type;
typedef std::promise<RetT> promise_type;
typedef std::future<RetT> future_type;
typedef std::packaged_task<RetT()> packaged_task_type;
typedef RetT result_type;
public:
template <typename _Func>
explicit Task(_Func&& func)
template <typename FuncT>
explicit Task(FuncT&& func)
: VTask()
, m_ptask(std::forward<_Func>(func))
, m_ptask(std::forward<FuncT>(func))
{}
template <typename _Func>
Task(VTaskGroup* tg, _Func&& func)
template <typename FuncT>
Task(VTaskGroup* tg, FuncT&& func)
: VTask(tg)
, m_ptask(std::forward<_Func>(func))
, m_ptask(std::forward<FuncT>(func))
{}
template <typename _Func>
Task(ThreadPool* tp, _Func&& func)
template <typename FuncT>
Task(ThreadPool* tp, FuncT&& func)
: VTask(tp)
, m_ptask(std::forward<_Func>(func))
, m_ptask(std::forward<FuncT>(func))
{}
virtual ~Task() {}
+115 -74
View File
@@ -51,70 +51,97 @@ class ThreadPool;
//--------------------------------------------------------------------------------------//
#if !defined(PTL_DEFAULT_OBJECT)
# define PTL_DEFAULT_OBJECT(NAME) \
NAME() = default; \
~NAME() = default; \
NAME(const NAME&) = default; \
NAME(NAME&&) noexcept = default; \
NAME& operator=(const NAME&) = default; \
NAME& operator=(NAME&&) noexcept = default;
#endif
//--------------------------------------------------------------------------------------//
template <typename JoinT, typename JoinArg>
struct JoinFunction
{
public:
using Type = std::function<JoinT(JoinT&, JoinArg&&)>;
public:
PTL_DEFAULT_OBJECT(JoinFunction)
template <typename Func>
JoinFunction(Func&& func)
: m_func(std::forward<Func>(func))
{}
template <typename... Args>
JoinT& operator()(Args&&... args)
{
return std::move(m_func(std::forward<Args>(args)...));
}
private:
Type m_func = [](JoinT& lhs, JoinArg&&) { return lhs; };
};
//--------------------------------------------------------------------------------------//
template <typename JoinArg>
struct JoinFunction<void, JoinArg>
{
public:
using Type = std::function<void(JoinArg)>;
public:
PTL_DEFAULT_OBJECT(JoinFunction)
template <typename Func>
JoinFunction(Func&& func)
: m_func(std::forward<Func>(func))
{}
template <typename... Args>
void operator()(Args&&... args)
{
m_func(std::forward<Args>(args)...);
}
private:
Type m_func = [](JoinArg) {};
};
//--------------------------------------------------------------------------------------//
template <>
struct JoinFunction<void, void>
{
public:
using Type = std::function<void()>;
public:
PTL_DEFAULT_OBJECT(JoinFunction)
template <typename Func>
JoinFunction(Func&& func)
: m_func(std::forward<Func>(func))
{}
void operator()() { m_func(); }
private:
Type m_func = []() {};
};
//--------------------------------------------------------------------------------------//
template <typename Tp, typename Arg = Tp>
class TaskGroup
: public VTaskGroup
, public TaskAllocator<TaskGroup<Tp, Arg>>
{
protected:
//----------------------------------------------------------------------------------//
template <typename JoinT, typename JoinArg>
struct JoinFunction
{
public:
typedef std::function<JoinT(JoinT&, JoinArg&&)> Type;
public:
JoinFunction() = default;
~JoinFunction() = default;
JoinFunction(const JoinFunction&) = default;
JoinFunction(JoinFunction&&) = default;
JoinFunction& operator=(const JoinFunction&) = default;
JoinFunction& operator=(JoinFunction&&) = default;
template <typename Func>
JoinFunction(Func&& func)
: m_func(std::forward<Func>(func))
{}
template <typename... Args>
JoinT& operator()(Args&&... args)
{
return std::move(m_func(std::forward<Args>(args)...));
}
private:
Type m_func = [](JoinT& lhs, JoinArg&&) { return lhs; };
};
//----------------------------------------------------------------------------------//
template <typename JoinArg>
struct JoinFunction<void, JoinArg>
{
public:
typedef std::function<void()> Type;
public:
JoinFunction() = default;
~JoinFunction() = default;
JoinFunction(const JoinFunction&) = default;
JoinFunction(JoinFunction&&) = default;
JoinFunction& operator=(const JoinFunction&) = default;
JoinFunction& operator=(JoinFunction&&) = default;
template <typename Func>
JoinFunction(Func&& func)
: m_func(std::forward<Func>(func))
{}
void operator()() { m_func(); }
private:
Type m_func = []() {};
};
//----------------------------------------------------------------------------------//
public:
//------------------------------------------------------------------------//
typedef decay_t<Arg> ArgTp;
@@ -131,7 +158,7 @@ public:
typedef typename task_list_t::const_reverse_iterator const_reverse_iterator;
//------------------------------------------------------------------------//
template <typename... Args>
using task_type = Task<ArgTp, Args...>;
using task_type = Task<ArgTp, decay_t<Args>...>;
//------------------------------------------------------------------------//
public:
@@ -176,29 +203,29 @@ public:
public:
//------------------------------------------------------------------------//
template <typename Func, typename... Args>
task_type<Args...>* wrap(Func&& func, Args&&... args)
task_type<Args...>* wrap(Func&& func, Args... args)
{
return operator+=(new task_type<Args...>(this, std::forward<Func>(func),
std::forward<Args>(args)...));
return operator+=(
new task_type<Args...>(this, std::forward<Func>(func), args...));
}
public:
//------------------------------------------------------------------------//
template <typename Func, typename... Args>
void exec(Func&& func, Args&&... args)
void exec(Func&& func, Args... args)
{
m_pool->add_task(wrap(std::forward<Func>(func), std::forward<Args>(args)...));
m_pool->add_task(wrap(std::forward<Func>(func), args...));
}
//------------------------------------------------------------------------//
template <typename Func, typename... Args>
void run(Func&& func, Args&&... args)
void run(Func&& func, Args... args)
{
m_pool->add_task(wrap(std::forward<Func>(func), std::forward<Args>(args)...));
m_pool->add_task(wrap(std::forward<Func>(func), args...));
}
//------------------------------------------------------------------------//
template <typename Func, typename... Args>
void parallel_for(const intmax_t& nitr, const intmax_t& chunks, Func&& func,
Args&&... args)
Args... args)
{
auto nsplit = nitr / chunks;
auto nmod = nitr % chunks;
@@ -208,8 +235,7 @@ public:
{
auto _beg = n * chunks;
auto _end = (n + 1) * chunks + ((n + 1 == nsplit) ? nmod : 0);
run(std::forward<Func>(func), std::move(_beg), std::move(_end),
std::forward<Args>(args)...);
run(std::forward<Func>(func), std::move(_beg), std::move(_end), args...);
}
}
@@ -244,21 +270,22 @@ public:
//------------------------------------------------------------------------//
// wait to finish
template <typename Up = Tp, enable_if_t<!std::is_same<Up, void>::value, int> = 0>
template <typename Up = Tp, enable_if_t<!std::is_void<Up>::value, int> = 0>
inline Up join(Up accum = {})
{
this->wait();
for(auto& itr : m_task_set)
{
using RetType = decltype(itr.get());
accum = std::move(m_join(std::ref(accum), std::forward<RetType>(itr.get())));
using RetT = decay_t<decltype(itr.get())>;
accum = std::move(m_join(std::ref(accum), std::forward<RetT>(itr.get())));
}
this->clear();
return accum;
}
//------------------------------------------------------------------------//
// wait to finish
template <typename Up = Tp, enable_if_t<std::is_same<Up, void>::value, int> = 0>
template <typename Up = Tp, typename Rp = Arg,
enable_if_t<std::is_void<Up>::value && std::is_void<Rp>::value, int> = 0>
inline void join()
{
this->wait();
@@ -268,6 +295,20 @@ public:
this->clear();
}
//------------------------------------------------------------------------//
// wait to finish
template <typename Up = Tp, typename Rp = Arg,
enable_if_t<std::is_void<Up>::value && !std::is_void<Rp>::value, int> = 0>
inline void join()
{
this->wait();
for(auto& itr : m_task_set)
{
using RetT = decay_t<decltype(itr.get())>;
m_join(std::forward<RetT>(itr.get()));
}
this->clear();
}
//------------------------------------------------------------------------//
// clear the task result history
void clear()
{
+58 -59
View File
@@ -30,6 +30,7 @@
#pragma once
#include "PTL/Globals.hh"
#include "PTL/TBBTaskGroup.hh"
#include "PTL/Task.hh"
#include "PTL/TaskGroup.hh"
@@ -52,9 +53,6 @@ public:
typedef TaskManager this_type;
typedef ThreadPool::size_type size_type;
template <bool _Bp, typename _Tp = void>
using enable_if_t = typename std::enable_if<_Bp, _Tp>::type;
public:
// Constructor and Destructors
explicit TaskManager(ThreadPool*);
@@ -89,8 +87,8 @@ public:
//------------------------------------------------------------------------//
// direct insertion of a task
//------------------------------------------------------------------------//
template <typename... _Args>
void exec(Task<_Args...>* _task)
template <typename... Args>
void exec(Task<Args...>* _task)
{
m_pool->add_task(_task);
}
@@ -98,39 +96,40 @@ public:
//------------------------------------------------------------------------//
// direct insertion of a packaged_task
//------------------------------------------------------------------------//
template <typename _Ret, typename _Func, typename... _Args>
std::future<_Ret> async(_Func&& func, _Args&&... args)
template <typename RetT, typename FuncT, typename... Args>
std::future<RetT> async(FuncT&& func, Args&&... args)
{
typedef PackagedTask<_Ret, _Args...> task_type;
typedef PackagedTask<RetT, Args...> task_type;
typedef task_type* task_pointer;
task_pointer _ptask =
new task_type(std::forward<_Func>(func), std::forward<_Args>(args)...);
std::future<_Ret> _f = _ptask->get_future();
new task_type(std::forward<FuncT>(func), std::forward<Args>(args)...);
std::future<RetT> _f = _ptask->get_future();
m_pool->add_task(_ptask);
return _f;
}
//------------------------------------------------------------------------//
template <typename _Ret, typename _Func>
std::future<_Ret> async(_Func&& func)
template <typename RetT, typename FuncT>
std::future<RetT> async(FuncT&& func)
{
typedef PackagedTask<_Ret> task_type;
typedef PackagedTask<RetT> task_type;
typedef task_type* task_pointer;
task_pointer _ptask = new task_type(std::forward<_Func>(func));
std::future<_Ret> _f = _ptask->get_future();
task_pointer _ptask = new task_type(std::forward<FuncT>(func));
std::future<RetT> _f = _ptask->get_future();
m_pool->add_task(_ptask);
return _f;
}
//------------------------------------------------------------------------//
template <typename _Func, typename... _Args,
typename _Ret = typename std::result_of<_Func(_Args&&...)>::type>
auto async(_Func&& func, _Args&&... args) -> std::future<_Ret>
template <typename FuncT, typename... Args>
auto async(FuncT&& func, Args... args)
-> std::future<decay_t<decltype(func(args...))>>
{
typedef PackagedTask<_Ret, _Args...> task_type;
using RetT = decay_t<decltype(func(args...))>;
typedef PackagedTask<RetT, Args...> task_type;
auto _ptask =
new task_type(std::forward<_Func>(func), std::forward<_Args>(args)...);
new task_type(std::forward<FuncT>(func), std::forward<Args>(args)...);
auto _f = _ptask->get_future();
m_pool->add_task(_ptask);
return _f;
@@ -141,59 +140,59 @@ public:
//------------------------------------------------------------------------//
// public wrap functions
//------------------------------------------------------------------------//
template <typename _Ret, typename _Arg, typename _Func, typename... _Args>
Task<_Ret, _Arg, _Args...>* wrap(TaskGroup<_Ret, _Arg>& tg, _Func&& func,
_Args&&... args)
template <typename RetT, typename ArgT, typename FuncT, typename... Args>
Task<RetT, ArgT, Args...>* wrap(TaskGroup<RetT, ArgT>& tg, FuncT&& func,
Args&&... args)
{
return tg.wrap(std::forward<_Func>(func), std::forward<_Args>(args)...);
return tg.wrap(std::forward<FuncT>(func), std::forward<Args>(args)...);
}
//------------------------------------------------------------------------//
template <typename _Ret, typename _Arg, typename _Func>
Task<_Ret, _Arg>* wrap(TaskGroup<_Ret, _Arg>& tg, _Func&& func)
template <typename RetT, typename ArgT, typename FuncT>
Task<RetT, ArgT>* wrap(TaskGroup<RetT, ArgT>& tg, FuncT&& func)
{
return tg.wrap(std::forward<_Func>(func));
return tg.wrap(std::forward<FuncT>(func));
}
public:
//------------------------------------------------------------------------//
// public exec functions
//------------------------------------------------------------------------//
template <typename _Ret, typename _Arg, typename _Func, typename... _Args>
void exec(TaskGroup<_Ret, _Arg>& tg, _Func&& func, _Args&&... args)
template <typename RetT, typename ArgT, typename FuncT, typename... Args>
void exec(TaskGroup<RetT, ArgT>& tg, FuncT&& func, Args&&... args)
{
tg.exec(std::forward<_Func>(func), std::forward<_Args>(args)...);
tg.exec(std::forward<FuncT>(func), std::forward<Args>(args)...);
}
//------------------------------------------------------------------------//
template <typename _Ret, typename _Arg, typename _Func>
void exec(TaskGroup<_Ret, _Arg>& tg, _Func&& func)
template <typename RetT, typename ArgT, typename FuncT>
void exec(TaskGroup<RetT, ArgT>& tg, FuncT&& func)
{
tg.exec(std::forward<_Func>(func));
tg.exec(std::forward<FuncT>(func));
}
//------------------------------------------------------------------------//
template <typename _Ret, typename _Arg, typename _Func, typename... _Args>
void rexec(TaskGroup<_Ret, _Arg>& tg, _Func&& func, _Args&&... args)
template <typename RetT, typename ArgT, typename FuncT, typename... Args>
void rexec(TaskGroup<RetT, ArgT>& tg, FuncT&& func, Args&&... args)
{
tg.exec(std::forward<_Func>(func), std::forward<_Args>(args)...);
tg.exec(std::forward<FuncT>(func), std::forward<Args>(args)...);
}
//------------------------------------------------------------------------//
template <typename _Ret, typename _Arg, typename _Func>
void rexec(TaskGroup<_Ret, _Arg>& tg, _Func&& func)
template <typename RetT, typename ArgT, typename FuncT>
void rexec(TaskGroup<RetT, ArgT>& tg, FuncT&& func)
{
tg.exec(std::forward<_Func>(func));
tg.exec(std::forward<FuncT>(func));
}
//------------------------------------------------------------------------//
// public exec functions (void specializations)
//------------------------------------------------------------------------//
template <typename _Func, typename... _Args>
void rexec(TaskGroup<void, void>& tg, _Func&& func, _Args&&... args)
template <typename FuncT, typename... Args>
void rexec(TaskGroup<void, void>& tg, FuncT&& func, Args&&... args)
{
tg.exec(std::forward<_Func>(func), std::forward<_Args>(args)...);
tg.exec(std::forward<FuncT>(func), std::forward<Args>(args)...);
}
//------------------------------------------------------------------------//
template <typename _Func>
void rexec(TaskGroup<void, void>& tg, _Func&& func)
template <typename FuncT>
void rexec(TaskGroup<void, void>& tg, FuncT&& func)
{
tg.exec(std::forward<_Func>(func));
tg.exec(std::forward<FuncT>(func));
}
//------------------------------------------------------------------------//
@@ -201,39 +200,39 @@ public:
//------------------------------------------------------------------------//
// public wrap functions using TBB tasks
//------------------------------------------------------------------------//
template <typename _Ret, typename _Arg, typename _Func, typename... _Args>
Task<_Ret, _Arg, _Args...>* wrap(TBBTaskGroup<_Ret, _Arg>& tg, _Func&& func,
_Args&&... args)
template <typename RetT, typename ArgT, typename FuncT, typename... Args>
Task<RetT, ArgT, Args...>* wrap(TBBTaskGroup<RetT, ArgT>& tg, FuncT&& func,
Args&&... args)
{
return tg.wrap(std::forward<_Func>(func), std::forward<_Args>(args)...);
return tg.wrap(std::forward<FuncT>(func), std::forward<Args>(args)...);
}
//------------------------------------------------------------------------//
template <typename _Ret, typename _Arg, typename _Func>
Task<_Ret, _Arg>* wrap(TBBTaskGroup<_Ret, _Arg>& tg, _Func&& func)
template <typename RetT, typename ArgT, typename FuncT>
Task<RetT, ArgT>* wrap(TBBTaskGroup<RetT, ArgT>& tg, FuncT&& func)
{
return tg.wrap(std::forward<_Func>(func));
return tg.wrap(std::forward<FuncT>(func));
}
//------------------------------------------------------------------------//
// public exec functions using TBB tasks
//------------------------------------------------------------------------//
template <typename _Ret, typename _Arg, typename _Func, typename... _Args>
void exec(TBBTaskGroup<_Ret, _Arg>& tg, _Func&& func, _Args&&... args)
template <typename RetT, typename ArgT, typename FuncT, typename... Args>
void exec(TBBTaskGroup<RetT, ArgT>& tg, FuncT&& func, Args&&... args)
{
tg.exec(std::forward<_Func>(func), std::forward<_Args>(args)...);
tg.exec(std::forward<FuncT>(func), std::forward<Args>(args)...);
}
//------------------------------------------------------------------------//
template <typename _Ret, typename _Arg, typename _Func>
void exec(TBBTaskGroup<_Ret, _Arg>& tg, _Func&& func)
template <typename RetT, typename ArgT, typename FuncT>
void exec(TBBTaskGroup<RetT, ArgT>& tg, FuncT&& func)
{
tg.exec(std::forward<_Func>(func));
tg.exec(std::forward<FuncT>(func));
}
//------------------------------------------------------------------------//
#endif
protected:
// Protected variables
ThreadPool* m_pool;
ThreadPool* m_pool = nullptr;
private:
static TaskManager*& fgInstance();
-2
View File
@@ -44,8 +44,6 @@ class TaskManager;
class TaskRunManager
{
public:
typedef TaskGroup<void> RunTaskGroup;
typedef TBBTaskGroup<void> RunTaskGroupTBB;
typedef TaskRunManager* pointer;
public:
+6 -6
View File
@@ -55,14 +55,14 @@ public:
// dummy wait
inline void wait() {}
// run function
template <typename _Func>
inline void run(_Func f)
template <typename FuncT>
inline void run(FuncT f)
{
f();
}
// run and wait
template <typename _Func>
inline void run_and_wait(_Func f)
template <typename FuncT>
inline void run_and_wait(FuncT f)
{
f();
}
@@ -99,8 +99,8 @@ class VUserTaskQueue;
class ThreadData
{
public:
template <typename _Tp>
using TaskStack = std::deque<_Tp>;
template <typename Tp>
using TaskStack = std::deque<Tp>;
ThreadData(ThreadPool* tp);
~ThreadData();
+128 -11
View File
@@ -53,6 +53,7 @@
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
#include <vector>
@@ -62,8 +63,8 @@ namespace PTL
class ThreadPool
{
public:
template <typename _KeyType, typename _MappedType, typename _HashType = _KeyType>
using uomap = std::unordered_map<_KeyType, _MappedType, std::hash<_HashType>>;
template <typename KeyT, typename MappedT, typename HashT = KeyT>
using uomap = std::unordered_map<KeyT, MappedT, std::hash<HashT>>;
// pod-types
using size_type = size_t;
@@ -82,8 +83,9 @@ public:
typedef std::vector<bool> bool_list_t;
typedef std::map<ThreadId, uintmax_t> thread_id_map_t;
typedef std::map<uintmax_t, ThreadId> thread_index_map_t;
typedef std::function<void()> initialize_func_t;
using thread_vec_t = std::vector<Thread>;
// functions
typedef std::function<void()> initialize_func_t;
typedef std::function<intmax_t(intmax_t)> affinity_func_t;
public:
@@ -110,6 +112,9 @@ public:
size_type destroy_threadpool(); // destroy the threads
size_type stop_thread();
template <typename FuncT>
void execute_on_all_threads(FuncT&& _func);
public:
// Public functions related to TBB
static bool using_tbb();
@@ -121,8 +126,8 @@ public:
size_type add_task(task_pointer task, int bin = -1);
// size_type add_thread_task(ThreadId id, task_pointer&& task);
// add a generic container with iterator
template <typename _List_t>
size_type add_tasks(_List_t&);
template <typename ListT>
size_type add_tasks(ListT&);
Thread* get_thread(size_type _n) const;
Thread* get_thread(std::thread::id id) const;
@@ -161,14 +166,14 @@ public:
void set_affinity(affinity_func_t f) { m_affinity_func = f; }
void set_affinity(intmax_t i, Thread&);
void SetVerbose(int n) { m_verbose = n; }
int GetVerbose() const { return m_verbose; }
void set_verbose(int n) { m_verbose = n; }
int get_verbose() const { return m_verbose; }
bool is_master() const { return ThisThread::get_id() == m_master_tid; }
public:
// read FORCE_NUM_THREADS environment variable
static const thread_id_map_t& GetThreadIDs();
static uintmax_t GetThisThreadID();
static const thread_id_map_t& get_thread_ids();
static uintmax_t get_this_thread_id();
protected:
void execute_thread(VUserTaskQueue*); // function thread sits in
@@ -214,6 +219,7 @@ private:
bool_list_t m_is_stopped; // lets thread know to stop
thread_list_t m_main_threads; // storage for active threads
thread_list_t m_stop_threads; // storage for stopped threads
thread_vec_t m_threads;
// task queue
task_queue_t* m_task_queue;
@@ -332,9 +338,9 @@ ThreadPool::add_task(task_pointer task, int bin)
return static_cast<size_type>(insert(task, bin));
}
//--------------------------------------------------------------------------------------//
template <typename _List_t>
template <typename ListT>
inline ThreadPool::size_type
ThreadPool::add_tasks(_List_t& c)
ThreadPool::add_tasks(ListT& c)
{
if(!m_alive_flag) // if we haven't built thread-pool, just execute
{
@@ -363,6 +369,117 @@ ThreadPool::add_tasks(_List_t& c)
return c_size;
}
//--------------------------------------------------------------------------------------//
template <typename FuncT>
inline void
ThreadPool::execute_on_all_threads(FuncT&& _func)
{
if(m_tbb_tp && m_tbb_task_group)
{
#if defined(PTL_USE_TBB)
// TBB lazily activates threads to process tasks and the master thread
// participates in processing the tasks so getting a specific
// function to execute only on the worker threads requires some trickery
//
auto master_tid = ThisThread::get_id();
std::set<std::thread::id> _first;
Mutex _mutex;
// init function which executes function and returns 1 only once
auto _init = [&]() {
static thread_local int _once = 0;
_mutex.lock();
if(_first.find(std::this_thread::get_id()) == _first.end())
{
// we need to reset this thread-local static for multiple invocations
// of the same template instantiation
_once = 0;
_first.insert(std::this_thread::get_id());
}
_mutex.unlock();
if(_once++ == 0)
{
_func();
return 1;
}
return 0;
};
// consumes approximately N milliseconds of cpu time
auto _consume = [](long n) {
using stl_mutex_t = std::mutex;
using unique_lock_t = std::unique_lock<stl_mutex_t>;
// a mutex held by one lock
stl_mutex_t mutex;
// acquire lock
unique_lock_t hold_lk(mutex);
// associate but defer
unique_lock_t try_lk(mutex, std::defer_lock);
// get current time
auto now = std::chrono::steady_clock::now();
// try until time point
while(std::chrono::steady_clock::now() < (now + std::chrono::milliseconds(n)))
try_lk.try_lock();
};
// this will collect the number of threads which have
// executed the _init function above
std::atomic<size_t> _total_init{ 0 };
// this is the task passed to the task-group
auto _init_task = [&]() {
int _ret = 0;
// don't let the master thread execute the function
if(ThisThread::get_id() != master_tid)
{
// execute the function
_ret = _init();
// add the result
_total_init += _ret;
}
// if the function did not return anything, put it to sleep
// so TBB will wake other threads to execute the remaining tasks
if(_ret == 0)
_consume(100);
};
// TBB won't oversubscribe so we need to limit by ncores - 1
size_t nitr = 0;
size_t _maxp = tbb_global_control()->active_value(
tbb::global_control::max_allowed_parallelism);
size_t _sz = size();
size_t _ncore = Threading::GetNumberOfCores() - 1;
size_t _num = std::min(_maxp, std::min(_sz, _ncore));
auto _fname = __FUNCTION__;
auto _write_info = [&]() {
std::cerr << "[" << _fname << "]> Total initalized: " << _total_init
<< ", expected: " << _num << ", max-parallel: " << _maxp
<< ", size: " << _sz << ", ncore: " << _ncore << std::endl;
};
while(_total_init < _num)
{
auto _n = _num;
while(--_n > 0)
m_tbb_task_group->run(_init_task);
m_tbb_task_group->wait();
// don't loop infinitely but use a strict condition
if(nitr++ > 2 * (_num + 1) && (_total_init - 1) == _num)
{
_write_info();
break;
}
// at this point we need to exit
if(nitr > 4 * (_ncore + 1))
{
_write_info();
break;
}
}
if(get_verbose() > 3)
_write_info();
#endif
}
else if(get_queue())
{
get_queue()->ExecuteOnAllThreads(this, std::forward<FuncT>(_func));
}
}
//======================================================================================//
} // namespace PTL
+17 -17
View File
@@ -42,12 +42,12 @@ namespace PTL
#define THREADSLEEP(tick) std::this_thread::sleep_for(std::chrono::seconds(tick))
// will be used in the future when migrating threading to task-based style
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>;
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>;
//
// NOTE ON Tasking SERIAL BUILDS AND MUTEX/UNIQUE_LOCK
@@ -94,12 +94,12 @@ using namespace std::this_thread;
// will be used in the future when migrating threading to task-based style
// and are currently used in unit tests
template <typename _Tp>
using Promise = std::promise<_Tp>;
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>;
template <typename Tp>
using Future = std::future<Tp>;
template <typename Tp>
using SharedFuture = std::shared_future<Tp>;
// Some useful types
typedef void* ThreadFunReturnType;
@@ -113,7 +113,7 @@ typedef int (*thread_unlock)(Mutex*);
// a template class "Cache<T>" that required a static
// mutex for specific to type T:
// AutoLock l(TypeMutex<Cache<T>>());
template <typename _Tp>
template <typename Tp>
Mutex&
TypeMutex(const unsigned int& _n = 0)
{
@@ -135,7 +135,7 @@ TypeMutex(const unsigned int& _n = 0)
// a template class "Cache<T>" that required a static
// recursive_mutex for specific to type T:
// RecursiveAutoLock l(TypeRecursiveMutex<Cache<T>>());
template <typename _Tp>
template <typename Tp>
RecursiveMutex&
TypeRecursiveMutex(const unsigned int& _n = 0)
{
@@ -175,11 +175,11 @@ typedef std::thread::id Pid_t;
// Instead of previous macro taking one argument, define function taking
// unlimited arguments
template <typename _Worker, typename _Func, typename... _Args>
template <typename WorkerT, typename FuncT, typename... Args>
void
THREADCREATE(_Worker*& worker, _Func func, _Args... args)
THREADCREATE(WorkerT*& worker, FuncT func, Args... args)
{
*worker = Thread(func, std::forward<_Args>(args)...);
*worker = Thread(func, std::forward<Args>(args)...);
}
// Conditions
+23 -23
View File
@@ -25,10 +25,10 @@
namespace PTL
{
template <typename _Tp, typename _Up>
template <typename Tp, typename Up>
struct SmallerThanT
{
static constexpr bool value = sizeof(_Tp) < sizeof(_Up);
static constexpr bool value = sizeof(Tp) < sizeof(Up);
};
//======================================================================================//
@@ -38,54 +38,54 @@ struct SmallerThanT
// useful to work with sequences of compile-time values, such as the bounds of a
// multidimensional array or indices into another typelist.
template <typename _Tp, _Tp Value>
template <typename Tp, Tp Value>
struct CTValue
{
static constexpr _Tp value = Value;
static constexpr Tp value = Value;
};
//======================================================================================//
template <std::size_t Height, typename _Tp,
bool = std::is_class<_Tp>::value && !std::is_final<_Tp>::value>
template <std::size_t Height, typename Tp,
bool = std::is_class<Tp>::value && !std::is_final<Tp>::value>
class TupleElt;
//--------------------------------------------------------------------------------------//
// specialization that does not satisfy is_class<> and not is_final<>
//
template <std::size_t Height, typename _Tp>
class TupleElt<Height, _Tp, false>
template <std::size_t Height, typename Tp>
class TupleElt<Height, Tp, false>
{
_Tp value;
Tp value;
public:
TupleElt() = default;
template <typename _Up>
TupleElt(_Up&& other)
: value(std::forward<_Up>(other))
template <typename Up>
TupleElt(Up&& other)
: value(std::forward<Up>(other))
{}
_Tp& get() { return value; }
_Tp const& get() const { return value; }
Tp& get() { return value; }
Tp const& get() const { return value; }
};
//--------------------------------------------------------------------------------------//
// specialization that does satisfy is_class<> and not is_final<>
//
template <std::size_t Height, typename _Tp>
class TupleElt<Height, _Tp, true> : private _Tp
template <std::size_t Height, typename Tp>
class TupleElt<Height, Tp, true> : private Tp
{
public:
TupleElt() = default;
template <typename _Up>
explicit TupleElt(_Up&& other)
: _Tp(std::forward<_Up>(other))
template <typename Up>
explicit TupleElt(Up&& other)
: Tp(std::forward<Up>(other))
{}
_Tp& get() { return *this; }
const _Tp& get() const { return *this; }
Tp& get() { return *this; }
const Tp& get() const { return *this; }
};
//======================================================================================//
@@ -141,8 +141,8 @@ get(Tuple<Elements...>& t) -> decltype(get_height<sizeof...(Elements) - I - 1>(t
return get_height<sizeof...(Elements) - I - 1>(t);
}
template <typename... _Tp>
using TypeList = Tuple<_Tp...>;
template <typename... Tp>
using TypeList = Tuple<Tp...>;
//======================================================================================//
+4 -4
View File
@@ -126,15 +126,15 @@ public:
static void set_max_depth(const int64_t& val) { fmax_depth = val; }
static bool is_enabled() { return fenabled; }
template <typename _Tp = CountedType,
typename std::enable_if<std::is_same<_Tp, void>::value>::type* = nullptr>
template <typename Tp = CountedType,
typename std::enable_if<std::is_same<Tp, void>::value>::type* = nullptr>
static bool enable()
{
return fenabled && fmax_depth > count();
}
// the void type is consider the global setting
template <typename _Tp = CountedType,
typename std::enable_if<!std::is_same<_Tp, void>::value>::type* = nullptr>
template <typename Tp = CountedType,
typename std::enable_if<!std::is_same<Tp, void>::value>::type* = nullptr>
static bool enable()
{
return void_type::is_enabled() && void_type::max_depth() > count() && fenabled &&
+32 -32
View File
@@ -39,20 +39,20 @@ namespace PTL
//--------------------------------------------------------------------------------------//
// use this function to get rid of "unused parameter" warnings
//
template <typename... _Args>
template <typename... Args>
void
ConsumeParameters(_Args...)
ConsumeParameters(Args...)
{}
//--------------------------------------------------------------------------------------//
// a non-string environment option with a string identifier
template <typename _Tp>
using EnvChoice = std::tuple<_Tp, std::string, std::string>;
template <typename Tp>
using EnvChoice = std::tuple<Tp, std::string, std::string>;
//--------------------------------------------------------------------------------------//
// list of environment choices with non-string and string identifiers
template <typename _Tp>
using EnvChoiceList = std::set<EnvChoice<_Tp>>;
template <typename Tp>
using EnvChoiceList = std::set<EnvChoice<Tp>>;
//--------------------------------------------------------------------------------------//
@@ -72,8 +72,8 @@ public:
}
public:
template <typename _Tp>
void insert(const std::string& env_id, _Tp val)
template <typename Tp>
void insert(const std::string& env_id, Tp val)
{
std::stringstream ss;
ss << std::boolalpha << val;
@@ -91,10 +91,10 @@ public:
m_mutex.unlock();
}
template <typename _Tp>
void insert(const std::string& env_id, EnvChoice<_Tp> choice)
template <typename Tp>
void insert(const std::string& env_id, EnvChoice<Tp> choice)
{
_Tp& val = std::get<0>(choice);
Tp& val = std::get<0>(choice);
std::string& str_val = std::get<1>(choice);
std::string& descript = std::get<2>(choice);
@@ -150,23 +150,23 @@ private:
// GetEnv<int>("FORCENUMBEROFTHREADS",
// std::thread::hardware_concurrency());
//
template <typename _Tp>
_Tp
GetEnv(const std::string& env_id, _Tp _default = _Tp())
template <typename Tp>
Tp
GetEnv(const std::string& env_id, Tp _default = Tp())
{
char* env_var = std::getenv(env_id.c_str());
if(env_var)
{
std::string str_var = std::string(env_var);
std::istringstream iss(str_var);
_Tp var = _Tp();
Tp var = Tp();
iss >> var;
// record value defined by environment
EnvSettings::GetInstance()->insert<_Tp>(env_id, var);
EnvSettings::GetInstance()->insert<Tp>(env_id, var);
return var;
}
// record default value
EnvSettings::GetInstance()->insert<_Tp>(env_id, _default);
EnvSettings::GetInstance()->insert<Tp>(env_id, _default);
// return default if not specified in environment
return _default;
@@ -207,25 +207,25 @@ GetEnv(const std::string& env_id, bool _default)
//--------------------------------------------------------------------------------------//
// overload for GetEnv + message when set
//
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, Tp _default, const std::string& msg)
{
char* env_var = std::getenv(env_id.c_str());
if(env_var)
{
std::string str_var = std::string(env_var);
std::istringstream iss(str_var);
_Tp var = _Tp();
Tp var = Tp();
iss >> var;
std::cout << "Environment variable \"" << env_id << "\" enabled with "
<< "value == " << var << ". " << msg << std::endl;
// record value defined by environment
EnvSettings::GetInstance()->insert<_Tp>(env_id, var);
EnvSettings::GetInstance()->insert<Tp>(env_id, var);
return var;
}
// record default value
EnvSettings::GetInstance()->insert<_Tp>(env_id, _default);
EnvSettings::GetInstance()->insert<Tp>(env_id, _default);
// return default if not specified in environment
return _default;
@@ -241,9 +241,9 @@ GetEnv(const std::string& env_id, _Tp _default, const std::string& msg)
//
// int eInterp = GetEnv<int>("INTERPOLATION", choices, CUBIC);
//
template <typename _Tp>
_Tp
GetEnv(const std::string& env_id, const EnvChoiceList<_Tp>& _choices, _Tp _default)
template <typename Tp>
Tp
GetEnv(const std::string& env_id, const EnvChoiceList<Tp>& _choices, Tp _default)
{
auto asupper = [](std::string var) {
for(auto& itr : var)
@@ -256,7 +256,7 @@ GetEnv(const std::string& env_id, const EnvChoiceList<_Tp>& _choices, _Tp _defau
{
std::string str_var = std::string(env_var);
std::string upp_var = asupper(str_var);
_Tp var = _Tp();
Tp var = Tp();
// check to see if string matches a choice
for(const auto& itr : _choices)
{
@@ -302,7 +302,7 @@ GetEnv(const std::string& env_id, const EnvChoiceList<_Tp>& _choices, _Tp _defau
}
// record default value
EnvSettings::GetInstance()->insert(env_id, EnvChoice<_Tp>(_default, _name, _desc));
EnvSettings::GetInstance()->insert(env_id, EnvChoice<Tp>(_default, _name, _desc));
// return default if not specified in environment
return _default;
@@ -310,9 +310,9 @@ GetEnv(const std::string& env_id, const EnvChoiceList<_Tp>& _choices, _Tp _defau
//--------------------------------------------------------------------------------------//
template <typename _Tp>
_Tp
GetChoice(const EnvChoiceList<_Tp>& _choices, const std::string str_var)
template <typename Tp>
Tp
GetChoice(const EnvChoiceList<Tp>& _choices, const std::string str_var)
{
auto asupper = [](std::string var) {
for(auto& itr : var)
@@ -321,7 +321,7 @@ GetChoice(const EnvChoiceList<_Tp>& _choices, const std::string str_var)
};
std::string upp_var = asupper(str_var);
_Tp var = _Tp();
Tp var = Tp();
// check to see if string matches a choice
for(const auto& itr : _choices)
{
+4 -9
View File
@@ -50,15 +50,13 @@ namespace PTL
{
class ThreadPool;
#define _MOVE_MEMBER(_member) _member = std::move(rhs._member)
class VTaskGroup
{
public:
template <typename _Tp>
using container_type = std::vector<_Tp>;
template <typename _Tp>
using list_type = std::vector<_Tp>;
template <typename Tp>
using container_type = std::vector<Tp>;
template <typename Tp>
using list_type = std::vector<Tp>;
typedef VTaskGroup this_type;
typedef std::thread::id tid_type;
@@ -154,7 +152,4 @@ VTaskGroup::clear()
//--------------------------------------------------------------------------------------//
// don't pollute
#undef _MOVE_MEMBER
} // namespace PTL
+24 -25
View File
@@ -114,44 +114,43 @@ public:
// virtual uintmax_t operator--(int) = 0;
public:
template <typename _Container, size_t... Idx>
static auto ContainerToTupleImpl(_Container&& container,
details::index_sequence<Idx...>)
-> decltype(std::make_tuple(std::forward<_Container>(container)[Idx]...))
template <typename ContainerT, size_t... Idx>
static auto ContainerToTupleImpl(ContainerT&& container, mpl::index_sequence<Idx...>)
-> decltype(std::make_tuple(std::forward<ContainerT>(container)[Idx]...))
{
return std::make_tuple(std::forward<_Container>(container)[Idx]...);
return std::make_tuple(std::forward<ContainerT>(container)[Idx]...);
}
template <std::size_t _N, typename _Container>
static auto ContainerToTuple(_Container&& container)
-> decltype(ContainerToTupleImpl(std::forward<_Container>(container),
details::make_index_sequence<_N>{}))
template <std::size_t N, typename ContainerT>
static auto ContainerToTuple(ContainerT&& container)
-> decltype(ContainerToTupleImpl(std::forward<ContainerT>(container),
mpl::make_index_sequence<N>{}))
{
return ContainerToTupleImpl(std::forward<_Container>(container),
details::make_index_sequence<_N>{});
return ContainerToTupleImpl(std::forward<ContainerT>(container),
mpl::make_index_sequence<N>{});
}
template <std::size_t _N, std::size_t _Nt, typename _Tuple,
enable_if_t<(_N == _Nt), int> = 0>
static void _Executor(_Tuple&& _t)
template <std::size_t N, std::size_t Nt, typename TupleT,
enable_if_t<(N == Nt), int> = 0>
static void TExecutor(TupleT&& _t)
{
if(std::get<_N>(_t).get())
(*(std::get<_N>(_t)))();
if(std::get<N>(_t).get())
(*(std::get<N>(_t)))();
}
template <std::size_t _N, std::size_t _Nt, typename _Tuple,
enable_if_t<(_N < _Nt), int> = 0>
static void _Executor(_Tuple&& _t)
template <std::size_t N, std::size_t Nt, typename TupleT,
enable_if_t<(N < Nt), int> = 0>
static void TExecutor(TupleT&& _t)
{
if(std::get<_N>(_t).get())
(*(std::get<_N>(_t)))();
_Executor<_N + 1, _Nt, _Tuple>(std::forward<_Tuple>(_t));
if(std::get<N>(_t).get())
(*(std::get<N>(_t)))();
TExecutor<N + 1, Nt, TupleT>(std::forward<TupleT>(_t));
}
template <typename _Tuple, std::size_t _N = std::tuple_size<decay_t<_Tuple>>::value>
static void Executor(_Tuple&& __t)
template <typename TupleT, std::size_t N = std::tuple_size<decay_t<TupleT>>::value>
static void Executor(TupleT&& __t)
{
_Executor<0, _N - 1, _Tuple>(std::forward<_Tuple>(__t));
TExecutor<0, N - 1, TupleT>(std::forward<TupleT>(__t));
}
template <typename Container,