Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
PTL::VTaskGroup Class Reference

#include <VTaskGroup.hh>

+ Inheritance diagram for PTL::VTaskGroup:

Public Types

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
 
typedef VTask task_type
 
typedef uintmax_t size_type
 
typedef Mutex lock_t
 
typedef std::atomic_intmax_t atomic_int
 
typedef std::atomic_uintmax_t atomic_uint
 
typedef Condition condition_t
 
typedef task_typetask_pointer
 
typedef container_type< task_pointervtask_list_type
 

Public Member Functions

 VTaskGroup (ThreadPool *tp=nullptr)
 
virtual ~VTaskGroup ()
 
 VTaskGroup (const this_type &)=delete
 
 VTaskGroup (this_type &&rhs)=default
 
this_typeoperator= (const this_type &)=delete
 
this_typeoperator= (this_type &&rhs)=default
 
virtual void wait ()
 
intmax_t operator++ ()
 
intmax_t operator++ (int)
 
intmax_t operator-- ()
 
intmax_t operator-- (int)
 
intmax_t size () const
 
std::shared_ptr< condition_ttask_cond ()
 
const uintmax_t & id () const
 
void set_pool (ThreadPool *tp)
 
ThreadPool *& pool ()
 
ThreadPoolpool () const
 
void clear ()
 
virtual bool is_native_task_group () const
 
virtual bool is_master () const
 
virtual intmax_t pending ()
 

Static Public Member Functions

static void set_verbose (int level)
 

Protected Member Functions

atomic_inttask_count ()
 
const atomic_inttask_count () const
 

Static Protected Member Functions

static tid_type this_tid ()
 

Protected Attributes

uintmax_t m_id
 
ThreadPoolm_pool
 
std::shared_ptr< atomic_intm_tot_task_count = std::make_shared<atomic_int>(0)
 
std::shared_ptr< condition_tm_task_cond = std::make_shared<condition_t>()
 
std::shared_ptr< lock_tm_task_lock = std::make_shared<lock_t>()
 
tid_type m_main_tid
 
vtask_list_type vtask_list
 

Static Protected Attributes

static int f_verbose = GetEnv<int>("PTL_VERBOSE", 0)
 

Detailed Description

Definition at line 53 of file VTaskGroup.hh.

Member Typedef Documentation

◆ atomic_int

typedef std::atomic_intmax_t PTL::VTaskGroup::atomic_int

Definition at line 66 of file VTaskGroup.hh.

◆ atomic_uint

typedef std::atomic_uintmax_t PTL::VTaskGroup::atomic_uint

Definition at line 67 of file VTaskGroup.hh.

◆ condition_t

Definition at line 68 of file VTaskGroup.hh.

◆ container_type

template<typename Tp >
using PTL::VTaskGroup::container_type = std::vector<Tp>

Definition at line 57 of file VTaskGroup.hh.

◆ list_type

template<typename Tp >
using PTL::VTaskGroup::list_type = std::vector<Tp>

Definition at line 59 of file VTaskGroup.hh.

◆ lock_t

Definition at line 65 of file VTaskGroup.hh.

◆ size_type

typedef uintmax_t PTL::VTaskGroup::size_type

Definition at line 64 of file VTaskGroup.hh.

◆ task_pointer

Definition at line 69 of file VTaskGroup.hh.

◆ task_type

Definition at line 63 of file VTaskGroup.hh.

◆ this_type

Definition at line 61 of file VTaskGroup.hh.

◆ tid_type

typedef std::thread::id PTL::VTaskGroup::tid_type

Definition at line 62 of file VTaskGroup.hh.

◆ vtask_list_type

Constructor & Destructor Documentation

◆ VTaskGroup() [1/3]

VTaskGroup::VTaskGroup ( ThreadPool tp = nullptr)
explicit

Definition at line 56 of file VTaskGroup.cc.

