{"record":{"id":"c94a9519de84564c","repo":"embassy-rs/embassy","slug":"blocking-at-sleeplevel-would-overflow","errorCode":null,"errorMessage":"Blocking at SleepLevel {:?} would overflow","messagePattern":"Blocking at SleepLevel (.+?) would overflow","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-mspm0/src/low_power/mod.rs","lineNumber":85,"sourceCode":"    mspm0g151x,\n    mspm0g351x,\n    mspm0g518x,\n    mspm0c110x,\n    mspm0c1105_c1106,\n    mspm0h321x\n)))]\ncompile_error!(\"the `low-power` feature is not implemented for this chip family\");\n\npub use crate::sysctl::SleepLevel;\n\nstatic SLEEP_BLOCKS: [AtomicU8; 5] = [const { AtomicU8::new(0) }; 5];\n\n/// Block sleep at `level` and every deeper mode. Paired with [`unblock`] by\n/// [`WakeGuard`](crate::sysctl::WakeGuard).\npub(crate) fn block(level: SleepLevel) {\n    trace!(\"Blocking sleep at level {:?}\", level);\n    if SLEEP_BLOCKS[level as usize].fetch_add(1, Ordering::Relaxed) == (u8::MAX - 1) {\n        panic!(\"Blocking at SleepLevel {:?} would overflow\", level)\n    };\n}\n\n/// Remove a block previously added at `level`.\npub(crate) fn unblock(level: SleepLevel) {\n    trace!(\"Unblocking sleep at level {:?}\", level);\n    SLEEP_BLOCKS[level as usize].fetch_sub(1, Ordering::Relaxed);\n}\n\n/// Deepest mode currently permitted, or `None` if all deep sleep is blocked.\nfn deepest_allowed() -> Option<SleepLevel> {\n    for (i, blocks) in SLEEP_BLOCKS.iter().enumerate() {\n        if blocks.load(Ordering::Relaxed) > 0 {\n            return i.checked_sub(1).map(|j| SleepLevel::LEVELS[j]);\n        }\n    }\n    Some(SleepLevel::Standby1)\n}","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-mspm0/src/low_power/mod.rs#L67-L103","documentation":"Each SleepLevel has a saturating u8 counter (SLEEP_BLOCKS) of active WakeGuards; block() detects that another increment would hit u8::MAX and overflow the count, which would corrupt the sleep-blocking bookkeeping. This is a driver-internal guard against ~255 outstanding WakeGuards at one level, effectively indicating a WakeGuard leak.","triggerScenarios":"Thrown at embassy-mspm0/src/low_power/mod.rs:85 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Drop WakeGuards when done rather than keeping them alive; each guard increments the counter and its Drop decrements it.","Audit code that std::mem::forget's or leaks a WakeGuard.","If >255 simultaneously-live guards at one sleep level is legitimate, raise the counter type from u8."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}