sync.h
1/*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _HARDWARE_SYNC_H
8#define _HARDWARE_SYNC_H
9
10#include "pico.h"
11
12#ifndef __cplusplus
13
14#if (__STDC_VERSION__ >= 201112L)
15#include <stdatomic.h>
16#else
17enum {
18 memory_order_acquire, memory_order_release
19};
20static inline void atomic_thread_fence(uint x) {}
21#endif
22
23#else
24
25#include <atomic>
26
27#endif
28
29#ifndef PICO_SPINLOCK_ID_TIMER
30#define PICO_SPINLOCK_ID_TIMER 10
31#endif
32
33#ifndef PICO_SPINLOCK_ID_STRIPED_FIRST
34#define PICO_SPINLOCK_ID_STRIPED_FIRST 16
35#endif
36
37#ifndef PICO_SPINLOCK_ID_STRIPED_LAST
38#define PICO_SPINLOCK_ID_STRIPED_LAST 23
39#endif
40
41typedef struct _spin_lock_t spin_lock_t;
42
43inline static void __mem_fence_acquire() {
44#ifndef __cplusplus
45 atomic_thread_fence(memory_order_acquire);
46#else
47 std::atomic_thread_fence(std::memory_order_acquire);
48#endif
49}
50
51inline static void __mem_fence_release() {
52#ifndef __cplusplus
53 atomic_thread_fence(memory_order_release);
54#else
55 std::atomic_thread_fence(std::memory_order_release);
56#endif
57}
58
59#ifdef __cplusplus
60extern "C" {
61#endif
62
63void __sev();
64
65void __wev();
66
67void __wfi();
68
69void __wfe();
70
72
73void restore_interrupts(uint32_t status);
74
76
77spin_lock_t *spin_lock_instance(uint lock_num);
78
80
82
83uint32_t spin_lock_blocking(spin_lock_t *lock);
84
85bool is_spin_locked(const spin_lock_t *lock);
86
87void spin_unlock(spin_lock_t *lock, uint32_t saved_irq);
88
89uint get_core_num();
90
91spin_lock_t *spin_lock_init(uint lock_num);
92
93void clear_spin_locks(void);
94
96
97void spin_lock_claim(uint lock_num);
98void spin_lock_claim_mask(uint32_t lock_num_mask);
99void spin_lock_unclaim(uint lock_num);
100int spin_lock_claim_unused(bool required);
101uint spin_lock_num(spin_lock_t *lock);
102
103#ifdef __cplusplus
104}
105#endif
106#endif
static __force_inline uint32_t spin_lock_blocking(spin_lock_t *lock)
Acquire a spin lock safely.
Definition: sync.h:274
int spin_lock_claim_unused(bool required)
Claim a free spin lock.
Definition: sync_core0_only.c:133
static __force_inline uint32_t save_and_disable_interrupts(void)
Save and disable interrupts.
Definition: sync.h:203
void spin_lock_unclaim(uint lock_num)
Mark a spin lock as no longer used.
Definition: sync_core0_only.c:129
static __force_inline void __mem_fence_release(void)
Release a memory fence.
Definition: sync.h:186
static __force_inline void spin_unlock_unsafe(spin_lock_t *lock)
Release a spin lock without re-enabling interrupts.
Definition: sync.h:261
static __force_inline void spin_unlock(spin_lock_t *lock, uint32_t saved_irq)
Release a spin lock safely.
Definition: sync.h:302
void spin_lock_claim_mask(uint32_t lock_num_mask)
Mark multiple spin locks as used.
Definition: sync_core0_only.c:125
static __force_inline void __sev(void)
Insert a SEV instruction in to the code path.
Definition: sync.h:112
void spin_lock_claim(uint lock_num)
Mark a spin lock as used.
Definition: sync_core0_only.c:121
static __force_inline uint get_core_num(void)
Get the current core number.
Definition: sync.h:312
static __force_inline void __wfe(void)
Insert a WFE instruction in to the code path.
Definition: sync.h:122
static __force_inline void restore_interrupts(uint32_t status)
Restore interrupts to a specified state.
Definition: sync.h:215
static __force_inline spin_lock_t * spin_lock_instance(uint lock_num)
Get HW Spinlock instance from number.
Definition: sync.h:225
uint next_striped_spin_lock_num(void)
Return a spin lock number from the striped range.
Definition: sync_core0_only.c:116
static __force_inline void __mem_fence_acquire(void)
Acquire a memory fence.
Definition: sync.h:170
static __force_inline void __wfi(void)
Insert a WFI instruction in to the code path.
Definition: sync.h:131
static __force_inline void spin_lock_unsafe_blocking(spin_lock_t *lock)
Acquire a spin lock without disabling interrupts (hence unsafe)
Definition: sync.h:248
spin_lock_t * spin_lock_init(uint lock_num)
Initialise a spin lock.
Definition: sync_core0_only.c:44
static __force_inline uint spin_lock_get_num(spin_lock_t *lock)
Get HW Spinlock number from instance.
Definition: sync.h:236
static bool is_spin_locked(spin_lock_t *lock)
Check to see if a spinlock is currently acquired elsewhere.
Definition: sync.h:285
Definition: sync_core0_only.c:12