@@ -46,44 +46,82 @@ mod sched_linux_like {
46
46
47
47
pub type CloneCb < ' a > = Box < dyn FnMut ( ) -> isize + ' a > ;
48
48
49
+ /// CpuSet represent a bit-mask of CPUs.
50
+ /// CpuSets are used by sched_setaffinity and
51
+ /// sched_getaffinity for example.
52
+ ///
53
+ /// This is a wrapper around `libc::cpu_set_t`.
49
54
#[ repr( C ) ]
50
55
#[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
51
56
pub struct CpuSet {
52
57
cpu_set : libc:: cpu_set_t ,
53
58
}
54
59
55
60
impl CpuSet {
61
+ /// Create a new and empty CpuSet.
56
62
pub fn new ( ) -> CpuSet {
57
63
CpuSet {
58
64
cpu_set : unsafe { mem:: zeroed ( ) } ,
59
65
}
60
66
}
61
67
68
+ /// Test to see if a CPU is in the CpuSet.
69
+ /// `field` is the CPU id to test
62
70
pub fn is_set ( & self , field : usize ) -> Result < bool > {
63
- if field >= 8 * mem :: size_of :: < libc :: cpu_set_t > ( ) {
71
+ if field >= CpuSet :: count ( ) {
64
72
Err ( Error :: Sys ( Errno :: EINVAL ) )
65
73
} else {
66
74
Ok ( unsafe { libc:: CPU_ISSET ( field, & self . cpu_set ) } )
67
75
}
68
76
}
69
77
78
+ /// Add a CPU to CpuSet.
79
+ /// `field` is the CPU id to add
70
80
pub fn set ( & mut self , field : usize ) -> Result < ( ) > {
71
- if field >= 8 * mem :: size_of :: < libc :: cpu_set_t > ( ) {
81
+ if field >= CpuSet :: count ( ) {
72
82
Err ( Error :: Sys ( Errno :: EINVAL ) )
73
83
} else {
74
84
Ok ( unsafe { libc:: CPU_SET ( field, & mut self . cpu_set ) } )
75
85
}
76
86
}
77
87
88
+ /// Remove a CPU from CpuSet.
89
+ /// `field` is the CPU id to remove
78
90
pub fn unset ( & mut self , field : usize ) -> Result < ( ) > {
79
- if field >= 8 * mem :: size_of :: < libc :: cpu_set_t > ( ) {
91
+ if field >= CpuSet :: count ( ) {
80
92
Err ( Error :: Sys ( Errno :: EINVAL ) )
81
93
} else {
82
94
Ok ( unsafe { libc:: CPU_CLR ( field, & mut self . cpu_set ) } )
83
95
}
84
96
}
97
+
98
+ /// Return the maximum number of CPU in CpuSet
99
+ pub fn count ( ) -> usize {
100
+ 8 * mem:: size_of :: < libc:: cpu_set_t > ( )
101
+ }
85
102
}
86
103
104
+ /// `sched_setaffinity` set a thread's CPU affinity mask
105
+ /// ([`sched_setaffinity(2)`](http://man7.org/linux/man-pages/man2/sched_setaffinity.2.html))
106
+ ///
107
+ /// `pid` is the thread ID to update.
108
+ /// If pid is zero, then the calling thread is updated.
109
+ ///
110
+ /// The `cpuset` argument specifies the set of CPUs on which the thread
111
+ /// will be eligible to run.
112
+ ///
113
+ /// # Example
114
+ ///
115
+ /// Binding the current thread to CPU 0 can be done as follows:
116
+ ///
117
+ /// ```rust,no_run
118
+ /// use nix::sched::{CpuSet, sched_setaffinity};
119
+ /// use nix::unistd::Pid;
120
+ ///
121
+ /// let mut cpu_set = CpuSet::new();
122
+ /// cpu_set.set(0);
123
+ /// sched_setaffinity(Pid::from_raw(0), &cpu_set);
124
+ /// ```
87
125
pub fn sched_setaffinity ( pid : Pid , cpuset : & CpuSet ) -> Result < ( ) > {
88
126
let res = unsafe {
89
127
libc:: sched_setaffinity (
@@ -96,6 +134,41 @@ mod sched_linux_like {
96
134
Errno :: result ( res) . map ( drop)
97
135
}
98
136
137
+ /// `sched_getaffinity` get a thread's CPU affinity mask
138
+ /// ([`sched_getaffinity(2)`](http://man7.org/linux/man-pages/man2/sched_getaffinity.2.html))
139
+ ///
140
+ /// `pid` is the thread ID to check.
141
+ /// If pid is zero, then the calling thread is checked.
142
+ ///
143
+ /// Returned `cpuset` is the set of CPUs on which the thread
144
+ /// is eligible to run.
145
+ ///
146
+ /// # Example
147
+ ///
148
+ /// Checking if the current thread can run on CPU 0 can be done as follows:
149
+ ///
150
+ /// ```rust,no_run
151
+ /// use nix::sched::sched_getaffinity;
152
+ /// use nix::unistd::Pid;
153
+ ///
154
+ /// let cpu_set = sched_getaffinity(Pid::from_raw(0)).unwrap();
155
+ /// if cpu_set.is_set(0).unwrap() {
156
+ /// println!("Current thread can run on CPU 0");
157
+ /// }
158
+ /// ```
159
+ pub fn sched_getaffinity ( pid : Pid ) -> Result < CpuSet > {
160
+ let mut cpuset = CpuSet :: new ( ) ;
161
+ let res = unsafe {
162
+ libc:: sched_getaffinity (
163
+ pid. into ( ) ,
164
+ mem:: size_of :: < CpuSet > ( ) as libc:: size_t ,
165
+ & mut cpuset. cpu_set ,
166
+ )
167
+ } ;
168
+
169
+ Errno :: result ( res) . and ( Ok ( cpuset) )
170
+ }
171
+
99
172
pub fn clone (
100
173
mut cb : CloneCb ,
101
174
stack : & mut [ u8 ] ,
0 commit comments