-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpin_thread.h
125 lines (107 loc) · 3.08 KB
/
pin_thread.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//
// Created by Anders Cedronius
//
#pragma once
#ifdef __APPLE__
#include <TargetConditionals.h>
#ifdef TARGET_OS_MAC
#include <sys/types.h>
#include <sys/sysctl.h>
#import <mach/thread_act.h>
#define SYSCTL_CORE_COUNT "machdep.cpu.core_count"
typedef struct cpu_set {
uint32_t count;
} cpu_set_t;
static inline void
CPU_ZERO(cpu_set_t *cs) { cs->count = 0; }
static inline void
CPU_SET(int num, cpu_set_t *cs) { cs->count |= (1 << num); }
static inline int
CPU_ISSET(int num, cpu_set_t *cs) { return (cs->count & (1 << num)); }
bool raise_thread_priority() {
/* raise the thread's priority */
thread_extended_policy_data_t extendedPolicy;
thread_act_t this_thread = pthread_mach_thread_np(pthread_self());
extendedPolicy.timeshare = 0;
kern_return_t error = thread_policy_set(this_thread, THREAD_EXTENDED_POLICY,
(thread_policy_t)&extendedPolicy,
THREAD_EXTENDED_POLICY_COUNT);
if (error != KERN_SUCCESS) {
std::cout << "Couldn't set thread timeshare policy" << std::endl;
return false;
}
return true;
}
int sched_getaffinity(pid_t pid, size_t cpu_size, cpu_set_t *cpu_set)
{
int32_t core_count = 0;
size_t len = sizeof(core_count);
int ret = sysctlbyname(SYSCTL_CORE_COUNT, &core_count, &len, 0, 0);
if (ret) {
return -1;
}
cpu_set->count = 0;
for (int i = 0; i < core_count; i++) {
cpu_set->count |= (1 << i);
}
return 0;
}
int pthread_setaffinity_np(pthread_t thread, size_t cpu_size,
cpu_set_t *cpu_set) {
thread_port_t mach_thread;
int core = 0;
for (core = 0; core < 8 * cpu_size; core++) {
if (CPU_ISSET(core, cpu_set)) break;
}
thread_affinity_policy_data_t policy = { core };
mach_thread = pthread_mach_thread_np(thread);
thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY,
(thread_policy_t)&policy, 1);
return 0;
}
bool pinThread(int32_t aCpu) {
if (aCpu < 0) {
return false;
}
cpu_set_t lCpuSet;
CPU_ZERO(&lCpuSet);
CPU_SET(aCpu, &lCpuSet);
if (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &lCpuSet)) {
return false;
}
//return raise_thread_priority();
return true;
}
#else
#error Only MacOS supported
#endif
#elif defined _WIN64
#include <Windows.h>
bool pinThread(int32_t aCpu) {
if (aCpu > 64) {
throw std::runtime_error("Support for more than 64 CPU's under Windows is not implemented.");
}
HANDLE lThread = GetCurrentThread();
DWORD_PTR lThreadAffinityMask = 1ULL << aCpu;
DWORD_PTR lReturn = SetThreadAffinityMask(lThread, lThreadAffinityMask);
if (lReturn) {
return true;
}
return false;
}
#elif __linux
bool pinThread(int32_t aCpu) {
if (aCpu < 0) {
return false;
}
cpu_set_t lCpuSet;
CPU_ZERO(&lCpuSet);
CPU_SET(aCpu, &lCpuSet);
if (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &lCpuSet)) {
return false;
}
return true;
}
#else
#error OS not supported
#endif