PLCnext API Documentation 23.6.0.37
Thread.hpp
1
2//
3// Copyright PHOENIX CONTACT Electronics GmbH
4//
6#pragma once
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
18namespace Arp { namespace System { namespace Ve
19{
20class IThreadService;
21}}}
22
23namespace Arp { namespace System { namespace Commons { namespace Threading
24{
25
26// forwards
27class ThreadBinaryCompatibilityExtensions;
28
29// forwards
30class AutoResetEvent2;
31
76class Thread : private Loggable<Thread>
77{
78private: // friends
79 friend class AutoResetEvent;
80 friend class AutoResetEvent2;
81
82public: // typedefs/usings
84 typedef void (*ThreadStartFunction)(void*);
85
87 typedef delegate<void(void*)> ThreadStartDelegate;
88
90 static const std::size_t CpuAffinityAll;
91
92public: // construction/destruction
93
100 template<class TInstance, class TFunction>
101 ARP_DEPRECATED("Use constructor with ThreadSettings instead. Supply at least a thread name!")
102 Thread(TInstance& instance, TFunction fn, void* pStartParam = nullptr);
103
110 template<class TInstance, class TFunction>
111 ARP_DEPRECATED("Use constructor with ThreadSettings instead. Supply at least a thread name!")
112 Thread(const TInstance& instance, TFunction fn, void* pStartParam = nullptr);
113
120 template<class TInstance, class TFunction>
121 ARP_DEPRECATED("Use constructor with ThreadSettings instead. Supply at least a thread name!")
122 Thread(TInstance* pInstance, TFunction fn, void* pStartParam = nullptr);
123
130 template<class TInstance, class TFunction>
131 ARP_DEPRECATED("Use constructor with ThreadSettings instead. Supply at least a thread name!")
132 Thread(const TInstance* pInstance, TFunction fn, void* pStartParam = nullptr);
133
139 ARP_DEPRECATED("Use constructor with ThreadSettings instead. Supply at least a thread name!")
140 explicit Thread(ThreadStartDelegate&& threadStart, void* pStartParam = nullptr);
141
151 ARP_DEPRECATED("Use constructor with ThreadSettings instead. Supply at least a thread name!")
152 Thread(ThreadStartFunction threadStart, void* pStartParam = nullptr);
153
160 template<class TInstance, class TFunction>
161 Thread(const ThreadSettings& settings, TInstance& instance, TFunction fn, void* pStartParam = nullptr);
162
169 template<class TInstance, class TFunction>
170 Thread(const ThreadSettings& settings, const TInstance& instance, TFunction fn, void* pStartParam = nullptr);
171
178 template<class TInstance, class TFunction>
179 Thread(const ThreadSettings& settings, TInstance* pInstance, TFunction fn, void* pStartParam = nullptr);
180
187 template<class TInstance, class TFunction>
188 Thread(const ThreadSettings& settings, const TInstance* pInstance, TFunction fn, void* pStartParam = nullptr);
189
195 Thread(ThreadSettings& settings, ThreadStartDelegate&& threadStart, void* pStartParam = nullptr);
196
202 Thread(ThreadSettings& settings, ThreadStartFunction threadStart, void* pStartParam = nullptr);
203
209 Thread(const ThreadSettings& settings, ThreadStartDelegate&& threadStart, void* pStartParam = nullptr);
210
216 Thread(const ThreadSettings& settings, ThreadStartFunction threadStart, void* pStartParam = nullptr);
217
221 ~Thread(void);
222
223public: // static operations
224
227 static void Sleep(size_t milliseconds);
228
231 static size_t GetCurrentThreadId(void);
232
235 static Thread* GetCurrentThread(void);
236
245 static void SetAsynchronousCancelability(bool enable);
246
247public: // properties/setter/getter
249 bool IsRunning(void)const;
250
268 void SetCpuAffinity(size_t mask);
269
273 size_t GetCpuAffinity(void)const;
274
278 void SetPriority(size_t value);
279
282 size_t GetPriority(void)const;
283
296 ARP_DEPRECATED("Set thread stack size at the constructor")
297 void SetStackSize(size_t value);
298
301 size_t GetStackSize(void)const;
302
310 void SetName(const String& value);
311
314 const String& GetName(void)const;
315
318 ThreadState GetState() const;
324 bool IsJoinable(void);
325
326public: // operations
329 void Start(void);
330
334 void Join(void);
335
341 void Interrupt(void);
342
344 void Terminate(void);
345
346private: // typedefs/usings
347 using IThreadService = Arp::System::Ve::IThreadService;
348
349private: // static methods
350 static void* RunInternal(void* pParam);
351 static void CheckInterruptOfCurrentThread(void);
352 static void SetStateOfCurrentThread(ThreadState state);
353 static String CreateDefaultThreadName(void);
354
355private: // methods
356 void CreateThreadInternal(void);
357 void CreateThreadInternal(const ThreadSettings& parameter);
358 void RunThread(ThreadBinaryCompatibilityExtensions* pBinCompat);
359
360private: // deleted methods
361 Thread(const Thread& arg) = delete;
362 Thread& operator=(const Thread& arg) = delete;
363
364private: // fields
365 ThreadStartDelegate threadStart;
366 void* pStartParam;
367 ThreadBinaryCompatibilityExtensions* pBinaryCompatibilityExtensions;
368 AutoResetEvent exitEvent;
369 std::atomic<ThreadState> state;
370 std::atomic<bool> interrupting;
371
372private: // static fields
373 static thread_local Thread* pCurrentThread;
374};
375
377// inline methods of class Thread
378template<class TInstance, class TFunction>
379inline Thread::Thread(TInstance& instance, TFunction fn, void* pStartParam)
380 : Thread(&instance, fn, pStartParam)
381{
382}
383
384template<class TInstance, class TFunction>
385inline Thread::Thread(const TInstance& instance, TFunction fn, void* pStartParam)
386 : Thread(&instance, fn, pStartParam)
387{
388}
389
390template<class TInstance, class TFunction>
391inline Thread::Thread(TInstance* pInstance, TFunction fn, void* pStartParam)
392 : threadStart(make_delegate(pInstance, fn))
393 , pStartParam(pStartParam)
394 , pBinaryCompatibilityExtensions(nullptr)
395 , state(ThreadState::Stopped)
396 , interrupting(false)
397{
398 this->CreateThreadInternal();
399}
400
401template<class TInstance, class TFunction>
402inline Thread::Thread(const TInstance* pInstance, TFunction fn, void* pStartParam)
403 : threadStart(make_delegate(pInstance, fn))
404 , pStartParam(pStartParam)
405 , pBinaryCompatibilityExtensions(nullptr)
406 , state(ThreadState::Stopped)
407 , interrupting(false)
408{
409 this->CreateThreadInternal();
410}
411
412inline Thread::Thread(ThreadStartDelegate&& threadStart, void* pStartParam)
413 : threadStart(std::move(threadStart))
414 , pStartParam(pStartParam)
415 , pBinaryCompatibilityExtensions(nullptr)
416 , state(ThreadState::Stopped)
417 , interrupting(false)
418{
419 this->CreateThreadInternal();
420}
421
422inline Thread::Thread(ThreadStartFunction threadStart, void* pStartParam)
423 : threadStart(make_delegate(threadStart))
424 , pStartParam(pStartParam)
425 , pBinaryCompatibilityExtensions(nullptr)
426 , state(ThreadState::Stopped)
427 , interrupting(false)
428{
429 this->CreateThreadInternal();
430}
431
432template<class TInstance, class TFunction>
433inline Thread::Thread(const ThreadSettings& settings, TInstance& instance, TFunction fn, void* pStartParam)
434 : Thread(settings, &instance, fn, pStartParam)
435{
436}
437
438template<class TInstance, class TFunction>
439inline Thread::Thread(const ThreadSettings& settings, const TInstance& instance, TFunction fn, void* pStartParam)
440 : Thread(settings, &instance, fn, pStartParam)
441{
442}
443
444template<class TInstance, class TFunction>
445inline Thread::Thread(const ThreadSettings& settings, TInstance* pInstance, TFunction fn, void* pStartParam)
446 : threadStart(make_delegate(pInstance, fn))
447 , pStartParam(pStartParam)
448 , pBinaryCompatibilityExtensions(nullptr)
449 , state(ThreadState::Stopped)
450 , interrupting(false)
451{
452 this->CreateThreadInternal(settings);
453}
454
455template<class TInstance, class TFunction>
456inline Thread::Thread(const ThreadSettings& settings, const TInstance* pInstance, TFunction fn, void* pStartParam)
457 : threadStart(make_delegate(pInstance, fn))
458 , pStartParam(pStartParam)
459 , pBinaryCompatibilityExtensions(nullptr)
460 , state(ThreadState::Stopped)
461 , interrupting(false)
462{
463 this->CreateThreadInternal(settings);
464}
465
466inline Thread::Thread(ThreadSettings& settings, ThreadStartDelegate&& threadStart, void* pStartParam)
467 : Thread((const ThreadSettings&)settings, std::move(threadStart), pStartParam)
468{
469}
470
471inline Thread::Thread(ThreadSettings& settings, ThreadStartFunction threadStart, void* pStartParam)
472 : Thread((const ThreadSettings&)settings, threadStart, pStartParam)
473{
474}
475
476inline Thread::Thread(const ThreadSettings& settings, ThreadStartDelegate&& threadStart, void* pStartParam)
477 : threadStart(std::move(threadStart))
478 , pStartParam(pStartParam)
479 , pBinaryCompatibilityExtensions(nullptr)
480 , state(ThreadState::Stopped)
481 , interrupting(false)
482{
483 this->CreateThreadInternal(settings);
484}
485
486inline Thread::Thread(const ThreadSettings& settings, ThreadStartFunction threadStart, void* pStartParam)
487 : threadStart(make_delegate(threadStart))
488 , pStartParam(pStartParam)
489 , pBinaryCompatibilityExtensions(nullptr)
490 , state(ThreadState::Stopped)
491 , interrupting(false)
492{
493 this->CreateThreadInternal(settings);
494}
495
496inline bool Thread::IsRunning(void)const
497{
498 return (this->GetState() == ThreadState::Running);
499}
500
502{
503 return Thread::pCurrentThread;
504}
505
506inline void Thread::Interrupt(void)
507{
508 this->interrupting = true;
509}
510
512{
513 return this->state.load();
514}
515
516}}}} // 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)
Deprecated! Sets a new stack size for the thread.
const String & GetName(void) const
Returns the current name of the thread.
ThreadState GetState() const
Returns the current state of the thread.
Definition: Thread.hpp:511
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:506
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)
Deprecated! Constructs a Thread instance for a class method.
Definition: Thread.hpp:379
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:496
delegate< void(void *)> ThreadStartDelegate
Definition of signature of class method to be executed in a separate thread.
Definition: Thread.hpp:87
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:501
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
@ Stopped
summary>Thread is either waiting for an event, currently sleeping or waits for another thread to fini...
Root namespace for the PLCnext API
class ARP_DEPRECATED("Use Arp::Enum<T> instead.") EnumStrings
Deprecated! The class implements an adapter for enums to define the string literals of the enum entri...
Definition: EnumStrings.hxx:38
Namespace of the C++ standard library