File port_rp2040_multicore.c¶
File List > port > rp2040 > port_rp2040_multicore.c
Go to the documentation of this file
#if __has_include("syn_config.h")
#include "syn_config.h"
#endif
#if defined(PICO_BOARD) && !defined(ARDUINO) && defined(SYN_USE_MULTICORE) && SYN_USE_MULTICORE
#include "hardware/sync.h"
#include "pico/multicore.h"
#include "syntropic/common/syn_barrier.h"
#include "syntropic/common/syn_defs.h"
#include "syntropic/port/syn_port_spinlock.h"
/* ── Per-lock saved interrupt state ────────────────────────────────────── */
static uint32_t s_saved_irq[SYN_SPINLOCK_COUNT];
/* ── Initialization (lazy, called on first acquire) ────────────────────── */
static bool s_spinlocks_initialized = false;
/*
* Maps SYN spinlock ID (0..SYN_SPINLOCK_COUNT-1) to actual hardware
* lock number, dynamically allocated to avoid conflicts with the
* Pico SDK's own claims.
*/
static uint s_hw_lock_num[SYN_SPINLOCK_COUNT];
static void __attribute__((constructor)) ensure_spinlocks_init(void)
{
if (!s_spinlocks_initialized) {
for (uint8_t i = 0; i < SYN_SPINLOCK_COUNT; i++) {
int hw = spin_lock_claim_unused(true);
s_hw_lock_num[i] = (uint)hw;
spin_lock_init((uint)hw);
}
s_spinlocks_initialized = true;
}
}
/* ── Memory barrier ────────────────────────────────────────────────────── */
void syn_port_memory_barrier(void)
{
__dmb();
}
/* ── Spinlock port ─────────────────────────────────────────────────────── */
void syn_port_spinlock_acquire(uint8_t id)
{
if (id >= SYN_SPINLOCK_COUNT)
return;
ensure_spinlocks_init();
spin_lock_t *lock = spin_lock_instance(s_hw_lock_num[id]);
s_saved_irq[id] = spin_lock_blocking(lock);
}
void syn_port_spinlock_release(uint8_t id)
{
if (id >= SYN_SPINLOCK_COUNT)
return;
spin_lock_t *lock = spin_lock_instance(s_hw_lock_num[id]);
spin_unlock(lock, s_saved_irq[id]);
}
bool syn_port_spinlock_try_acquire(uint8_t id)
{
if (id >= SYN_SPINLOCK_COUNT)
return false;
ensure_spinlocks_init();
spin_lock_t *lock = spin_lock_instance(s_hw_lock_num[id]);
if (is_spin_locked(lock))
return false;
uint32_t save = save_and_disable_interrupts();
bool acquired = spin_try_lock_unsafe(lock);
if (acquired) {
s_saved_irq[id] = save;
} else {
restore_interrupts(save);
}
return acquired;
}
/* ── Core identity ─────────────────────────────────────────────────────── */
uint8_t syn_port_core_id(void)
{
return (uint8_t)get_core_num();
}
/* ── Inter-core notification ───────────────────────────────────────────── */
void syn_port_ipc_notify(void)
{
__sev();
}
#endif /* PICO_BOARD && !ARDUINO && SYN_USE_MULTICORE */