58, m_pool(tp)
59, m_tot_task_count(std::make_shared<atomic_int>(0))
60, m_task_cond(std::make_shared<condition_t>())
61, m_task_lock(std::make_shared<lock_t>())
62, m_main_tid(std::this_thread::get_id())
63{
66
67 if(!m_pool)
68 {
69 std::cerr << __FUNCTION__ << "@" << __LINE__ << " :: Warning! "
70 << "nullptr to thread pool!" << std::endl;
71 }
72}
std::atomic_uintmax_t & vtask_group_counter()
Definition: VTaskGroup.cc:44
static TaskRunManager * GetMasterRunManager(bool useTBB=false)
ThreadPool * GetThreadPool() const
std::shared_ptr< atomic_int > m_tot_task_count
Definition: VTaskGroup.hh:137
ThreadPool * m_pool
Definition: VTaskGroup.hh:136
std::shared_ptr< condition_t > m_task_cond
Definition: VTaskGroup.hh:138
uintmax_t m_id
Definition: VTaskGroup.hh:135
tid_type m_main_tid
Definition: VTaskGroup.hh:140
std::shared_ptr< lock_t > m_task_lock
Definition: VTaskGroup.hh:139

◆ ~VTaskGroup()

VTaskGroup::~VTaskGroup ( )
virtual

Definition at line 76 of file VTaskGroup.cc.

76{}

◆ VTaskGroup() [2/3]

PTL::VTaskGroup::VTaskGroup ( const this_type )
delete

◆ VTaskGroup() [3/3]

PTL::VTaskGroup::VTaskGroup ( this_type &&  rhs)
default

Member Function Documentation

◆ clear()

void PTL::VTaskGroup::clear ( )
inline

Definition at line 146 of file VTaskGroup.hh.

147{
148 for(auto& itr : vtask_list)
149 delete itr;
150 vtask_list.clear();
151}
vtask_list_type vtask_list
Definition: VTaskGroup.hh:141

Referenced by PTL::TaskGroup< Tp, Arg >::clear().

◆ id()

const uintmax_t & PTL::VTaskGroup::id ( ) const
inline

Definition at line 106 of file VTaskGroup.hh.

106{ return m_id; }

◆ is_master()

virtual bool PTL::VTaskGroup::is_master ( ) const
inlinevirtual

Definition at line 115 of file VTaskGroup.hh.

115{ return this_tid() == m_main_tid; }
static tid_type this_tid()
Definition: VTaskGroup.hh:126

◆ is_native_task_group()

virtual bool PTL::VTaskGroup::is_native_task_group ( ) const
inlinevirtual

Definition at line 114 of file VTaskGroup.hh.

114{ return true; }

Referenced by PTL::VTask::is_native_task(), and wait().

◆ operator++() [1/2]

intmax_t PTL::VTaskGroup::operator++ ( )
inline

Definition at line 92 of file VTaskGroup.hh.

92{ return ++(*m_tot_task_count); }

Referenced by PTL::TaskGroup< Tp, Arg >::operator+=().

◆ operator++() [2/2]

intmax_t PTL::VTaskGroup::operator++ ( int  )
inline

Definition at line 93 of file VTaskGroup.hh.

93{ return (*m_tot_task_count)++; }

◆ operator--() [1/2]

intmax_t PTL::VTaskGroup::operator-- ( )
inline

Definition at line 96 of file VTaskGroup.hh.

96{ return --(*m_tot_task_count); }

◆ operator--() [2/2]

intmax_t PTL::VTaskGroup::operator-- ( int  )
inline

Definition at line 97 of file VTaskGroup.hh.

97{ return (*m_tot_task_count)--; }

◆ operator=() [1/2]

this_type & PTL::VTaskGroup::operator= ( const this_type )
delete

◆ operator=() [2/2]

this_type & PTL::VTaskGroup::operator= ( this_type &&  rhs)
default

◆ pending()

virtual intmax_t PTL::VTaskGroup::pending ( )
inlinevirtual

Definition at line 119 of file VTaskGroup.hh.

119{ return m_tot_task_count->load(); }

Referenced by wait().

◆ pool() [1/2]

ThreadPool *& PTL::VTaskGroup::pool ( )
inline

Definition at line 110 of file VTaskGroup.hh.

110{ return m_pool; }

Referenced by PTL::VTask::pool().

◆ pool() [2/2]

ThreadPool * PTL::VTaskGroup::pool ( ) const
inline

Definition at line 111 of file VTaskGroup.hh.

111{ return m_pool; }

◆ set_pool()

