@@ -3,10 +3,13 @@ use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
3
3
4
4
use crate :: MemoryStats ;
5
5
6
+ #[ cfg( not( feature = "always_use_statm" ) ) ]
6
7
const SMAPS : & str = "/proc/self/smaps" ;
7
8
const STATM : & str = "/proc/self/statm" ;
8
9
10
+ #[ cfg( not( feature = "always_use_statm" ) ) ]
9
11
static SMAPS_CHECKED : AtomicBool = AtomicBool :: new ( false ) ;
12
+ #[ cfg( not( feature = "always_use_statm" ) ) ]
10
13
static SMAPS_EXIST : AtomicBool = AtomicBool :: new ( false ) ;
11
14
static PAGE_SIZE : AtomicUsize = AtomicUsize :: new ( 0 ) ;
12
15
@@ -16,25 +19,24 @@ pub fn memory_stats() -> Option<MemoryStats> {
16
19
// kernels. We use the inaccurate /proc/self/statm stats
17
20
// as a fallback in case smaps isn't avaliable.
18
21
22
+ #[ cfg( feature = "always_use_statm" ) ]
23
+ load_page_size ( ) ?;
24
+
25
+ #[ cfg( not( feature = "always_use_statm" ) ) ]
19
26
if let Ok ( false ) = SMAPS_CHECKED . compare_exchange ( false , true , Ordering :: Relaxed , Ordering :: Relaxed ) {
20
27
let smaps_exist = fs:: metadata ( SMAPS ) . is_ok ( ) ;
21
28
22
- if !smaps_exist && PAGE_SIZE . load ( Ordering :: Relaxed ) == 0 {
23
- let page_size = unsafe { libc:: sysconf ( libc:: _SC_PAGESIZE) } ;
24
- if page_size == -1 {
25
- // sysconf returned error
26
- return None ;
27
- } else {
28
- PAGE_SIZE . store ( page_size as usize , Ordering :: Relaxed ) ;
29
- }
29
+ if !smaps_exist {
30
+ load_page_size ( ) ?;
30
31
}
31
32
32
33
// store SMAPS_EXIST last to prevent code from loading a PAGE_SIZE of 0
33
34
SMAPS_EXIST . store ( smaps_exist, Ordering :: Relaxed ) ;
34
35
}
35
36
37
+ #[ cfg( not( feature = "always_use_statm" ) ) ]
36
38
if SMAPS_EXIST . load ( Ordering :: Relaxed ) {
37
- match fs:: read_to_string ( SMAPS ) {
39
+ return match fs:: read_to_string ( SMAPS ) {
38
40
Ok ( smap_info) => {
39
41
// smaps returns a list of different areas of memory
40
42
// and the sizes of each, in kB. smaps_rollup doesn't
@@ -60,25 +62,39 @@ pub fn memory_stats() -> Option<MemoryStats> {
60
62
} )
61
63
}
62
64
Err ( _) => None ,
65
+ } ;
66
+ }
67
+
68
+ match fs:: read_to_string ( STATM ) {
69
+ Ok ( statm_info) => {
70
+ // statm returns the virtual size and rss, in
71
+ // multiples of the page size, as the first
72
+ // two columns of output.
73
+
74
+ let page_size = PAGE_SIZE . load ( Ordering :: Relaxed ) ;
75
+ let ( total_size_pages, idx) = scan_int ( & statm_info) ;
76
+ let ( total_rss_pages, _) = scan_int ( & statm_info[ idx..] ) ;
77
+ Some ( MemoryStats {
78
+ physical_mem : total_rss_pages * page_size,
79
+ virtual_mem : total_size_pages * page_size,
80
+ } )
63
81
}
64
- } else {
65
- match fs:: read_to_string ( STATM ) {
66
- Ok ( statm_info) => {
67
- // statm returns the virtual size and rss, in
68
- // multiples of the page size, as the first
69
- // two columns of output.
70
-
71
- let page_size = PAGE_SIZE . load ( Ordering :: Relaxed ) ;
72
- let ( total_size_pages, idx) = scan_int ( & statm_info) ;
73
- let ( total_rss_pages, _) = scan_int ( & statm_info[ idx..] ) ;
74
- Some ( MemoryStats {
75
- physical_mem : total_rss_pages * page_size,
76
- virtual_mem : total_size_pages * page_size,
77
- } )
78
- }
79
- Err ( _) => None ,
82
+ Err ( _) => None ,
83
+ }
84
+ }
85
+
86
+ /// Grabs the value of the SC_PAGESIZE if needed.
87
+ fn load_page_size ( ) -> Option < ( ) > {
88
+ if PAGE_SIZE . load ( Ordering :: Relaxed ) == 0 {
89
+ let page_size = unsafe { libc:: sysconf ( libc:: _SC_PAGESIZE) } ;
90
+ if page_size == -1 {
91
+ // sysconf returned error
92
+ return None ;
93
+ } else {
94
+ PAGE_SIZE . store ( page_size as usize , Ordering :: Relaxed ) ;
80
95
}
81
96
}
97
+ Some ( ( ) )
82
98
}
83
99
84
100
/// Extracts a positive integer from a string that
@@ -94,7 +110,7 @@ fn scan_int(string: &str) -> (usize, usize) {
94
110
}
95
111
for n in chars {
96
112
idx += 1 ;
97
- if ( '0' ..= '9' ) . contains ( & n ) {
113
+ if n . is_ascii_digit ( ) {
98
114
out *= 10 ;
99
115
out += n as usize - '0' as usize ;
100
116
} else {
0 commit comments