32 using Functor = std::function<void()>;
34 Thread(std::string name =
"",
int cpuid = -1,
int priority = 0,
int policy = POLICY_DEFAULT_VALUE)
36 name_(std::move(name)),
45 if (thread_.joinable()) {
51 void SetName(
const std::string& name) { name_ = name; }
53 void SetAffinity(
int cpuid) { cpuid_ = cpuid; }
55 void SetOSPriority(
int priority,
int policy) {
60 void StartFunc(
const Functor& func) {
62 throw std::runtime_error(
"Thread already started");
65 thread_ = std::thread([
this, func]() {
80 bool IsRunning()
const {
return running_; }
83 if (thread_.joinable()) {
95 std::atomic<bool> running_{};
97 void SetThreadName() {
100 const DWORD MS_VC_EXCEPTION = 0x406D1388;
104 typedef struct tagTHREADNAME_INFO {
113 THREADNAME_INFO info;
114 info.dwType = 0x1000;
115 info.szName = name_.c_str();
116 info.dwThreadID = GetCurrentThreadId();
120 RaiseException(MS_VC_EXCEPTION, 0,
sizeof(info) /
sizeof(ULONG_PTR), (ULONG_PTR*)&info);
121 } __except (EXCEPTION_EXECUTE_HANDLER) {}
122#elif defined(__APPLE__)
123 pthread_setname_np(name_.c_str());
125 pthread_setname_np(pthread_self(), name_.c_str());
130 void SetThreadAffinity() {
133 DWORD_PTR mask = 1 << cpuid_;
134 SetThreadAffinityMask(GetCurrentThread(), mask);
135#elif defined(__APPLE__)
136 thread_affinity_policy_data_t policy = {cpuid_};
137 thread_port_t mach_thread = pthread_mach_thread_np(pthread_self());
138 kern_return_t ret = thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1);
139 if (ret != KERN_SUCCESS) {
140 throw std::runtime_error(
"Error setting thread affinity on macOS");
145 CPU_SET(cpuid_, &cpuset);
147 int rc = pthread_setaffinity_np(pthread_self(),
sizeof(cpu_set_t), &cpuset);
149 throw std::runtime_error(
"Error calling pthread_setaffinity_np");
155 void SetThreadPriority() {
156 if (priority_ != 0) {
158 int win_priority = THREAD_PRIORITY_NORMAL;
160 win_priority = THREAD_PRIORITY_HIGHEST;
161 }
else if (priority_ < 0) {
162 win_priority = THREAD_PRIORITY_LOWEST;
164 ::SetThreadPriority(GetCurrentThread(), win_priority);
166 struct sched_param param{};
168 param.sched_priority = priority_;
170 int rc = pthread_setschedparam(pthread_self(), policy_, ¶m);
172 throw std::runtime_error(
"Error calling pthread_setschedparam");