8 #include <argos3/core/simulator/simulator.h>
9 #include <argos3/core/utility/profiler/profiler.h>
25 static void CleanupThread(
void* p_data) {
30 SCleanupThreadData& sData =
31 *
reinterpret_cast<SCleanupThreadData*
>(p_data);
32 pthread_mutex_unlock(sData.FetchTaskMutex);
33 pthread_mutex_unlock(sData.StartSenseControlPhaseMutex);
34 pthread_mutex_unlock(sData.StartActPhaseMutex);
35 pthread_mutex_unlock(sData.StartPhysicsPhaseMutex);
36 pthread_mutex_unlock(sData.StartMediaPhaseMutex);
37 pthread_mutex_unlock(sData.StartEntityIterPhaseMutex);
42 LOG.AddThreadSafeBuffer();
43 LOGERR.AddThreadSafeBuffer();
45 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,
nullptr);
46 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,
nullptr);
48 auto* psData =
reinterpret_cast<CSpaceMultiThreadBalanceLength::SThreadLaunchData*
>(p_data);
57 pthread_cleanup_push(CleanupThread, &sCancelData);
58 psData->Space->SlaveThread();
60 pthread_cleanup_pop(1);
73 if((nErrors = pthread_mutex_init(&m_tStartSenseControlPhaseMutex,
nullptr)) ||
74 (nErrors = pthread_mutex_init(&m_tStartActPhaseMutex,
nullptr)) ||
75 (nErrors = pthread_mutex_init(&m_tStartPhysicsPhaseMutex,
nullptr)) ||
76 (nErrors = pthread_mutex_init(&m_tStartMediaPhaseMutex,
nullptr)) ||
77 (nErrors = pthread_mutex_init(&m_tStartEntityIterPhaseMutex,
nullptr)) ||
78 (nErrors = pthread_mutex_init(&m_tFetchTaskMutex,
nullptr))) {
82 if((nErrors = pthread_cond_init(&m_tStartSenseControlPhaseCond,
nullptr)) ||
83 (nErrors = pthread_cond_init(&m_tStartActPhaseCond,
nullptr)) ||
84 (nErrors = pthread_cond_init(&m_tStartPhysicsPhaseCond,
nullptr)) ||
85 (nErrors = pthread_cond_init(&m_tStartMediaPhaseCond,
nullptr)) ||
86 (nErrors = pthread_cond_init(&m_tStartEntityIterPhaseCond,
nullptr)) ||
87 (nErrors = pthread_cond_init(&m_tFetchTaskCond,
nullptr))) {
106 if(m_ptThreads !=
nullptr) {
108 if((nErrors = pthread_cancel(m_ptThreads[i]))) {
114 if((nErrors = pthread_join(m_ptThreads[i], ppJoinResult + i))) {
117 if(ppJoinResult[i] != PTHREAD_CANCELED) {
118 LOGERR <<
"[WARNING] Thread #" << i<<
" not canceled" << std::endl;
121 delete[] ppJoinResult;
123 delete[] m_ptThreads;
125 if(m_psThreadData !=
nullptr) {
127 delete m_psThreadData[i];
130 delete[] m_psThreadData;
131 pthread_mutex_destroy(&m_tStartSenseControlPhaseMutex);
132 pthread_mutex_destroy(&m_tStartActPhaseMutex);
133 pthread_mutex_destroy(&m_tStartPhysicsPhaseMutex);
134 pthread_mutex_destroy(&m_tStartMediaPhaseMutex);
135 pthread_mutex_destroy(&m_tStartEntityIterPhaseMutex);
136 pthread_mutex_destroy(&m_tFetchTaskMutex);
138 pthread_cond_destroy(&m_tStartSenseControlPhaseCond);
139 pthread_cond_destroy(&m_tStartActPhaseCond);
140 pthread_cond_destroy(&m_tStartPhysicsPhaseCond);
141 pthread_cond_destroy(&m_tStartMediaPhaseCond);
142 pthread_cond_destroy(&m_tStartEntityIterPhaseCond);
143 pthread_cond_destroy(&m_tFetchTaskCond);
166 #define MAIN_START_PHASE(PHASE) \
167 pthread_mutex_lock(&m_tStart ## PHASE ## PhaseMutex); \
168 m_un ## PHASE ## PhaseIdleCounter = 0; \
170 pthread_cond_broadcast(&m_tStart ## PHASE ## PhaseCond); \
171 pthread_mutex_unlock(&m_tStart ## PHASE ## PhaseMutex);
173 #define MAIN_WAIT_FOR_END_OF(PHASE) \
174 pthread_mutex_lock(&m_tStart ## PHASE ## PhaseMutex); \
175 while(m_un ## PHASE ## PhaseIdleCounter < CSimulator::GetInstance().GetNumThreads()) { \
176 pthread_cond_wait(&m_tStart ## PHASE ## PhaseCond, &m_tStart ## PHASE ## PhaseMutex); \
178 pthread_mutex_unlock(&m_tStart ## PHASE ## PhaseMutex);
196 (*m_ptPhysicsEngines)[i]->TransferEntities();
234 void CSpaceMultiThreadBalanceLength::StartThreads() {
241 m_psThreadData[i] =
new SThreadLaunchData(i,
this);
243 if((nErrors = pthread_create(m_ptThreads + i,
246 reinterpret_cast<void*
>(m_psThreadData[i])))) {
255 #define THREAD_WAIT_FOR_START_OF(PHASE) \
256 pthread_mutex_lock(&m_tStart ## PHASE ## PhaseMutex); \
257 while(m_un ## PHASE ## PhaseIdleCounter == CSimulator::GetInstance().GetNumThreads()) { \
258 pthread_cond_wait(&m_tStart ## PHASE ## PhaseCond, &m_tStart ## PHASE ## PhaseMutex); \
260 pthread_mutex_unlock(&m_tStart ## PHASE ## PhaseMutex); \
261 pthread_testcancel();
263 #define THREAD_PERFORM_TASK(PHASE, TASKVEC, CONDITION, SNIPPET) \
265 pthread_mutex_lock(&m_tFetchTaskMutex); \
266 if((CONDITION) && m_unTaskIndex < (TASKVEC).size()) { \
267 unTaskIndex = m_unTaskIndex; \
269 pthread_mutex_unlock(&m_tFetchTaskMutex); \
270 pthread_testcancel(); \
274 pthread_testcancel(); \
277 pthread_mutex_unlock(&m_tFetchTaskMutex); \
278 pthread_testcancel(); \
279 pthread_mutex_lock(&m_tStart ## PHASE ## PhaseMutex); \
280 ++m_un ## PHASE ## PhaseIdleCounter; \
281 pthread_cond_broadcast(&m_tStart ## PHASE ## PhaseCond); \
282 pthread_mutex_unlock(&m_tStart ## PHASE ## PhaseMutex); \
283 pthread_testcancel(); \
287 pthread_testcancel();
289 void CSpaceMultiThreadBalanceLength::SlaveThread() {
#define THREAD_WAIT_FOR_START_OF(PHASE)
#define MAIN_WAIT_FOR_END_OF(PHASE)
#define THREAD_PERFORM_TASK(PHASE, TASKVEC, CONDITION, SNIPPET)
#define MAIN_START_PHASE(PHASE)
#define THROW_ARGOSEXCEPTION(message)
This macro throws an ARGoS exception with the passed message.
unsigned int UInt32
32-bit unsigned integer.
The namespace containing all the ARGoS related code.
CARGoSLog LOGERR(std::cerr, SLogColor(ARGOS_LOG_ATTRIBUTE_BRIGHT, ARGOS_LOG_COLOR_RED))
ticpp::Element TConfigurationNode
The ARGoS configuration XML node.
CARGoSLog LOG(std::cout, SLogColor(ARGOS_LOG_ATTRIBUTE_BRIGHT, ARGOS_LOG_COLOR_GREEN))
void * LaunchThreadBalanceLength(void *p_data)
CProfiler & GetProfiler()
Returns a reference to the profiler.
static CSimulator & GetInstance()
Returns the instance to the CSimulator class.
UInt32 GetNumThreads() const
Returns the number of threads used during the experiment.
bool IsProfiling() const
Returns true if ARGoS is being profiled.
CControllableEntity::TVector m_vecControllableEntities
A vector of controllable entities.
virtual void Init(TConfigurationNode &t_tree)
Initializes the space using the <arena> section of the XML configuration file.
virtual void Destroy()
Destroys the space and all its entities.
bool ControllableEntityIterationEnabled() const
virtual void Update()
Updates the space.
CPhysicsEngine::TVector * m_ptPhysicsEngines
A pointer to the list of physics engines.
TControllableEntityIterCBType m_cbControllableEntityIter
Callback for iterating over entities from within the loop functions.
CMedium::TVector * m_ptMedia
A pointer to the list of media.
std::function< void(CControllableEntity *)> TControllableEntityIterCBType
The callback type for iteration over controllable entities within the PreStep() and/or PostStep() par...
pthread_mutex_t * StartMediaPhaseMutex
pthread_mutex_t * StartEntityIterPhaseMutex
pthread_mutex_t * StartSenseControlPhaseMutex
pthread_mutex_t * FetchTaskMutex
pthread_mutex_t * StartActPhaseMutex
pthread_mutex_t * StartPhysicsPhaseMutex
virtual void UpdatePhysics()
virtual void UpdateControllableEntitiesSenseStep()
virtual void Update()
Updates the space.
virtual void IterateOverControllableEntities(const TControllableEntityIterCBType &c_cb)
Given a callback specified in the loop functions, iterate over all controllable entities currently pr...
virtual void Destroy()
Destroys the space and all its entities.
friend void * LaunchThreadBalanceLength(void *p_data)
virtual void Init(TConfigurationNode &t_tree)
Initializes the space using the <arena> section of the XML configuration file.
virtual void UpdateControllableEntitiesAct()
virtual void UpdateMedia()
void CollectThreadResourceUsage()