Skip to content

Commit d7d60a3

Browse files
committed
osal/none: add nested count to spin lock
Signed-off-by: HiFiPhile <[email protected]>
1 parent 1634d11 commit d7d60a3

File tree

1 file changed

+24
-3
lines changed

1 file changed

+24
-3
lines changed

src/osal/osal_none.h

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,26 +34,47 @@ extern "C" {
3434
//--------------------------------------------------------------------+
3535
// Spinlock API
3636
//--------------------------------------------------------------------+
37+
// Note: This implementation is designed for bare-metal single-core systems without RTOS.
38+
// - Supports nested locking within the same execution context
39+
// - NOT suitable for true SMP (Symmetric Multi-Processing) systems
40+
// - NOT thread-safe for multi-threaded environments
41+
// - Primarily manages interrupt enable/disable state for critical sections
3742
typedef struct {
3843
void (* interrupt_set)(bool enabled);
44+
uint32_t nested_count;
3945
} osal_spinlock_t;
4046

4147
// For SMP, spinlock must be locked by hardware, cannot just use interrupt
4248
#define OSAL_SPINLOCK_DEF(_name, _int_set) \
43-
osal_spinlock_t _name = { .interrupt_set = _int_set }
49+
osal_spinlock_t _name = { .interrupt_set = _int_set, .nested_count = 0 }
4450

4551
TU_ATTR_ALWAYS_INLINE static inline void osal_spin_init(osal_spinlock_t *ctx) {
4652
(void) ctx;
4753
}
4854

4955
TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) {
50-
if (!in_isr) {
56+
// Disable interrupts first to make nested_count increment atomic
57+
if (!in_isr && ctx->nested_count == 0) {
5158
ctx->interrupt_set(false);
5259
}
60+
ctx->nested_count++;
5361
}
5462

5563
TU_ATTR_ALWAYS_INLINE static inline void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr) {
56-
if (!in_isr) {
64+
// Check for underflow - unlock without lock
65+
if (ctx->nested_count == 0) {
66+
// Re-enable interrupts before asserting to avoid leaving interrupts disabled
67+
if (!in_isr) {
68+
ctx->interrupt_set(true);
69+
}
70+
TU_ASSERT(0,);
71+
return;
72+
}
73+
74+
ctx->nested_count--;
75+
76+
// Only re-enable interrupts when fully unlocked
77+
if (!in_isr && ctx->nested_count == 0) {
5778
ctx->interrupt_set(true);
5879
}
5980
}

0 commit comments

Comments
 (0)