Skip to main content

av_denoise_core/
stack.rs

1use std::ffi::OsStr;
2
3/// Stack bytes the kernel codegen thread needs.
4pub const CODEGEN_STACK_BYTES: usize = 16 << 20;
5
6/// Raises `RUST_MIN_STACK` to [`CODEGEN_STACK_BYTES`] when it is unset.
7///
8/// No-op if the variable is already set.
9///
10/// # Safety
11///
12/// The same safety rules as [std::env::set_var] applies.
13pub unsafe fn raise_codegen_stack_limit() {
14    if std::env::var_os("RUST_MIN_STACK").is_none() {
15        // SAFETY: forwarded from this function's own precondition.
16        unsafe { std::env::set_var("RUST_MIN_STACK", CODEGEN_STACK_BYTES.to_string()) };
17    }
18}
19
20/// Whether the process's `RUST_MIN_STACK` is large enough for codegen.
21pub fn codegen_stack_is_sufficient() -> bool {
22    limit_is_sufficient(std::env::var_os("RUST_MIN_STACK").as_deref())
23}
24
25/// Parses a raw `RUST_MIN_STACK` value and checks it against [`CODEGEN_STACK_BYTES`].
26///
27/// Unset is insufficient. A value that fails to parse is also insufficient.
28fn limit_is_sufficient(raw: Option<&OsStr>) -> bool {
29    raw.and_then(|v| v.to_str())
30        .and_then(|v| v.parse::<usize>().ok())
31        .is_some_and(|bytes| bytes >= CODEGEN_STACK_BYTES)
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37
38    #[test]
39    fn unset_is_insufficient() {
40        assert!(!limit_is_sufficient(None));
41    }
42
43    #[test]
44    fn zero_is_insufficient() {
45        assert!(!limit_is_sufficient(Some(OsStr::new("0"))));
46    }
47
48    #[test]
49    fn one_below_the_limit_is_insufficient() {
50        let value = (CODEGEN_STACK_BYTES - 1).to_string();
51        assert!(!limit_is_sufficient(Some(OsStr::new(&value))));
52    }
53
54    #[test]
55    fn exactly_the_limit_is_sufficient() {
56        let value = CODEGEN_STACK_BYTES.to_string();
57        assert!(limit_is_sufficient(Some(OsStr::new(&value))));
58    }
59
60    #[test]
61    fn above_the_limit_is_sufficient() {
62        let value = (CODEGEN_STACK_BYTES * 2).to_string();
63        assert!(limit_is_sufficient(Some(OsStr::new(&value))));
64    }
65
66    #[test]
67    fn surrounding_whitespace_is_insufficient() {
68        let value = format!("  {CODEGEN_STACK_BYTES}  ");
69        assert!(!limit_is_sufficient(Some(OsStr::new(&value))));
70    }
71
72    #[test]
73    fn non_numeric_is_insufficient() {
74        assert!(!limit_is_sufficient(Some(OsStr::new("not-a-number"))));
75    }
76}