aboutsummaryrefslogtreecommitdiffstats
path: root/util/system/thread.h
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /util/system/thread.h
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'util/system/thread.h')
-rw-r--r--util/system/thread.h174
1 files changed, 174 insertions, 0 deletions
diff --git a/util/system/thread.h b/util/system/thread.h
new file mode 100644
index 0000000000..a6e8abdb5b
--- /dev/null
+++ b/util/system/thread.h
@@ -0,0 +1,174 @@
+#pragma once
+
+/// This code should not be used directly unless you really understand what you do.
+/// If you need threads, use thread pool functionality in <util/thread/factory.h>
+/// @see SystemThreadFactory()
+
+#include <util/generic/ptr.h>
+#include <util/generic/string.h>
+
+#include "defaults.h"
+#include "progname.h"
+
+bool SetHighestThreadPriority();
+
+class TThread {
+ template <typename Callable>
+ struct TCallableParams;
+ struct TPrivateCtor {};
+
+public:
+ using TThreadProc = void* (*)(void*);
+ using TId = size_t;
+
+ struct TParams {
+ TThreadProc Proc;
+ void* Data;
+ size_t StackSize;
+ void* StackPointer;
+ // See comments for `SetCurrentThreadName`
+ TString Name = GetProgramName();
+
+ inline TParams()
+ : Proc(nullptr)
+ , Data(nullptr)
+ , StackSize(0)
+ , StackPointer(nullptr)
+ {
+ }
+
+ inline TParams(TThreadProc proc, void* data)
+ : Proc(proc)
+ , Data(data)
+ , StackSize(0)
+ , StackPointer(nullptr)
+ {
+ }
+
+ inline TParams(TThreadProc proc, void* data, size_t stackSize)
+ : Proc(proc)
+ , Data(data)
+ , StackSize(stackSize)
+ , StackPointer(nullptr)
+ {
+ }
+
+ inline TParams& SetName(const TString& name) noexcept {
+ Name = name;
+
+ return *this;
+ }
+
+ inline TParams& SetStackSize(size_t size) noexcept {
+ StackSize = size;
+
+ return *this;
+ }
+
+ inline TParams& SetStackPointer(void* ptr) noexcept {
+ StackPointer = ptr;
+
+ return *this;
+ }
+ };
+
+ TThread(const TParams& params);
+ TThread(TThreadProc threadProc, void* param);
+
+ template <typename Callable>
+ TThread(Callable&& callable)
+ : TThread(TPrivateCtor{},
+ MakeHolder<TCallableParams<Callable>>(std::forward<Callable>(callable)))
+ {
+ }
+
+ TThread(TParams&& params)
+ : TThread((const TParams&)params)
+ {
+ }
+
+ TThread(TParams& params)
+ : TThread((const TParams&)params)
+ {
+ }
+
+ ~TThread();
+
+ void Start();
+
+ void* Join();
+ void Detach();
+ bool Running() const noexcept;
+ TId Id() const noexcept;
+
+ static TId ImpossibleThreadId() noexcept;
+ static TId CurrentThreadId() noexcept;
+
+ /*
+ * Returns numeric thread id, as visible in e. g. htop.
+ * Consider using this value for logging.
+ */
+ static TId CurrentThreadNumericId() noexcept;
+
+ // NOTE: Content of `name` will be copied.
+ //
+ // NOTE: On Linux thread name is limited to 15 symbols which is probably the smallest one among
+ // all platforms. If you provide a name longer than 15 symbols it will be cut. So if you expect
+ // `CurrentThreadName` to return the same name as `name` make sure it's not longer than 15
+ // symbols.
+ static void SetCurrentThreadName(const char* name);
+
+ // NOTE: Will return empty string where CanGetCurrentThreadName() returns false.
+ static TString CurrentThreadName();
+
+ // NOTE: Depends on a platform version.
+ // Will return true for Darwin, Linux or fresh Windows 10.
+ static bool CanGetCurrentThreadName();
+
+private:
+ struct TCallableBase {
+ virtual ~TCallableBase() = default;
+ virtual void run() = 0;
+
+ static void* ThreadWorker(void* arg) {
+ static_cast<TCallableBase*>(arg)->run();
+ return nullptr;
+ }
+ };
+
+ template <typename Callable>
+ struct TCallableParams: public TCallableBase {
+ TCallableParams(Callable&& callable)
+ : Callable_(std::forward<Callable>(callable))
+ {
+ }
+
+ Callable Callable_;
+
+ void run() override {
+ Callable_();
+ }
+ };
+
+ TThread(TPrivateCtor, THolder<TCallableBase> callable);
+
+private:
+ class TImpl;
+ THolder<TImpl> Impl_;
+};
+
+class ISimpleThread: public TThread {
+public:
+ ISimpleThread(size_t stackSize = 0);
+
+ virtual ~ISimpleThread() = default;
+
+ virtual void* ThreadProc() = 0;
+};
+
+struct TCurrentThreadLimits {
+ TCurrentThreadLimits() noexcept;
+
+ const void* StackBegin;
+ size_t StackLength;
+};