123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- #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();
- bool SetLowestThreadPriority();
- 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;
- };
|