icl_core_thread/Thread.cpp
Go to the documentation of this file.
1 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
2 
3 // -- BEGIN LICENSE BLOCK ----------------------------------------------
4 // This file is part of FZIs ic_workspace.
5 //
6 // This program is free software licensed under the LGPL
7 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
8 // You can find a copy of this license in LICENSE folder in the top
9 // directory of the source code.
10 //
11 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
12 //
13 // -- END LICENSE BLOCK ------------------------------------------------
14 
15 //----------------------------------------------------------------------
22 //----------------------------------------------------------------------
23 #include "Thread.h"
24 
25 #include <icl_core/os_lxrt.h>
26 #include <icl_core/os_string.h>
27 #include <icl_core/os_time.h>
28 
29 #include "Common.h"
30 #include "Logging.h"
31 
32 #if defined _SYSTEM_LXRT_
33 # include "ThreadImplLxrt.h"
34 #endif
35 
36 #if defined _SYSTEM_POSIX_
37 # include "ThreadImplPosix.h"
38 #elif defined _SYSTEM_WIN32_
39 # include "ThreadImplWin32.h"
40 #else
41 # error "No implementation specified for System dependent components"
42 #endif
43 
45 
46 namespace icl_core {
47 namespace thread {
48 
49 Thread::Thread(const icl_core::String& description, ThreadPriority priority)
50  : m_execute(false),
51  m_finished(true),
52  m_joined(true),
53  m_starting(false),
54  m_thread_info(description + ", 0"),
55  m_priority(priority),
56  m_impl(NULL)
57 {
58 #if defined _SYSTEM_LXRT_
59  // Only create an LXRT implementation if the LXRT runtime system
60  // is really available. Otherwise create an ACE or POSIX implementation,
61  // depending on the system configuration.
62  // Remark: This allows us to compile programs with LXRT support but run
63  // them on systems on which no LXRT is installed and to disable LXRT support
64  // at program startup on systems with installed LXRT!
66  {
67  m_impl = new ThreadImplLxrt(this, description, priority);
68  }
69  else
70  {
71  m_impl = new ThreadImplPosix(this, description, priority);
72  }
73 
74 #elif defined _SYSTEM_POSIX_
75  m_impl = new ThreadImplPosix(this, description, priority);
76 
77 #elif defined _SYSTEM_WIN32_
78  m_impl = new ThreadImplWin32(this, description, priority);
79 
80 #endif
81 }
82 
84 {
85  if (!m_joined)
86  {
87  stop();
88  join();
89  }
90 
91  delete m_impl;
92  m_impl = NULL;
93 }
94 
96 {
97  LOGGING_TRACE_CO(IclCoreThread, Thread, threadInfo(), "Begin." << endl);
98  waitStarted();
99  if (running())
100  {
101  LOGGING_DEBUG_CO(IclCoreThread, Thread, threadInfo(), "Still running." << endl);
102  m_execute = false;
103  m_impl->cancel();
104  m_finished = true;
105  }
106  LOGGING_DEBUG_CO(IclCoreThread, Thread, threadInfo(), "Done." << endl);
107 }
108 
110 {
111 #ifdef _SYSTEM_LXRT_
112  if (threadSelf() && os::isThisHRT() && !isHardRealtime() && m_priority < 0)
113  {
114  return setHardRealtime(true);
115  }
116  else
117 #endif
118  {
119  return false;
120  }
121 }
122 
124 {
125  return m_impl->getDescription();
126 }
127 
129 {
130  return m_impl->isHardRealtime();
131 }
132 
134 {
135  return m_impl->executesHardRealtime();
136 }
137 
139 {
140  if (running())
141  {
142  m_impl->join();
143  }
144 
145  m_joined = true;
146 }
147 
149 {
150  return m_impl->priority();
151 }
152 
153 void Thread::setDescription(const icl_core::String& description)
154 {
155  m_impl->setDescription(description);
156 }
157 
158 bool Thread::setHardRealtime(bool hard_realtime)
159 {
160  return m_impl->setHardRealtime(hard_realtime);
161 }
162 
164 {
165  if (m_impl->setPriority(priority))
166  {
168  return true;
169  }
170  else
171  {
172  return false;
173  }
174 }
175 
177 {
178  // Don't do anything if the thread is already starting or running.
179  if (m_starting || running())
180  {
181  waitStarted();
182 
183  return running();
184  }
185 
186  m_starting = true;
187  m_finished = false;
188 
189  if (!m_joined)
190  {
191  join();
192  }
193 
194  m_joined = false;
195 
196  if (!m_impl->start())
197  {
198  m_finished = true;
199  m_starting = false;
200  m_joined = true;
201 
202  return false;
203  }
204  else
205  {
206  waitStarted();
207 
208  return true;
209  }
210 }
211 
213 {
214  return m_impl->threadId();
215 }
216 
218 {
219  char buffer[1024];
220 #if defined(_SYSTEM_WIN32_)
221  icl_core::os::snprintf(buffer, 1023, "%s, %lu", getDescription().c_str(), threadId());
222 #elif defined(_SYSTEM_DARWIN_)
223  icl_core::os::snprintf(buffer, 1023, "%s, %p", getDescription().c_str(), threadId().m_thread_id);
224 #else
225  icl_core::os::snprintf(buffer, 1023, "%s, %lu", getDescription().c_str(), threadId().m_thread_id);
226 #endif
228 
229  LOGGING_TRACE_CO(IclCoreThread, Thread, threadInfo(), "Begin." << endl);
230 
232  m_execute = true;
233  m_starting = false;
234  m_finished = false;
235 
236  // If this is actually a periodic thread, this call makes it periodic.
237  // It this is a "normal" thread, this call does nothing.
238  makePeriodic();
239 
240  // Call the run loop.
241  run();
242 
243  m_execute = false;
245  m_finished = true;
246 
247  LOGGING_TRACE_CO(IclCoreThread, Thread, threadInfo(), "Done." << endl);
248 }
249 
251 {
253 }
254 
256 {
257  bool success = false;
258 
259  if (m_joined)
260  {
261  return true;
262  }
263 
264  waitStarted();
265 
266  if (m_finished)
267  {
268  success = true;
269  }
270  else if ((until == icl_core::TimeStamp::maxTime() && m_thread_mutex.lock())
271  || m_thread_mutex.lock(until))
272  {
274  }
275  else if (icl_core::TimeStamp::now() < until)
276  {
277  LOGGING_ERROR_CO(IclCoreThread, Thread, threadInfo(),
278  "Thread is running and we should still wait, but LockMutex() returned unexpected."
279  "The wait function will now block further until the thread is really finished."
280  "But consider that your implementation could have a failure in locking ..." << endl);
281 
282  while (icl_core::TimeStamp::now() < until && !m_finished)
283  {
284  os::sleep(1);
285  }
286  }
287 
288  if (m_finished)
289  {
290  success = true;
291  }
292 
293  if (success)
294  {
295  join();
296  return true;
297  }
298  else
299  {
300  LOGGING_ERROR_CO(IclCoreThread, Thread, threadInfo(), "Wait not succesful." << endl);
301  return false;
302  }
303 }
304 
306 {
307  return wait(impl::getAbsoluteTimeout(timeout));
308 }
309 
311 #ifdef _IC_BUILDER_DEPRECATED_STYLE_
312 
321 void Thread::Cancel()
322 {
323  cancel();
324 }
325 
329 bool Thread::CheckHardRealtime()
330 {
331  return checkHardRealtime();
332 }
333 
337 icl_core::String Thread::Description() const
338 {
339  return getDescription();
340 }
341 
346 bool Thread::Execute() const
347 {
348  return execute();
349 }
350 
354 bool Thread::IsHardRealtime() const
355 {
356  return isHardRealtime();
357 }
358 
363 bool Thread::ExecutesHardRealtime() const
364 {
365  return executesHardRealtime();
366 }
367 
371 void Thread::Join()
372 {
373  join();
374 }
375 
379 icl_core::ThreadPriority Thread::Priority() const
380 {
381  return priority();
382 }
383 
387 bool Thread::Running() const
388 {
389  return running();
390 }
391 
395 void Thread::SetDescription(const icl_core::String& description)
396 {
397  setDescription(description);
398 }
399 
403 bool Thread::SetHardRealtime(bool hard_realtime)
404 {
405  return setHardRealtime(hard_realtime);
406 }
407 
411 bool Thread::SetPriority(icl_core::ThreadPriority priority)
412 {
413  return setPriority(priority);
414 }
415 
419 bool Thread::Start()
420 {
421  return start();
422 }
423 
427 void Thread::Stop()
428 {
429  stop();
430 }
431 
436 {
437  return threadId();
438 }
439 
444 const char *Thread::ThreadInfo() const
445 {
446  return threadInfo();
447 }
448 
453 bool Thread::ThreadSelf() const
454 {
455  return threadSelf();
456 }
457 
461 bool Thread::Wait()
462 {
463  return wait();
464 }
465 
470 bool Thread::Wait(const icl_core::TimeStamp& timeout)
471 {
472  return wait(timeout);
473 }
474 
479 bool Thread::Wait(const icl_core::TimeSpan& timeout)
480 {
481  return wait(timeout);
482 }
483 
487 icl_core::ThreadId Thread::SelfId()
488 {
489  return selfId();
490 }
491 
492 #endif
493 
496 {
497  while (m_starting)
498  {
499  // Sleep for 1 microsecond.
501  }
502 }
503 
505 {
506 }
507 
509 #ifdef _IC_BUILDER_DEPRECATED_STYLE_
510 
514 void Thread::RunThread()
515 {
516  runThread();
517 }
518 
522 void Thread::WaitStarted() const
523 {
524  waitStarted();
525 }
526 
527 #endif
528 
530 }
531 }
ICL_CORE_OS_IMPL_NS::ThreadId ThreadId
Definition: os_thread.h:49
TimeStamp getAbsoluteTimeout(const TimeSpan &timeout_relative)
Definition: Common.h:59
static icl_core::ThreadId selfId()
icl_core::ThreadPriority m_priority
Represents absolute times.
Definition: TimeStamp.h:61
virtual void run()=0
bool setPriority(icl_core::ThreadPriority priority)
static TimeStamp now()
Definition: TimeStamp.cpp:111
virtual icl_core::String getDescription() const =0
icl_core::String getDescription() const
Contains global functions for string manipulation, encapsulated into the icl_core::os namespace...
#define LOGGING_ERROR_CO(stream, classname, objectname, arg)
int usleep(unsigned long useconds)
Definition: os_time.h:56
unsigned int sleep(unsigned int seconds)
Definition: os_time.h:51
bool isLxrtAvailable()
Definition: os_lxrt.cpp:141
virtual icl_core::ThreadPriority priority() const =0
Thread(const icl_core::String &description, icl_core::ThreadPriority priority=0)
Contains logging definitions for the icl_core_thread library.
ThreadStream & endl(ThreadStream &stream)
Definition: ThreadStream.h:249
#define LOGGING_TRACE_CO(stream, classname, objectname, arg)
#define LOGGING_DEBUG_CO(stream, classname, objectname, arg)
bool setHardRealtime(bool hard_realtime=true)
Contains icl_core::thread::tMutex.
virtual bool isHardRealtime() const =0
static char buffer[2000]
const TimeSpan timeout(1, 0)
virtual void setDescription(const icl_core::String &description)=0
bool isThisHRT()
Definition: os_lxrt.cpp:159
void setDescription(const icl_core::String &description)
Contains global LXRT functions.
icl_core::ThreadPriority priority() const
Repesents absolute times.
Definition: TimeSpan.h:46
std::string String
Definition: BaseTypes.h:43
virtual bool setPriority(icl_core::ThreadPriority priority)=0
Contains icl_core::thread::Thread.
Contains global functions for time manipulation, encapsulated into the icl_core::os namespace...
icl_core::ThreadId threadId() const
virtual bool executesHardRealtime() const =0
const char * threadInfo() const
virtual icl_core::ThreadId threadId() const =0
int32_t ThreadPriority
Definition: os_thread.h:50
static TimeStamp maxTime()
Definition: TimeStamp.h:285
virtual bool setHardRealtime(bool hard_realtime)=0
int snprintf(char *buffer, size_t maxlen, const char *format,...)
Definition: os_string.cpp:28


fzi_icl_core
Author(s):
autogenerated on Mon Jun 10 2019 13:17:58