summaryrefslogtreecommitdiff
path: root/src/thread.h
diff options
context:
space:
mode:
authorMichael Lutz <michi@icosahedron.de>2019-03-17 01:59:46 +0100
committerMichael Lutz <michi@icosahedron.de>2019-04-06 11:27:39 +0200
commit05bc2ed7cbe07cb4cd535932f10778b35f72e944 (patch)
tree0faaf12fd1bafb0786236ffc82052e8b83dfca60 /src/thread.h
parent05f4e7360886e36b221ef5c3af4426625a3de686 (diff)
downloadopenttd-05bc2ed7cbe07cb4cd535932f10778b35f72e944.tar.xz
Codechange: Replace custom thread code with C++11 thread objects.
We assume a conforming C++11 compiler environment that has a valid <thread>-header. Failure to run a real thread is handled gracefully.
Diffstat (limited to 'src/thread.h')
-rw-r--r--src/thread.h78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/thread.h b/src/thread.h
new file mode 100644
index 000000000..086e2f51e
--- /dev/null
+++ b/src/thread.h
@@ -0,0 +1,78 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD 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, version 2.
+ * OpenTTD 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 OpenTTD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file thread.h Base of all threads. */
+
+#ifndef THREAD_H
+#define THREAD_H
+
+#include "debug.h"
+#include <system_error>
+#include <thread>
+
+/** Signal used for signalling we knowingly want to end the thread. */
+class OTTDThreadExitSignal { };
+
+
+/**
+ * Get number of processor cores in the system, including HyperThreading or similar.
+ * @return Total number of processor cores.
+ */
+uint GetCPUCoreCount();
+
+/**
+ * Name the thread this function is called on for the debugger.
+ * @param name Name to set for the thread..
+ */
+void SetCurrentThreadName(const char *name);
+
+
+/**
+ * Start a new thread.
+ * @tparam TFn Type of the function to call on the thread.
+ * @tparam TArgs Type of the parameters of the thread function.
+ * @param thr Pointer to a thread object; may be \c NULL if a detached thread is wanted.
+ * @param name Name of the thread.
+ * @param _Fx Function to call on the thread.
+ * @param _Ax Arguments for the thread function.
+ * @return True if the thread was successfully started, false otherwise.
+ */
+template<class TFn, class... TArgs>
+inline bool StartNewThread(std::thread *thr, const char *name, TFn&& _Fx, TArgs&&... _Ax)
+{
+#ifndef NO_THREADS
+ try {
+ std::thread t([] (const char *name, TFn&& F, TArgs&&... A) {
+ SetCurrentThreadName(name);
+ try {
+ /* Call user function with the given arguments. */
+ F(A...);
+ } catch (OTTDThreadExitSignal&) {
+ } catch (...) {
+ NOT_REACHED();
+ }
+ }, name, std::forward<TFn>(_Fx), std::forward<TArgs>(_Ax)...);
+
+ if (thr != NULL) {
+ *thr = std::move(t);
+ } else {
+ t.detach();
+ }
+
+ return true;
+ } catch (const std::system_error& e) {
+ /* Something went wrong, the system we are running on might not support threads. */
+ DEBUG(misc, 1, "Can't create thread '%s': %s", name, e.what());
+ }
+#endif
+
+ return false;
+}
+
+#endif /* THREAD_H */