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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
//! Thread affinity and priority control for the CURRENT thread.
//!
//! [`pin_thread_to_core`] / [`set_thread_affinity`] set hard CPU affinity
//! (Linux, Windows; macOS returns [`crate::Error::Unsupported`] - Apple
//! Silicon ignores affinity, QoS via [`set_thread_priority`] is the only
//! placement tool there). [`set_thread_priority`] maps the 7 portable
//! [`ThreadPriority`] levels onto each OS scheduler.
use crate::;
/// Pins the current thread to a single logical core (OS LP id).
///
/// Convenience over [`set_thread_affinity`] with a one-bit mask. Logical core
/// IDs are the OS's own ids - get them from
/// [`crate::CpuInfo::logical_processor_ids()`] or the mask helpers
/// ([`crate::CpuInfo::performance_core_mask()`] etc.).
///
/// # Examples
///
/// ```
/// use gdt_cpus::{CpuInfo, pin_thread_to_core};
///
/// if let Ok(info) = CpuInfo::detect() {
/// if let Some(&first) = info.logical_processor_ids().first() {
/// if let Err(e) = pin_thread_to_core(first) {
/// eprintln!("pin failed: {}", e);
/// }
/// }
/// }
/// ```
/// Sets the current thread's hard CPU affinity to `mask` (OS LP ids).
///
/// Linux: `sched_setaffinity`. Windows: `SetThreadGroupAffinity` - a thread's
/// hard affinity is single-group by OS design, so masks spanning multiple
/// 64-LP processor groups return [`crate::Error::InvalidParameter`].
/// macOS and other platforms: [`crate::Error::Unsupported`].
/// Reads the current thread's hard CPU affinity as an [`AffinityMask`].
///
/// Linux: `sched_getaffinity`. Windows: the thread's `GROUP_AFFINITY` (a
/// thread's hard affinity is single-group by OS design, so the mask carries
/// bits from one 64-LP processor group). macOS and other platforms:
/// [`crate::Error::Unsupported`] (Apple Silicon ignores affinity).
///
/// Pairs with [`set_thread_affinity`] for save/restore - read the current mask,
/// pin to a subset, then restore.
///
/// # Examples
///
/// ```
/// # #[cfg(any(target_os = "linux", target_os = "windows"))]
/// # {
/// use gdt_cpus::current_affinity;
///
/// if let Ok(mask) = current_affinity() {
/// println!("running on {} logical processors", mask.count());
/// }
/// # }
/// ```
/// Sets the current thread's SOFT affinity to `mask` (OS LP ids) - Windows only.
///
/// Soft affinity (the CPU Sets API, `SetThreadSelectedCpuSets`) tells the
/// scheduler to PREFER the given LPs while still allowing migration under
/// contention - the mode Intel's game guidance recommends over hard masks
/// (it cooperates with Thread Director and core parking instead of fighting
/// them), and the only cross-processor-group placement tool. Returns
/// [`crate::Error::Unsupported`] on every other platform.
/// Sets the current thread's priority.
///
/// Mapping per OS (full tables on [`ThreadPriority`] and in the platform
/// modules): Linux - pure timeshare nice 19/10/5/0/-5/-10/-20; denied
/// negative values cascade to rtkit (feature `rtkit`, on by default) and
/// finally to nice 0 - real-time is the separate opt-in
/// [`crate::promote_thread_to_realtime`]. macOS - QoS classes for every
/// level except `TimeCritical`, which is `SCHED_RR` 47 (a permanent QoS
/// opt-out). Windows - `THREAD_PRIORITY_IDLE..TIME_CRITICAL`.
///
/// Returns an [`AppliedPriority`] describing what the request actually
/// produced - on Linux a "success" can mean the level was granted directly,
/// brokered through rtkit, or silently degraded to `Normal`. Branch on
/// [`AppliedPriority::degraded`] / [`crate::Grant`], or `Display` it for the
/// platform mechanism string.
///
/// # Examples
///
/// ```
/// use gdt_cpus::{ThreadPriority, set_thread_priority};
///
/// match set_thread_priority(ThreadPriority::Highest) {
/// Ok(applied) if applied.degraded() => {
/// eprintln!("priority silently weakened: {}", applied);
/// }
/// Ok(applied) => println!("priority set: {}", applied),
/// Err(e) => eprintln!("priority change failed: {}", e),
/// }
/// ```