Feat: tweak and fix from last night workshop
This commit is contained in:
@@ -1,45 +1,52 @@
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
#[cfg(target_os = "linux")]
|
||||
mod memory {
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
static MLOCKALL_CALLED: AtomicBool = AtomicBool::new(false);
|
||||
static MLOCKALL_SUCCESS: AtomicBool = AtomicBool::new(false);
|
||||
static MLOCKALL_CALLED: AtomicBool = AtomicBool::new(false);
|
||||
static MLOCKALL_SUCCESS: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
/// Locks all current and future memory pages to prevent page faults during RT execution.
|
||||
/// Must be called BEFORE spawning any threads for maximum effectiveness.
|
||||
/// Returns true if mlockall succeeded, false otherwise (which is common without rtprio).
|
||||
#[cfg(unix)]
|
||||
pub fn lock_memory() -> bool {
|
||||
if MLOCKALL_CALLED.swap(true, Ordering::SeqCst) {
|
||||
return MLOCKALL_SUCCESS.load(Ordering::SeqCst);
|
||||
/// Locks all current and future memory pages to prevent page faults during RT execution.
|
||||
/// Must be called BEFORE spawning any threads for maximum effectiveness.
|
||||
pub fn lock_memory() -> bool {
|
||||
if MLOCKALL_CALLED.swap(true, Ordering::SeqCst) {
|
||||
return MLOCKALL_SUCCESS.load(Ordering::SeqCst);
|
||||
}
|
||||
|
||||
let result = unsafe { libc::mlockall(libc::MCL_CURRENT | libc::MCL_FUTURE) };
|
||||
|
||||
if result == 0 {
|
||||
MLOCKALL_SUCCESS.store(true, Ordering::SeqCst);
|
||||
true
|
||||
} else {
|
||||
let errno = std::io::Error::last_os_error();
|
||||
eprintln!("[cagire] mlockall failed: {errno}");
|
||||
eprintln!("[cagire] Memory locking disabled. For best RT performance on Linux:");
|
||||
eprintln!("[cagire] 1. Add user to 'audio' group: sudo usermod -aG audio $USER");
|
||||
eprintln!("[cagire] 2. Add to /etc/security/limits.conf:");
|
||||
eprintln!("[cagire] @audio - memlock unlimited");
|
||||
eprintln!("[cagire] 3. Log out and back in");
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
let result = unsafe { libc::mlockall(libc::MCL_CURRENT | libc::MCL_FUTURE) };
|
||||
|
||||
if result == 0 {
|
||||
MLOCKALL_SUCCESS.store(true, Ordering::SeqCst);
|
||||
true
|
||||
} else {
|
||||
// Get the actual error for better diagnostics
|
||||
let errno = std::io::Error::last_os_error();
|
||||
eprintln!("[cagire] mlockall failed: {errno}");
|
||||
eprintln!("[cagire] Memory locking disabled. For best RT performance on Linux:");
|
||||
eprintln!("[cagire] 1. Add user to 'audio' group: sudo usermod -aG audio $USER");
|
||||
eprintln!("[cagire] 2. Add to /etc/security/limits.conf:");
|
||||
eprintln!("[cagire] @audio - memlock unlimited");
|
||||
eprintln!("[cagire] 3. Log out and back in");
|
||||
false
|
||||
#[allow(dead_code)]
|
||||
pub fn is_memory_locked() -> bool {
|
||||
MLOCKALL_SUCCESS.load(Ordering::Relaxed)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
#[cfg(target_os = "linux")]
|
||||
pub use memory::{is_memory_locked, lock_memory};
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
pub fn lock_memory() -> bool {
|
||||
// Windows: VirtualLock exists but isn't typically needed for audio
|
||||
true
|
||||
}
|
||||
|
||||
/// Check if memory locking is active.
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
#[allow(dead_code)]
|
||||
pub fn is_memory_locked() -> bool {
|
||||
MLOCKALL_SUCCESS.load(Ordering::Relaxed)
|
||||
false
|
||||
}
|
||||
|
||||
/// Attempts to set realtime scheduling priority for the current thread.
|
||||
|
||||
Reference in New Issue
Block a user