@@ -132,18 +132,18 @@ impl OutOfMemoryEstimator {
132
132
}
133
133
134
134
#[ cfg( target_os = "linux" ) ]
135
- fn get_cgroup_paths < ' a > ( proc_cgroups : & ' a str ) -> Vec < & ' a str > {
135
+ fn get_cgroup_paths ( proc_cgroups : & str ) -> Option < Vec < & str > > {
136
136
let mut result = vec ! [ ] ;
137
137
for line in proc_cgroups. lines ( ) {
138
138
// TODO better error handling?
139
- let mut parts = line. splitn ( 3 , ":" ) ;
140
- let subsystems = parts. nth ( 1 ) . unwrap ( ) ;
141
- if ( subsystems == "" ) || subsystems. split ( "," ) . any ( |s| s == "memory" ) {
142
- let cgroup_path = parts. nth ( 0 ) . unwrap ( ) . strip_prefix ( "/" ) . unwrap ( ) ;
139
+ let mut parts = line. splitn ( 3 , ':' ) ;
140
+ let subsystems = parts. nth ( 1 ) ? ;
141
+ if subsystems. is_empty ( ) || subsystems. split ( ',' ) . any ( |s| s == "memory" ) {
142
+ let cgroup_path = parts. next ( ) ? . strip_prefix ( '/' ) ? ;
143
143
result. push ( cgroup_path) ;
144
144
}
145
145
}
146
- result
146
+ Some ( result)
147
147
}
148
148
149
149
/// Real system information.
@@ -156,9 +156,9 @@ pub struct RealMemoryInfo {
156
156
cgroup : Option < cgroups_rs:: Cgroup > ,
157
157
}
158
158
159
- impl RealMemoryInfo {
159
+ impl Default for RealMemoryInfo {
160
160
#[ cfg( target_os = "linux" ) ]
161
- pub fn new ( ) -> Self {
161
+ fn default ( ) -> Self {
162
162
let get_cgroup = || {
163
163
let contents = match read_to_string ( "/proc/self/cgroup" ) {
164
164
Ok ( contents) => contents,
@@ -167,14 +167,14 @@ impl RealMemoryInfo {
167
167
return None ;
168
168
}
169
169
} ;
170
- let cgroup_paths = get_cgroup_paths ( & contents) ;
171
- for path in cgroup_paths {
170
+ let cgroup_paths = get_cgroup_paths ( & contents) ? ;
171
+ if let Some ( path) = cgroup_paths. into_iter ( ) . next ( ) {
172
172
let h = cgroups_rs:: hierarchies:: auto ( ) ;
173
173
let cgroup = cgroups_rs:: Cgroup :: load ( h, path) ;
174
174
// Make sure memory_stat() works. Sometimes it doesn't
175
175
// (https://github.com/pythonspeed/filprofiler/issues/147). If
176
176
// it doesn't, this'll panic.
177
- let mem: & cgroups_rs:: memory:: MemController = cgroup. controller_of ( ) . unwrap ( ) ;
177
+ let mem: & cgroups_rs:: memory:: MemController = cgroup. controller_of ( ) ? ;
178
178
let _mem = mem. memory_stat ( ) ;
179
179
return Some ( cgroup) ;
180
180
}
@@ -190,18 +190,20 @@ impl RealMemoryInfo {
190
190
}
191
191
} ;
192
192
Self {
193
- cgroup : cgroup ,
193
+ cgroup,
194
194
process : psutil:: process:: Process :: current ( ) . ok ( ) ,
195
195
}
196
196
}
197
197
198
198
#[ cfg( target_os = "macos" ) ]
199
- pub fn new ( ) -> Self {
199
+ fn default ( ) -> Self {
200
200
Self {
201
201
process : psutil:: process:: Process :: current ( ) . ok ( ) ,
202
202
}
203
203
}
204
+ }
204
205
206
+ impl RealMemoryInfo {
205
207
#[ cfg( target_os = "linux" ) ]
206
208
pub fn get_cgroup_available_memory ( & self ) -> usize {
207
209
let mut result = std:: usize:: MAX ;
@@ -231,14 +233,18 @@ impl RealMemoryInfo {
231
233
232
234
impl MemoryInfo for RealMemoryInfo {
233
235
fn total_memory ( & self ) -> usize {
234
- psutil:: memory:: virtual_memory ( ) . unwrap ( ) . total ( ) as usize
236
+ psutil:: memory:: virtual_memory ( )
237
+ . map ( |vm| vm. total ( ) as usize )
238
+ . unwrap_or ( 0 )
235
239
}
236
240
237
241
/// Return how much free memory we have, as bytes.
238
242
fn get_available_memory ( & self ) -> usize {
239
243
// This will include memory that can become available by syncing
240
244
// filesystem buffers to disk, which is probably what we want.
241
- let available = psutil:: memory:: virtual_memory ( ) . unwrap ( ) . available ( ) as usize ;
245
+ let available = psutil:: memory:: virtual_memory ( )
246
+ . map ( |vm| vm. available ( ) as usize )
247
+ . unwrap_or ( std:: usize:: MAX ) ;
242
248
let cgroup_available = self . get_cgroup_available_memory ( ) ;
243
249
std:: cmp:: min ( available, cgroup_available)
244
250
}
@@ -261,8 +267,10 @@ impl MemoryInfo for RealMemoryInfo {
261
267
eprintln ! (
262
268
"=fil-profile= cgroup (e.g. container) memory info: {:?}" ,
263
269
if let Some ( cgroup) = & self . cgroup {
264
- let mem: & cgroups_rs:: memory:: MemController = cgroup. controller_of( ) . unwrap( ) ;
265
- Some ( mem. memory_stat( ) )
270
+ cgroup
271
+ . controller_of:: <cgroups_rs:: memory:: MemController >( )
272
+ . as_ref( )
273
+ . map( |mem| mem. memory_stat( ) )
266
274
} else {
267
275
None
268
276
}
@@ -369,7 +377,7 @@ mod tests {
369
377
proptest ! {
370
378
// Random allocations don't break invariants
371
379
#[ test]
372
- fn not_oom( allocated_sizes in prop:: collection:: vec( 1 ..1000 as usize , 10 ..2000 ) ) {
380
+ fn not_oom( allocated_sizes in prop:: collection:: vec( 1 ..1000usize , 10 ..2000 ) ) {
373
381
let ( mut estimator, memory_info) = setup_estimator( ) ;
374
382
let mut allocated = 0 ;
375
383
for size in allocated_sizes {
0 commit comments