PLCnext API Documentation  22.9.0.33
Thread.hpp
1 //
3 // Copyright PHOENIX CONTACT Electronics GmbH
4 //
6 #pragma once
7 #include "Arp/System/Core/Arp.h"
8 #include "Arp/System/Core/delegate.hxx"
9 #include "Arp/System/Commons/Threading/ThreadSettings.hpp"
10 #include "Arp/System/Commons/Logging.h"
11 #include "Arp/System/Commons/Threading/AutoResetEvent.hpp"
12 #include "Arp/System/Commons/Threading/ThreadState.hpp"
13 #include "Arp/System/Commons/Threading/Semaphore.hpp"
14 
15 #include <atomic>
16 
17 // forwards
18 namespace Arp { namespace System { namespace Ve
19 {
20 class IThreadService;
21 }}}
22 
23 namespace Arp { namespace System { namespace Commons { namespace Threading
24 {
25 
26 // forwards
27 class ThreadBinaryCompatibilityExtensions;
28 
29 // forwards
30 class AutoResetEvent2;
31 
76 class Thread : private Loggable<Thread>
77 {
78 private: // friends
79  friend class AutoResetEvent;
80  friend class AutoResetEvent2;
81 
82 public: // typedefs/usings
84  typedef void (*ThreadStartFunction)(void*);
85 
87  typedef delegate<void(void*)> ThreadStartDelegate;
88 
90  static const std::size_t CpuAffinityAll;
91 
92 public: // construction/destruction
93 
99  template<class TInstance, class TFunction>
100  ARP_DEPRECATED("Use constructor with ThreadSettings instead. Supply at least a thread name!")
101  Thread(TInstance& instance, TFunction fn, void* pStartParam = nullptr);
102 
108  template<class TInstance, class TFunction>
109  ARP_DEPRECATED("Use constructor with ThreadSettings instead. Supply at least a thread name!")
110  Thread(const TInstance& instance, TFunction fn, void* pStartParam = nullptr);
111 
117  template<class TInstance, class TFunction>
118  ARP_DEPRECATED("Use constructor with ThreadSettings instead. Supply at least a thread name!")
119  Thread(TInstance* pInstance, TFunction fn, void* pStartParam = nullptr);
120 
126  template<class TInstance, class TFunction>
127  ARP_DEPRECATED("Use constructor with ThreadSettings instead. Supply at least a thread name!")
128  Thread(const TInstance* pInstance, TFunction fn, void* pStartParam = nullptr);
129 
134  ARP_DEPRECATED("Use constructor with ThreadSettings instead. Supply at least a thread name!")
135  explicit Thread(ThreadStartDelegate&& threadStart, void* pStartParam = nullptr);
136 
145  ARP_DEPRECATED("Use constructor with ThreadSettings instead. Supply at least a thread name!")
146  Thread(ThreadStartFunction threadStart, void* pStartParam = nullptr);
147 
154  template<class TInstance, class TFunction>
155  Thread(const ThreadSettings& settings, TInstance& instance, TFunction fn, void* pStartParam = nullptr);
156 
163  template<class TInstance, class TFunction>
164  Thread(const ThreadSettings& settings, const TInstance& instance, TFunction fn, void* pStartParam = nullptr);
165 
172  template<class TInstance, class TFunction>
173  Thread(const ThreadSettings& settings, TInstance* pInstance, TFunction fn, void* pStartParam = nullptr);
174 
181  template<class TInstance, class TFunction>
182  Thread(const ThreadSettings& settings, const TInstance* pInstance, TFunction fn, void* pStartParam = nullptr);
183 
189  Thread(ThreadSettings& settings, ThreadStartDelegate&& threadStart, void* pStartParam = nullptr);
190 
196  Thread(ThreadSettings& settings, ThreadStartFunction threadStart, void* pStartParam = nullptr);
197 
203  Thread(const ThreadSettings& settings, ThreadStartDelegate&& threadStart, void* pStartParam = nullptr);
204 
210  Thread(const ThreadSettings& settings, ThreadStartFunction threadStart, void* pStartParam = nullptr);
211 
215  ~Thread(void);
216 
217 public: // static operations
218 
221  static void Sleep(size_t milliseconds);
222 
225  static size_t GetCurrentThreadId(void);
226 
229  static Thread* GetCurrentThread(void);
230 
239  static void SetAsynchronousCancelability(bool enable);
240 
241 public: // properties/setter/getter
243  bool IsRunning(void)const;
244 
262  void SetCpuAffinity(size_t mask);
263 
267  size_t GetCpuAffinity(void)const;
268 
272  void SetPriority(size_t value);
273 
276  size_t GetPriority(void)const;
277 
290  ARP_DEPRECATED("Set thread stack size at the constructor")
291  void SetStackSize(size_t value);
292 
295  size_t GetStackSize(void)const;
296 
304  void SetName(const String& value);
305 
308  const String& GetName(void)const;
309 
312  ThreadState GetState() const;
318  bool IsJoinable(void);
319 
320 public: // operations
323  void Start(void);
324 
328  void Join(void);
329 
335  void Interrupt(void);
336 
338  void Terminate(void);
339 
340 private: // typedefs/usings
341  using IThreadService = Arp::System::Ve::IThreadService;
342 
343 private: // static methods
344  static void* RunInternal(void* pParam);
345  static void CheckInterruptOfCurrentThread(void);
346  static void SetStateOfCurrentThread(ThreadState state);
347  static String CreateDefaultThreadName(void);
348 
349 private: // methods
350  void CreateThreadInternal(void);
351  void CreateThreadInternal(const ThreadSettings& parameter);
352  void RunThread(ThreadBinaryCompatibilityExtensions* pBinCompat);
353 
354 private: // deleted methods
355  Thread(const Thread& arg) = delete;
356  Thread& operator=(const Thread& arg) = delete;
357 
358 private: // fields
359  ThreadStartDelegate threadStart;
360  void* pStartParam;
361  ThreadBinaryCompatibilityExtensions* pBinaryCompatibilityExtensions;
362  AutoResetEvent exitEvent;
363  std::atomic<ThreadState> state;
364  std::atomic<bool> interrupting;
365 
366 private: // static fields
367  static thread_local Thread* pCurrentThread;
368 };
369 
371 // inline methods of class Thread
372 template<class TInstance, class TFunction>
373 inline Thread::Thread(TInstance& instance, TFunction fn, void* pStartParam)
374  : Thread(&instance, fn, pStartParam)
375 {
376 }
377 
378 template<class TInstance, class TFunction>
379 inline Thread::Thread(const TInstance& instance, TFunction fn, void* pStartParam)
380  : Thread(&instance, fn, pStartParam)
381 {
382 }
383 
384 template<class TInstance, class TFunction>
385 inline Thread::Thread(TInstance* pInstance, TFunction fn, void* pStartParam)
386  : threadStart(make_delegate(pInstance, fn))
387  , pStartParam(pStartParam)
388  , pBinaryCompatibilityExtensions(nullptr)
389  , state(ThreadState::Stopped)
390  , interrupting(false)
391 {
392  this->CreateThreadInternal();
393 }
394 
395 template<class TInstance, class TFunction>
396 inline Thread::Thread(const TInstance* pInstance, TFunction fn, void* pStartParam)
397  : threadStart(make_delegate(pInstance, fn))
398  , pStartParam(pStartParam)
399  , pBinaryCompatibilityExtensions(nullptr)
400  , state(ThreadState::Stopped)
401  , interrupting(false)
402 {
403  this->CreateThreadInternal();
404 }
405 
406 inline Thread::Thread(ThreadStartDelegate&& threadStart, void* pStartParam)
407  : threadStart(std::move(threadStart))
408  , pStartParam(pStartParam)
409  , pBinaryCompatibilityExtensions(nullptr)
410  , state(ThreadState::Stopped)
411  , interrupting(false)
412 {
413  this->CreateThreadInternal();
414 }
415 
416 inline Thread::Thread(ThreadStartFunction threadStart, void* pStartParam)
417  : threadStart(make_delegate(threadStart))
418  , pStartParam(pStartParam)
419  , pBinaryCompatibilityExtensions(nullptr)
420  , state(ThreadState::Stopped)
421  , interrupting(false)
422 {
423  this->CreateThreadInternal();
424 }
425 
426 template<class TInstance, class TFunction>
427 inline Thread::Thread(const ThreadSettings& settings, TInstance& instance, TFunction fn, void* pStartParam)
428  : Thread(settings, &instance, fn, pStartParam)
429 {
430 }
431 
432 template<class TInstance, class TFunction>
433 inline Thread::Thread(const ThreadSettings& settings, const TInstance& instance, TFunction fn, void* pStartParam)
434  : Thread(settings, &instance, fn, pStartParam)
435 {
436 }
437 
438 template<class TInstance, class TFunction>
439 inline Thread::Thread(const ThreadSettings& settings, TInstance* pInstance, TFunction fn, void* pStartParam)
440  : threadStart(make_delegate(pInstance, fn))
441  , pStartParam(pStartParam)
442  , pBinaryCompatibilityExtensions(nullptr)
443  , state(ThreadState::Stopped)
444  , interrupting(false)
445 {
446  this->CreateThreadInternal(settings);
447 }
448 
449 template<class TInstance, class TFunction>
450 inline Thread::Thread(const ThreadSettings& settings, const TInstance* pInstance, TFunction fn, void* pStartParam)
451  : threadStart(make_delegate(pInstance, fn))
452  , pStartParam(pStartParam)
453  , pBinaryCompatibilityExtensions(nullptr)
454  , state(ThreadState::Stopped)
455  , interrupting(false)
456 {
457  this->CreateThreadInternal(settings);
458 }
459 
460 inline Thread::Thread(ThreadSettings& settings, ThreadStartDelegate&& threadStart, void* pStartParam)
461  : Thread((const ThreadSettings&)settings, std::move(threadStart), pStartParam)
462 {
463 }
464 
465 inline Thread::Thread(ThreadSettings& settings, ThreadStartFunction threadStart, void* pStartParam)
466  : Thread((const ThreadSettings&)settings, threadStart, pStartParam)
467 {
468 }
469 
470 inline Thread::Thread(const ThreadSettings& settings, ThreadStartDelegate&& threadStart, void* pStartParam)
471  : threadStart(std::move(threadStart))
472  , pStartParam(pStartParam)
473  , pBinaryCompatibilityExtensions(nullptr)
474  , state(ThreadState::Stopped)
475  , interrupting(false)
476 {
477  this->CreateThreadInternal(settings);
478 }
479 
480 inline Thread::Thread(const ThreadSettings& settings, ThreadStartFunction threadStart, void* pStartParam)
481  : threadStart(make_delegate(threadStart))
482  , pStartParam(pStartParam)
483  , pBinaryCompatibilityExtensions(nullptr)
484  , state(ThreadState::Stopped)
485  , interrupting(false)
486 {
487  this->CreateThreadInternal(settings);
488 }
489 
490 inline bool Thread::IsRunning(void)const
491 {
492  return (this->GetState() == ThreadState::Running);
493 }
494 
496 {
497  return Thread::pCurrentThread;
498 }
499 
500 inline void Thread::Interrupt(void)
501 {
502  this->interrupting = true;
503 }
504 
505 inline ThreadState Thread::GetState(void) const
506 {
507  return this->state.load();
508 }
509 
510 }}}} // end of namespace Arp::System::Commons::Threading
Event object to signal a single thread that an event has occurred. Can be used to synchronize threads...
Definition: AutoResetEvent.hpp:23
Container class for adaptable thread settings.
Definition: ThreadSettings.hpp:13
The Thread-class provides methods to execute functions and methods in a separate thread.
Definition: Thread.hpp:77
size_t GetPriority(void) const
Returns the current priority of the thread.
void SetStackSize(size_t value)
Sets a new stack size for the thread.
ThreadState GetState() const
Returns the current state of the thread.
Definition: Thread.hpp:505
void SetName(const String &value)
Sets a new name to the thread.
static const std::size_t CpuAffinityAll
Use this constant to express an affinity of the thread to all available CPUs aka. cores.
Definition: Thread.hpp:90
void Interrupt(void)
Interrupts the currents execution.
Definition: Thread.hpp:500
static size_t GetCurrentThreadId(void)
Returns the id of the calling thread.
void(* ThreadStartFunction)(void *)
Definition of signature of function to be executed in a separate thread.
Definition: Thread.hpp:84
void Join(void)
Waits for the thread to terminate.
static void Sleep(size_t milliseconds)
Suspends the execution of the calling thread.
void SetPriority(size_t value)
Assigns a new priority to the thread.
Thread(TInstance &instance, TFunction fn, void *pStartParam=nullptr)
Constructs a Thread instance for a class method.
Definition: Thread.hpp:373
size_t GetStackSize(void) const
Returns the current stack size of the thread.Current size of stack in bytes.
static void SetAsynchronousCancelability(bool enable)
Activates/Deactivates the asynchronous cancelability of the calling thread.
void Start(void)
Starts the execution of the thread.
bool IsRunning(void) const
Determines if this thread is in running state.
Definition: Thread.hpp:490
delegate< void(void *)> ThreadStartDelegate
Definition of signature of class method to be executed in a separate thread.
Definition: Thread.hpp:87
const String & GetName(void) const
Returns the current name of the thread.
size_t GetCpuAffinity(void) const
Returns the CPU affinity mask.
static Thread * GetCurrentThread(void)
Returns the current thread of the calling context.
Definition: Thread.hpp:495
bool IsJoinable(void)
Checks if this thread is joinable.
void SetCpuAffinity(size_t mask)
Pins the thread to a specific CPUs inside a multiprocessor system.
void Terminate(void)
Aborts the execution of this thread.
delegate< R(A...)> make_delegate(R(*const function_ptr)(A...)) noexcept
Creates a delegate from a static function.
Definition: delegate.hxx:225
@ System
System components used by the System, Device, Plc or Io domains.
ThreadState
Possible thread states.
Definition: ThreadState.hpp:15
@ Running
summary>Thread is up and running
Root namespace for the PLCnext API
Namespace of the C++ standard library