()
| 189 | /// Returns an error if `/proc/meminfo` cannot be read. |
| 190 | #[cfg_attr(feature = "hotpath", hotpath::measure)] |
| 191 | pub fn get_memory_usage() -> Result<String, Error> { |
| 192 | #[cfg_attr(feature = "hotpath", hotpath::measure)] |
| 193 | fn parse_memory_info() -> Result<(f64, f64), Error> { |
| 194 | let mut total_memory_kb = 0u64; |
| 195 | let mut available_memory_kb = 0u64; |
| 196 | let mut buffer = [0u8; 1024]; |
| 197 | |
| 198 | // Use fast syscall-based file reading |
| 199 | let bytes_read = read_file_fast("/proc/meminfo", &mut buffer) |
| 200 | .map_err(Error::from_raw_os_error)?; |
| 201 | let meminfo = &buffer[..bytes_read]; |
| 202 | |
| 203 | // Fast scanning for MemTotal and MemAvailable |
| 204 | let mut offset = 0; |
| 205 | let mut found_total = false; |
| 206 | let mut found_available = false; |
| 207 | |
| 208 | while offset < meminfo.len() && (!found_total || !found_available) { |
| 209 | let remaining = &meminfo[offset..]; |
| 210 | |
| 211 | // Find newline or end |
| 212 | let line_end = remaining |
| 213 | .iter() |
| 214 | .position(|&b| b == b'\n') |
| 215 | .unwrap_or(remaining.len()); |
| 216 | let line = &remaining[..line_end]; |
| 217 | |
| 218 | if line.starts_with(b"MemTotal:") { |
| 219 | // Skip "MemTotal:" and whitespace |
| 220 | let mut pos = 9; |
| 221 | while pos < line.len() && line[pos].is_ascii_whitespace() { |
| 222 | pos += 1; |
| 223 | } |
| 224 | total_memory_kb = parse_u64_fast(&line[pos..]); |
| 225 | found_total = true; |
| 226 | } else if line.starts_with(b"MemAvailable:") { |
| 227 | // Skip "MemAvailable:" and whitespace |
| 228 | let mut pos = 13; |
| 229 | while pos < line.len() && line[pos].is_ascii_whitespace() { |
| 230 | pos += 1; |
| 231 | } |
| 232 | available_memory_kb = parse_u64_fast(&line[pos..]); |
| 233 | found_available = true; |
| 234 | } |
| 235 | |
| 236 | offset += line_end + 1; |
| 237 | } |
| 238 | |
| 239 | #[allow(clippy::cast_precision_loss)] |
| 240 | let total_gb = total_memory_kb as f64 / 1024.0 / 1024.0; |
| 241 | #[allow(clippy::cast_precision_loss)] |
| 242 | let available_gb = available_memory_kb as f64 / 1024.0 / 1024.0; |
| 243 | let used_memory_gb = total_gb - available_gb; |
| 244 | |
| 245 | Ok((used_memory_gb, total_gb)) |
| 246 | } |
| 247 | |
| 248 | let (used_memory, total_memory) = parse_memory_info()?; |
no test coverage detected