diff --git a/src/lib/thread.cpp b/src/lib/thread.cpp
new file mode 100644
index 000000000..588c9d402
--- /dev/null
+++ b/src/lib/thread.cpp
@@ -0,0 +1,114 @@
+/*
+ THREAD.hpp - thin convenience wrapper for starting threads
+
+ Copyright (C) Lumiera.org
+ 2023, Hermann Vosseler
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+* *****************************************************/
+
+/** @file sync.cpp
+ ** This compilation unit holds some implementation details
+ ** of the [thread wrapper](\ref lib::Thread), relegated here
+ ** to reduce header inclusions.
+ ** @warning setting the thread name only works on some POSIX systems,
+ ** and using a GNU specific addition to the libC here.
+ */
+
+
+#include "lib/thread.hpp"
+#include "lib/format-string.hpp"
+#include "lib/util.hpp"
+
+#include
+#include
+
+using std::chrono::steady_clock;
+using std::chrono_literals::operator ""ms;
+
+
+
+namespace lib {
+namespace thread{
+
+ namespace {
+
+ void
+ setThreadName (std::thread& handle, string name)
+ {
+ // API limitation: max 15 characters + \0
+ name = util::sanitise(name).substr(0, 15);
+
+ pthread_t nativeHandle = handle.native_handle();
+ pthread_setname_np(nativeHandle, name.c_str());
+ }
+
+ void
+ lifecycle (string format, string threadID)
+ {
+ string message = util::_Fmt{format} % threadID;
+ TRACE (thread, "%s", message.c_str());
+ }
+ }
+
+
+
+ template
+ void
+ ThreadWrapper::markThreadStart (string const& threadID)
+ {
+ lifecycle ("Thread '%s' start...", threadID);
+ setThreadName (threadImpl_, threadID);
+ }
+
+
+ template
+ void
+ ThreadWrapper::markThreadEnd (string const& threadID)
+ {
+ lifecycle ("Thread '%s' finished.", threadID);
+ }
+
+
+ template
+ void
+ ThreadWrapper::waitGracePeriod() noexcept
+ {
+ try {
+ auto start = steady_clock::now();
+ while (threadImpl_.joinable()
+ and steady_clock::now () - start < 20ms
+ )
+ std::this_thread::yield();
+ }
+ ERROR_LOG_AND_IGNORE (thread, "Thread shutdown wait")
+
+ if (threadImpl_.joinable())
+ ALERT (thread, "Thread failed to terminate after grace period. Abort.");
+ // invocation of std::thread dtor will presumably call std::terminate...
+ }
+
+
+ template void ThreadWrapper::markThreadStart (string const&);
+ template void ThreadWrapper::markThreadEnd (string const&);
+ template void ThreadWrapper::waitGracePeriod () noexcept;
+
+ template void ThreadWrapper::markThreadStart (string const&);
+ template void ThreadWrapper::markThreadEnd (string const&);
+ template void ThreadWrapper::waitGracePeriod () noexcept;
+
+
+}}// namespace lib::thread
diff --git a/src/lib/thread.hpp b/src/lib/thread.hpp
index 69deb4b94..c402867dd 100644
--- a/src/lib/thread.hpp
+++ b/src/lib/thread.hpp
@@ -105,13 +105,10 @@
#include "lib/nocopy.hpp"
#include "include/logging.h"
#include "lib/meta/function.hpp"
-#include "lib/format-string.hpp" ///////////////////////////OOO RLY? or maybe into CPP file?
-#include "lib/result.hpp"
#include
#include
#include
-#include
namespace lib {
@@ -198,40 +195,9 @@ namespace lib {
} // Note: implies get_id() != std::thread::id{} ==> it is running
private:
- void
- markThreadStart (string const& threadID)
- {
- string logMsg = util::_Fmt{"Thread '%s' start..."} % threadID;
- TRACE (thread, "%s", logMsg.c_str());
- //////////////////////////////////////////////////////////////////////OOO maybe set the the Thread-ID via POSIX ??
- }
-
- void
- markThreadEnd (string const& threadID)
- {
- string logMsg = util::_Fmt{"Thread '%s' finished..."} % threadID;
- TRACE (thread, "%s", logMsg.c_str());
- }
-
- void
- waitGracePeriod() noexcept
- {
- using std::chrono::steady_clock;
- using std::chrono_literals::operator ""ms;
-
- try {
- auto start = steady_clock::now();
- while (threadImpl_.joinable()
- and steady_clock::now () - start < 20ms
- )
- std::this_thread::yield();
- }
- ERROR_LOG_AND_IGNORE (thread, "Thread shutdown wait")
-
- if (threadImpl_.joinable())
- ALERT (thread, "Thread failed to terminate after grace period. Abort.");
- // invocation of std::thread dtor will presumably call std::terminate...
- }
+ void markThreadStart (string const& threadID);
+ void markThreadEnd (string const& threadID);
+ void waitGracePeriod() noexcept;
};
}//(End)base implementation.
@@ -281,7 +247,7 @@ namespace lib {
join ()
{
if (not threadImpl_.joinable())
- throw error::Logic ("joining on an already terminated thread");
+ throw lumiera::error::Logic ("joining on an already terminated thread");
threadImpl_.join();
}
diff --git a/tests/15library.tests b/tests/15library.tests
index ddc1815b6..0757347c8 100644
--- a/tests/15library.tests
+++ b/tests/15library.tests
@@ -747,17 +747,6 @@ END
TEST "util: sanitised identifier" UtilSanitizedIdentifier_test < 'Word'
-out-lit: 'a Sentence' --> 'a_Sentence'
-out-lit: 'trailing Withespace
-out-lit: ' --> 'trailing_Withespace'
-out-lit: 'with a lot
-out-lit: of Whitespace' --> 'with_a_lot_of_Whitespace'
-out-lit: '@with".'much (\$punctuation)[]!' --> '@with.much_(\$punctuation)'
-out-lit: '§&Ω%€ leading garbage' --> 'leading_garbage'
-out-lit: 'mixed Ω garbage' --> 'mixed_garbage'
-out-lit: 'Bääääh!!' --> 'Bh'
-out-lit: '§&Ω%€' --> ''
return: 0
END
diff --git a/tests/library/util-sanitised-identifier-test.cpp b/tests/library/util-sanitised-identifier-test.cpp
index bf8288715..bc27f07c7 100644
--- a/tests/library/util-sanitised-identifier-test.cpp
+++ b/tests/library/util-sanitised-identifier-test.cpp
@@ -26,6 +26,7 @@
#include "lib/test/run.hpp"
+#include "lib/test/test-helper.hpp"
#include "lib/util.hpp"
@@ -42,22 +43,16 @@ namespace test {
{
virtual void run (Arg)
{
- print_clean ("Word");
- print_clean ("a Sentence");
- print_clean ("trailing Withespace\n \t");
- print_clean ("with a \t lot\n of Whitespace");
- print_clean ("@with\".\'much ($punctuation)[]!");
- print_clean ("§&Ω%€ leading garbage");
- print_clean ("mixed Ω garbage");
- print_clean ("Bääääh!!");
- print_clean ("§&Ω%€");
+ CHECK (sanitise ( "Word") == "Word"_expect);
+ CHECK (sanitise ( "a Sentence") == "a_Sentence"_expect);
+ CHECK (sanitise ( "trailing Withespace\n \t") == "trailing_Withespace"_expect);
+ CHECK (sanitise ("with a \t lot\n of Whitespace") == "with_a_lot_of_Whitespace"_expect);
+ CHECK (sanitise ( "@with\".\'much ($punctuation)[]!") == "@with.much_($punctuation)"_expect);
+ CHECK (sanitise ( "§&Ω%€ leading garbage") == "leading_garbage"_expect);
+ CHECK (sanitise ( "mixed Ω garbage") == "mixed_garbage"_expect);
+ CHECK (sanitise ( "Bääääh!!") == "Bh"_expect);
+ CHECK (sanitise ( "§&Ω%€") == ""_expect);
}
-
- /** @test print the original and the sanitised string */
- void print_clean (const string org)
- {
- cout << "'" << org << "' --> '" << sanitise(org) << "'\n";
- }
};
LAUNCHER (UtilSanitizedIdentifier_test, "unit common");
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm
index a990804fa..3f36033b3 100644
--- a/wiki/thinkPad.ichthyo.mm
+++ b/wiki/thinkPad.ichthyo.mm
@@ -79299,9 +79299,9 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
-
-
+
+
+
@@ -79312,10 +79312,41 @@ Date: Thu Apr 20 18:53:17 2023 +0200
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ std::thread::native_handle() ⟼ liefert hier pthread_t
+
+
+
+
+
+
+
+
+
+
+
+