join 1.0
lightweight network framework library
Loading...
Searching...
No Matches
thread.hpp
Go to the documentation of this file.
1
25#ifndef JOIN_CORE_THREAD_HPP
26#define JOIN_CORE_THREAD_HPP
27
28// libjoin.
29#include <join/utils.hpp>
30
31// C++.
32#include <system_error>
33#include <type_traits>
34#include <functional>
35#include <memory>
36#include <atomic>
37
38// C.
39#include <sys/syscall.h>
40#include <pthread.h>
41#include <unistd.h>
42
43namespace join
44{
48 class Invoker
49 {
50 public:
54 Invoker () = delete;
55
56 private:
67 template <class Function, class... Args>
68 explicit Invoker (int core, int prio, size_t stackSize, bool prefault, Function&& func, Args&&... args)
69 : _func (std::bind (std::forward<Function> (func), std::forward<Args> (args)...))
70 , _core (core)
71 , _priority (prio)
72 , _prefault (prefault)
73 , _done (false)
74 {
75 pthread_attr_t attr;
76 pthread_attr_init (&attr);
77
78 if (stackSize > 0)
79 {
80 const int err = pthread_attr_setstacksize (&attr, stackSize);
81 if (err != 0)
82 {
83 pthread_attr_destroy (&attr);
84 throw std::system_error (err, std::system_category (), "pthread_attr_setstacksize failed");
85 }
86 }
87
88 const int err = pthread_create (&_handle, &attr, _routine, this);
89 pthread_attr_destroy (&attr);
90 if (err != 0)
91 {
92 throw std::system_error (err, std::system_category (), "pthread_create failed"); // LCOV_EXCL_LINE
93 }
94 }
95
96 public:
101 Invoker (const Invoker& other) = delete;
102
108 Invoker& operator= (const Invoker& other) = delete;
109
114 Invoker (Invoker&& other) = delete;
115
121 Invoker& operator= (Invoker&& other) = delete;
122
126 ~Invoker () = default;
127
128 private:
133 static int prefault () noexcept;
134
140 static void* _routine (void* context);
141
146 void* routine ();
147
149 std::function<void ()> _func;
150
152 pthread_t _handle = {};
153
155 std::atomic_int _core{-1};
156
158 std::atomic_int _priority{0};
159
161 bool _prefault = false;
162
164 static constexpr pid_t _invalidId = -1;
165
167 std::atomic<pid_t> _id{_invalidId};
168
170 std::atomic_bool _done;
171
173 friend class Thread;
174 };
175
179 class Thread
180 {
181 public:
183 static constexpr pid_t invalidId = Invoker::_invalidId;
184
188 Thread () noexcept = default;
189
196 template <class Function, class... Args>
197 explicit Thread (Function&& func, Args&&... args)
198 requires (!std::is_arithmetic_v<std::decay_t<Function>>)
199 : Thread (-1, 0, 0, false, std::forward<Function> (func), std::forward<Args> (args)...)
200 {
201 }
202
211 template <class Function, class... Args>
212 explicit Thread (int core, int prio, Function&& func, Args&&... args)
213 requires (!std::is_arithmetic_v<std::decay_t<Function>>)
214 : Thread (core, prio, 0, false, std::forward<Function> (func), std::forward<Args> (args)...)
215 {
216 }
217
228 template <class Function, class... Args>
229 explicit Thread (int core, int prio, size_t stackSize, bool prefault, Function&& func, Args&&... args)
230 : _invoker (new Invoker (core, prio, stackSize, prefault, std::forward<Function> (func),
231 std::forward<Args> (args)...))
232 {
233 }
234
239 Thread (const Thread& other) = delete;
240
246 Thread& operator= (const Thread& other) = delete;
247
252 Thread (Thread&& other) noexcept;
253
259 Thread& operator= (Thread&& other) noexcept;
260
264 ~Thread ();
265
271 int affinity (int core);
272
279 static int affinity (pthread_t handle, int core);
280
285 int affinity () const noexcept;
286
292 int priority (int prio);
293
300 static int priority (pthread_t handle, int prio);
301
306 int priority () const noexcept;
307
312 bool joinable () const noexcept;
313
318 bool running () const noexcept;
319
323 void join () noexcept;
324
329 bool tryJoin () noexcept;
330
334 void cancel () noexcept;
335
340 void swap (Thread& other) noexcept;
341
346 static pid_t currentId () noexcept
347 {
348 static thread_local pid_t tid __attribute__ ((tls_model ("initial-exec"))) = 0;
349 if (JOIN_UNLIKELY (tid == 0))
350 {
351 static const int registered = ::pthread_atfork (nullptr, nullptr, [] () {
352 tid = 0;
353 });
354 static_cast<void> (registered);
355 tid = static_cast<pid_t> (::syscall (SYS_gettid));
356 }
357 return tid;
358 }
359
364 pid_t id () const noexcept;
365
370 pthread_t handle () const noexcept;
371
372 private:
374 std::unique_ptr<Invoker> _invoker;
375 };
376}
377
378#endif
fixed-capacity move-only allocation-free alternative to std::function.
Definition function.hpp:44
thread invoker class.
Definition thread.hpp:49
Invoker()=delete
default constructor.
~Invoker()=default
destoyer.
Invoker(const Invoker &other)=delete
copy constructor.
Invoker & operator=(const Invoker &other)=delete
copy assignment.
Invoker(Invoker &&other)=delete
move constructor.
thread class.
Definition thread.hpp:180
int priority() const noexcept
get current thread priority.
Definition thread.cpp:265
int affinity() const noexcept
get current thread affinity.
Definition thread.cpp:202
~Thread()
destroys the thread object.
Definition thread.cpp:139
bool tryJoin() noexcept
performs a nonblocking join on the running thread.
Definition thread.cpp:305
Thread() noexcept=default
default constructor.
static constexpr pid_t invalidId
invalid thread id.
Definition thread.hpp:183
Thread(int core, int prio, size_t stackSize, bool prefault, Function &&func, Args &&... args)
creates a new thread object associated with a thread of execution.
Definition thread.hpp:229
static pid_t currentId() noexcept
get calling thread id.
Definition thread.hpp:346
Thread(const Thread &other)=delete
copy constructor.
void swap(Thread &other) noexcept
swap underlying handles of two thread objects.
Definition thread.cpp:332
void cancel() noexcept
cancel the running thread if any.
Definition thread.cpp:319
Thread & operator=(const Thread &other)=delete
copy assignment.
pid_t id() const noexcept
get thread id.
Definition thread.cpp:341
bool joinable() const noexcept
check if thread is joinable.
Definition thread.cpp:274
pthread_t handle() const noexcept
get the handle of the thread of execution.
Definition thread.cpp:350
bool running() const noexcept
check if the thread is running.
Definition thread.cpp:283
Thread(int core, int prio, Function &&func, Args &&... args)
creates a new thread object associated with a thread of execution.
Definition thread.hpp:212
Definition acceptor.hpp:32
__attribute__((cold, noinline)) void throwException(Args &&... args)
throw an exception out of the hot path.
Definition utils.hpp:75
Definition error.hpp:144
#define JOIN_UNLIKELY(x)
Definition utils.hpp:51