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

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