1
Fork 0
mirror of https://github.com/RGBCube/superfreq synced 2025-07-27 17:07:44 +00:00

daemon: cross-platform safe arithmetic

This commit is contained in:
NotAShelf 2025-05-17 05:39:01 +03:00
parent 59602b0e3e
commit 139746069a
No known key found for this signature in database
GPG key ID: 29D95B64378DB4BF

View file

@ -68,27 +68,17 @@ fn compute_new(params: &IntervalParams) -> u64 {
// Apply a multiplier based on battery discharge rate // Apply a multiplier based on battery discharge rate
if let Some(discharge_rate) = params.battery_discharge_rate { if let Some(discharge_rate) = params.battery_discharge_rate {
if discharge_rate > 20.0 { if discharge_rate > 20.0 {
// High discharge rate - increase polling interval significantly // High discharge rate - increase polling interval significantly (3x)
let multiplied = adjusted_interval as f64 * 3.0; adjusted_interval = adjusted_interval.saturating_mul(3);
adjusted_interval = if multiplied >= u64::MAX as f64 {
u64::MAX
} else {
multiplied.round() as u64
};
} else if discharge_rate > 10.0 { } else if discharge_rate > 10.0 {
// Moderate discharge - double polling interval // Moderate discharge - double polling interval (2x)
adjusted_interval = adjusted_interval.saturating_mul(2); adjusted_interval = adjusted_interval.saturating_mul(2);
} else { } else {
// Low discharge rate - increase by 50% // Low discharge rate - increase by 50% (multiply by 3/2)
let multiplied = adjusted_interval as f64 * 1.5; adjusted_interval = adjusted_interval.saturating_mul(3).saturating_div(2);
adjusted_interval = if multiplied >= u64::MAX as f64 {
u64::MAX
} else {
multiplied.round() as u64
};
} }
} else { } else {
// If we don't know discharge rate, use a conservative multiplier // If we don't know discharge rate, use a conservative multiplier (2x)
adjusted_interval = adjusted_interval.saturating_mul(2); adjusted_interval = adjusted_interval.saturating_mul(2);
} }
} }
@ -108,22 +98,22 @@ fn compute_new(params: &IntervalParams) -> u64 {
idle_factor idle_factor
); );
let multiplied = adjusted_interval as f64 * f64::from(idle_factor); // Convert f32 multiplier to integer-safe math
adjusted_interval = if multiplied >= u64::MAX as f64 { // Multiply by a large number first, then divide to maintain precision
u64::MAX // Use 1000 as the scaling factor to preserve up to 3 decimal places
} else { let scaling_factor = 1000;
multiplied.round() as u64 let scaled_factor = (idle_factor * scaling_factor as f32) as u64;
}; adjusted_interval = adjusted_interval
.saturating_mul(scaled_factor)
.saturating_div(scaling_factor);
} }
// If idle_time_seconds is 0, no factor is applied by this block // If idle_time_seconds is 0, no factor is applied by this block
} }
// Adjust for CPU/temperature volatility // Adjust for CPU/temperature volatility
if params.cpu_volatility > 10.0 || params.temp_volatility > 2.0 { if params.cpu_volatility > 10.0 || params.temp_volatility > 2.0 {
// XXX: This operation reduces the interval, so overflow is not an issue. // For division by 2 (halving the interval), we can safely use integer division
// Using f64 for precision in multiplication before rounding. adjusted_interval = (adjusted_interval / 2).max(1);
// Max with 1 to prevent zero interval before final clamp.
adjusted_interval = ((adjusted_interval as f64 * 0.5).round() as u64).max(1);
} }
// Ensure interval stays within configured bounds // Ensure interval stays within configured bounds