void PTL::VTaskGroup::set_pool ( ThreadPool tp)
inline

Definition at line 109 of file VTaskGroup.hh.

◆ set_verbose()

static void PTL::VTaskGroup::set_verbose ( int  level)
inlinestatic

Definition at line 121 of file VTaskGroup.hh.

121{ f_verbose = level; }
static int f_verbose
Definition: VTaskGroup.hh:142

◆ size()

intmax_t PTL::VTaskGroup::size ( ) const
inline

Definition at line 100 of file VTaskGroup.hh.

100{ return m_tot_task_count->load(); }

◆ task_cond()

std::shared_ptr< condition_t > PTL::VTaskGroup::task_cond ( )
inline

Definition at line 103 of file VTaskGroup.hh.

103{ return m_task_cond; }

Referenced by PTL::VTask::operator--().

◆ task_count() [1/2]

atomic_int & PTL::VTaskGroup::task_count ( )
inlineprotected

Definition at line 130 of file VTaskGroup.hh.

130{ return *m_tot_task_count; }

Referenced by wait().

◆ task_count() [2/2]

const atomic_int & PTL::VTaskGroup::task_count ( ) const
inlineprotected

Definition at line 131 of file VTaskGroup.hh.

131{ return *m_tot_task_count; }

◆ this_tid()

static tid_type PTL::VTaskGroup::this_tid ( )
inlinestaticprotected

Definition at line 126 of file VTaskGroup.hh.

126{ return std::this_thread::get_id(); }

Referenced by is_master().

◆ wait()

void VTaskGroup::wait ( )
virtual

Definition at line 81 of file VTaskGroup.cc.

82{
83 // if no pool was initially present at creation
84 if(!m_pool)
85 {
86 // check for master MT run-manager
89
90 // if MTRunManager does not exist or no thread pool created
91 if(!m_pool)
92 {
93 if(f_verbose > 0)
94 {
95 fprintf(stderr, "%s @ %i :: Warning! nullptr to thread-pool (%p)\n",
96 __FUNCTION__, __LINE__, static_cast<void*>(m_pool));
97 std::cerr << __FUNCTION__ << "@" << __LINE__ << " :: Warning! "
98 << "nullptr to thread pool!" << std::endl;
99 }
100 return;
101 }
102 }
103
105 if(!data)
106 return;
107
108 ThreadPool* tpool = (m_pool) ? m_pool : data->thread_pool;
109 VUserTaskQueue* taskq = (tpool) ? tpool->get_queue() : data->current_queue;
110
111 bool _is_master = data->is_master;
112 bool _within_task = data->within_task;
113
114 auto is_active_state = [&]() {
115 return (tpool->state()->load(std::memory_order_relaxed) !=
116 thread_pool::state::STOPPED);
117 };
118
119 auto execute_this_threads_tasks = [&]() {
120 if(!taskq)
121 return;
122
123 // only want to process if within a task
124 if((!_is_master || tpool->size() < 2) && _within_task)
125 {
126 int bin = static_cast<int>(taskq->GetThreadBin());
127 // const auto nitr = (tpool) ? tpool->size() : Thread::hardware_concurrency();
128 while(this->pending() > 0)
129 {
130 task_pointer _task = taskq->GetTask(bin);
131 if(_task)
132 (*_task)();
133 }
134 }
135 };
136
137 // checks for validity
139 {
140 // for external threads
141 if(!_is_master || tpool->size() < 2)
142 return;
143 }
144 else if(f_verbose > 0)
145 {
146 if(!tpool || !taskq)
147 {
148 // something is wrong, didn't create thread-pool?
149 fprintf(
150 stderr,
151 "%s @ %i :: Warning! nullptr to thread data (%p) or task-queue (%p)\n",
152 __FUNCTION__, __LINE__, static_cast<void*>(tpool),
153 static_cast<void*>(taskq));
154 }
155 // return if thread pool isn't built
156 else if(is_native_task_group() && !tpool->is_alive())
157 {
158 fprintf(stderr, "%s @ %i :: Warning! thread-pool is not alive!\n",
159 __FUNCTION__, __LINE__);
160 }
161 else if(!is_active_state())
162 {
163 fprintf(stderr, "%s @ %i :: Warning! thread-pool is not active!\n",
164 __FUNCTION__, __LINE__);
165 }
166 }
167
168 intmax_t wake_size = 2;
169 AutoLock _lock(*m_task_lock, std::defer_lock);
170
171 while(is_active_state())
172 {
173 execute_this_threads_tasks();
174
175 // while loop protects against spurious wake-ups
176 while(_is_master && pending() > 0 && is_active_state())
177 {
178 // auto _wake = [&]() { return (wake_size > pending() || !is_active_state());
179 // };
180
181 // lock before sleeping on condition
182 if(!_lock.owns_lock())
183 _lock.lock();
184
185 // Wait until signaled that a task has been competed
186 // Unlock mutex while wait, then lock it back when signaled
187 // when true, this wakes the thread
188 if(pending() >= wake_size)
189 {
190 m_task_cond->wait(_lock);
191 }
192 else
193 {
194 m_task_cond->wait_for(_lock, std::chrono::microseconds(100));
195 }
196 // unlock
197 if(_lock.owns_lock())
198 _lock.unlock();
199 }
200
201 // if pending is not greater than zero, we are joined
202 if(pending() <= 0)
203 break;
204 }
205
206 if(_lock.owns_lock())
207 _lock.unlock();
208
209 intmax_t ntask = this->task_count().load();
210 if(ntask > 0)
211 {
212 std::stringstream ss;
213 ss << "\nWarning! Join operation issue! " << ntask << " tasks still "
214 << "are running!" << std::endl;
215 std::cerr << ss.str();
216 this->wait();
217 }
218}
static ThreadData *& GetInstance()
Definition: ThreadData.cc:35
VUserTaskQueue * current_queue
Definition: ThreadData.hh:115
ThreadPool * thread_pool
Definition: ThreadData.hh:114
const pool_state_type & state() const
Definition: ThreadPool.hh:149
task_queue_t * get_queue() const
Definition: ThreadPool.hh:135
size_type size() const
Definition: ThreadPool.hh:151
task_type * task_pointer
Definition: VTaskGroup.hh:69
atomic_int & task_count()
Definition: VTaskGroup.hh:130
virtual void wait()
Definition: VTaskGroup.cc:81
virtual intmax_t pending()
Definition: VTaskGroup.hh:119
virtual bool is_native_task_group() const
Definition: VTaskGroup.hh:114

