Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
thread.cpp
Go to the documentation of this file.
1/*
2 THREAD.hpp - thin convenience wrapper for starting threads
3
4 Copyright (C)
5 2023, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12* *****************************************************************/
13
23#include "lib/thread.hpp"
24#include "lib/format-string.hpp"
25#include "lib/symbol.hpp"
26#include "lib/util.hpp"
27
28#include <chrono>
29#include <atomic>
30#include <pthread.h>
31
32using util::_Fmt;
33using lib::Literal;
34using std::atomic_uint;
35using std::chrono::steady_clock;
36using std::chrono_literals::operator ""ms;
37
38
39
40namespace lib {
41namespace thread{
42
43 namespace {
44 const auto SHUTDOWN_GRACE_PERIOD = 20ms;
45
46 string
47 lifecycleMsg (Literal phase, string threadID)
48 {
49 return _Fmt{"Thread '%s' %s"} % threadID % phase;
50 }
51 }
52
53
55 string
57 {
58 static atomic_uint globalCnt{1};
59 return _Fmt{"%s.%03i"} % rawID % globalCnt.fetch_add (+1, std::memory_order_acq_rel);
60 }
61
62
64 bool
66 {
67 return threadImpl_.get_id() == std::this_thread::get_id();
68 }
69
70
71 void
73 {
74 TRACE (thread, "%s", lifecycleMsg ("start...", threadID_).c_str());
76 }
77
78
79 void
81 {
82 TRACE (thread, "%s", lifecycleMsg ("terminates.", threadID_).c_str());
83 }
84
85
86 void
88 {
89 pthread_t nativeHandle = threadImpl_.native_handle();
90
91 // API limitation: max 15 characters + \0
92 pthread_setname_np(nativeHandle, threadID_.substr(0, 15).c_str());
93 }
94
95
96 void
98 {
99 try {
100 auto start = steady_clock::now();
101 while (threadImpl_.joinable()
102 and steady_clock::now () - start < SHUTDOWN_GRACE_PERIOD
103 )
104 std::this_thread::yield();
105 }
106 ERROR_LOG_AND_IGNORE (thread, lifecycleMsg("shutdown wait", threadID_).c_str());
107
108 if (threadImpl_.joinable())
109 ALERT (thread, "Thread '%s' failed to terminate after grace period. Abort.", threadID_.c_str());
110 // invocation of std::thread dtor will presumably call std::terminate...
111 }
112
113
114
115}}// namespace lib::thread
Inline string literal.
Definition symbol.hpp:78
A front-end for using printf-style formatting.
#define ERROR_LOG_AND_IGNORE(_FLAG_, _OP_DESCR_)
convenience shortcut for a sequence of catch blocks just logging and consuming an error.
Definition error.hpp:267
Front-end for printf-style string template interpolation.
string lifecycleMsg(Literal phase, string threadID)
Definition thread.cpp:47
Implementation namespace for support and library code.
void waitGracePeriod() noexcept
Definition thread.cpp:97
bool invokedWithinThread() const
detect if the currently executing code runs within this thread
Definition thread.cpp:65
static string decorate_with_global_count(string const &)
Helper to create a suffix to the thread-ID with running count.
Definition thread.cpp:56
Marker types to indicate a literal string and a Symbol.
Convenience front-end to simplify and codify basic thread handling.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...