-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand file tree
/
Copy pathworker_interface.cpp
More file actions
73 lines (59 loc) · 2.19 KB
/
worker_interface.cpp
File metadata and controls
73 lines (59 loc) · 2.19 KB
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
// This program demonstrates how to change the worker behavior
// upon the creation of an executor.
#include <taskflow/taskflow.hpp>
// ----------------------------------------------------------------------------
// Affinity
// ----------------------------------------------------------------------------
#if defined(__linux__)
#include <sched.h>
#include <pthread.h>
#elif defined(_WIN32)
#include <windows.h>
#elif defined(__APPLE__)
#include <mach/mach.h>
#include <mach/thread_policy.h>
#endif
// affine the given thread to a specific core
bool affine(std::thread& thread, size_t core_id) {
#if defined(__linux__)
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(core_id, &cpuset);
pthread_t native_handle = thread.native_handle();
return pthread_setaffinity_np(native_handle, sizeof(cpu_set_t), &cpuset) == 0;
#elif defined(_WIN32)
return SetThreadAffinityMask(thread.native_handle(), 1ULL << core_id) != 0;
#elif defined(__APPLE__)
thread_port_t native_handle = pthread_mach_thread_np(thread.native_handle());
thread_affinity_policy_data_t policy = {static_cast<integer_t>(core_id)};
return thread_policy_set(
native_handle, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1
) == KERN_SUCCESS;
#else
// Unsupported platform
return false;
#endif
}
// ----------------------------------------------------------------------------
class CustomWorkerBehavior : public tf::WorkerInterface {
public:
// to call before the worker enters the scheduling loop
void scheduler_prologue(tf::Worker& w) override {
printf("worker %zu prepares to enter the work-stealing loop\n", w.id());
// now affine the worker to a particular CPU core equal to its id
if(affine(w.thread(), w.id())) {
printf("successfully affines worker %zu to CPU core %zu\n", w.id(), w.id());
}
else {
printf("failed to affine worker %zu to CPU core %zu\n", w.id(), w.id());
}
}
// to call after the worker leaves the scheduling loop
void scheduler_epilogue(tf::Worker& w, std::exception_ptr) override {
printf("worker %zu left the work-stealing loop\n", w.id());
}
};
int main() {
tf::Executor executor(4, tf::make_worker_interface<CustomWorkerBehavior>());
return 0;
}