Referenced by G4TaskRunManager::CreateAndStartWorkers(), PTL::TaskGroup< Tp, Arg >::join(), and wait().

Member Data Documentation

◆ f_verbose

int VTaskGroup::f_verbose = GetEnv<int>("PTL_VERBOSE", 0)
staticprotected

Definition at line 142 of file VTaskGroup.hh.

Referenced by set_verbose(), and wait().

◆ m_id

uintmax_t PTL::VTaskGroup::m_id
protected

Definition at line 135 of file VTaskGroup.hh.

Referenced by id().

◆ m_main_tid

tid_type PTL::VTaskGroup::m_main_tid
protected

Definition at line 140 of file VTaskGroup.hh.

Referenced by is_master().

◆ m_pool

ThreadPool* PTL::VTaskGroup::m_pool
protected

◆ m_task_cond

std::shared_ptr<condition_t> PTL::VTaskGroup::m_task_cond = std::make_shared<condition_t>()
protected

Definition at line 138 of file VTaskGroup.hh.

Referenced by task_cond(), and wait().

◆ m_task_lock

std::shared_ptr<lock_t> PTL::VTaskGroup::m_task_lock = std::make_shared<lock_t>()
protected

Definition at line 139 of file VTaskGroup.hh.

Referenced by wait().

◆ m_tot_task_count

std::shared_ptr<atomic_int> PTL::VTaskGroup::m_tot_task_count = std::make_shared<atomic_int>(0)
protected

Definition at line 137 of file VTaskGroup.hh.

Referenced by operator++(), operator--(), pending(), size(), and task_count().

◆ vtask_list

vtask_list_type PTL::VTaskGroup::vtask_list
protected

Definition at line 141 of file VTaskGroup.hh.

Referenced by clear(), and PTL::TaskGroup< Tp, Arg >::operator+=().


The documentation for this class was generated from the following files: