Skip to content

Strange behavior on RP2350 with mutexes and alarms #2706

@writeonlymemory

Description

@writeonlymemory

Hello,

I have been having some trouble with some code that makes use of mutexes to protect a data structure shared between core 0 and core 1 on the RP2350 [but the code works fine on the RP2040]. SDK version is 2.2.0.

[Note: after filing this issue I noticed that I was building with -O2 -- the problem seems to go away with optimizations turned off.]

The minimal [silly] program below demonstrates the behavior. If executed on an RP2040 [or an RP2350 with PICO_USE_SW_SPIN_LOCKS=0] the program runs as I expect with "Core 1 frames" printing and climbing at a regular cadence of ~2-3/second. There's no obvious change in anything after the timer expires.

If it is run on RP2350 with PICO_USE_SW_SPIN_LOCKS=1 [the default], the program does not advance usefully until after the timer expires - maybe 1-3 "frames" lines will be output - then the timer expires and the program advances as normal at the expected cadence of output.

Removing the add_alarm_in_ms(5000, ... call makes things proceed normally [no stall on the rp2350].

Adding a second periodic timer on a short interval [say 50ms] also seems to make things work as expected [even with USE_SW_SPIN_LOCKS=1].

Thanks for any insight and sorry if I'm missing something obvious...

#include <stdio.h>

#include <pico/multicore.h>
#include <pico/stdlib.h>
#include <pico/sync.h>
#include <pico/time.h>

#define N 1000000

auto_init_mutex(lock);

static uint32_t core1_frames = 0;

void core1_entry() {
  for (;;) {
    if (!mutex_enter_timeout_ms(&lock, 500)) {
      continue;
    }
    core1_frames++;
    for (volatile int i = 0; i < N; ++i);
    mutex_exit(&lock);
    sleep_ms(10);
  }
}

int64_t do_nothing(alarm_id_t, void*) { return 0; }

void main() {
  stdio_init_all();
  sleep_ms(5000); // just wait for USB

  printf("Starting test\n");

  multicore_launch_core1(core1_entry);

  add_alarm_in_ms(5000, do_nothing, NULL, true);

  for (;;) {
    mutex_enter_blocking(&lock);
    uint32_t current = core1_frames;
    for (volatile int i = 0; i < N; ++i);
    mutex_exit(&lock);
    printf("Core 1 Frames: %u\n", current);
    sleep_ms(10);
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions