Clearing the event flag before calling __wfe() in sleep_until? #3052

Closed
opened 2026-07-01 07:54:14 -05:00 by antoineomond · 2 comments
antoineomond commented 2026-07-01 07:54:14 -05:00 (Migrated from github.com)

Environment

  • RP2350 (Pico 2)
  • pico-sdk version: 2.2.0 (current master branch)

Problem summary
By default, it looks like the sleep_until function doesn't go into wfe, and does a busy wait instead. The sleep_until function calls __wfe() using the lock_internal_spin_unlock_with_wait macro:

uint64_t t_us = to_us_since_boot(t);
uint64_t t_before_us = t_us - PICO_TIME_SLEEP_OVERHEAD_ADJUST_US;
// needs to work in the first PICO_TIME_SLEEP_OVERHEAD_ADJUST_US of boot
if (t_before_us > t_us) t_before_us = 0;
absolute_time_t t_before;
update_us_since_boot(&t_before, t_before_us);
if (absolute_time_diff_us(get_absolute_time(), t_before) > 0) {
    if (add_alarm_at(t_before, sleep_until_callback, NULL, false) >= 0) {
        // able to add alarm for just before the time
        while (!time_reached(t_before)) {
            uint32_t save = spin_lock_blocking(sleep_notifier.spin_lock);
            lock_internal_spin_unlock_with_wait(&sleep_notifier, save); // This translates into spin_unlock((&sleep_notifier)->spin_lock, save), __wfe()
        }
    }
}

Apparently, when using the software implementation of the spinlock (PICO_USE_SW_SPIN_LOCKS set to 1), the spin_lock_block function implementation sets the event flag (#1812). This means that, because __wfe() is called only once after the spin_block_blocking call, the __wfe() call always returns immediately.

Question
Would it make sense to clear the event flag in the macro before the __wfe call? Like redefined the macro from:
#define lock_internal_spin_unlock_with_wait(lock, save) spin_unlock((lock)->spin_lock, save), __wfe()
to:
#define lock_internal_spin_unlock_with_wait(lock, save) spin_unlock((lock)->spin_lock, save), __sev(), __wfe(), __wfe()
?
Using that, it looks like the board goes into wfe even when using software spin lock (the default).

**Environment** - RP2350 (Pico 2) - pico-sdk version: 2.2.0 (current master branch) **Problem summary** By default, it looks like the `sleep_until` function doesn't go into wfe, and does a busy wait instead. The `sleep_until` function calls `__wfe()` using the `lock_internal_spin_unlock_with_wait` macro: ```c uint64_t t_us = to_us_since_boot(t); uint64_t t_before_us = t_us - PICO_TIME_SLEEP_OVERHEAD_ADJUST_US; // needs to work in the first PICO_TIME_SLEEP_OVERHEAD_ADJUST_US of boot if (t_before_us > t_us) t_before_us = 0; absolute_time_t t_before; update_us_since_boot(&t_before, t_before_us); if (absolute_time_diff_us(get_absolute_time(), t_before) > 0) { if (add_alarm_at(t_before, sleep_until_callback, NULL, false) >= 0) { // able to add alarm for just before the time while (!time_reached(t_before)) { uint32_t save = spin_lock_blocking(sleep_notifier.spin_lock); lock_internal_spin_unlock_with_wait(&sleep_notifier, save); // This translates into spin_unlock((&sleep_notifier)->spin_lock, save), __wfe() } } } ``` Apparently, when using the software implementation of the spinlock (PICO_USE_SW_SPIN_LOCKS set to 1), the `spin_lock_block` function implementation sets the event flag ([#1812](https://github.com/raspberrypi/pico-sdk/issues/1812)). This means that, because `__wfe()` is called only once after the `spin_block_blocking` call, the `__wfe()` call always returns immediately. **Question** Would it make sense to clear the event flag in the macro before the __wfe call? Like redefined the macro from: `#define lock_internal_spin_unlock_with_wait(lock, save) spin_unlock((lock)->spin_lock, save), __wfe()` to: `#define lock_internal_spin_unlock_with_wait(lock, save) spin_unlock((lock)->spin_lock, save), __sev(), __wfe(), __wfe()` ? Using that, it looks like the board goes into wfe even when using software spin lock (the default).
lurch commented 2026-07-01 08:16:46 -05:00 (Migrated from github.com)

current master branch

Could you re-test with the current develop branch please? There have been a number of recent fixes to this 🙂

> current master branch Could you re-test with the current `develop` branch please? There have been a number of recent fixes to this 🙂
kilograham commented 2026-07-01 13:06:08 -05:00 (Migrated from github.com)

should be fixed in develop branch

should be fixed in develop branch
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-raspberrypi/pico-sdk#3052
No description provided.