hujun5 b7c8430de6 spinlock: fix ticket lock corruption in trylock and unlock
Two defects in the CONFIG_TICKET_SPINLOCK paths of spinlock.h:

1. spin_trylock_notrace() passed &lock->owner as the "expected" pointer
   of atomic_cmpxchg().  A failed compare-exchange writes the current
   value of the target object back through that pointer, so a losing
   trylock stores lock->next into lock->owner.  owner then equals next,
   which is the unlocked state: a lock still held by another CPU reports
   itself as free, spin_is_locked() returns false and the lock can be
   taken again.  Every later unlock keeps incrementing owner past next,
   so the ticket of a real waiter never matches and the lock stays
   locked forever.  Keep the expected value in a local variable.

2. spin_unlock() was wrapped in #ifdef __SP_UNLOCK_FUNCTION, a macro
   that is never defined anywhere in the tree.  The function body was
   therefore dead code and spin_unlock() always expanded to
   "do { *(l) = SP_UNLOCKED; } while (0)", which zeroes both ticket
   counters instead of releasing one ticket with
   atomic_fetch_add(&lock->owner, 1).  That drops queued waiters, lets a
   newcomer draw ticket 0 and enter the critical section, and also skips
   the UP_DMB/UP_DSB/UP_SEV release barriers and the
   sched_note_spinlock_unlock() note.  Drop the dead #ifdef so
   spin_unlock() is always the function.

Both were reproduced on qemu-armv7a:smp (cortex-a7 x4) with
CONFIG_TICKET_SPINLOCK=y, where the compare-exchange lowers to native
ldrex/strex.  This confirms the root cause is the C-level aliasing of
the expected pointer, not the atomic implementation.

Refs: https://github.com/apache/nuttx/issues/19808

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2026-08-18 10:21:51 +08:00
2026-08-12 16:06:03 -03:00
2026-08-16 23:23:04 +08:00

POSIX Badge License Issues Tracking Badge Contributors GitHub Build Badge Documentation Badge MemBrowse

Apache NuttX is a real-time operating system (RTOS) with an emphasis on standards compliance and small footprint. Scalable from 8-bit to 64-bit microcontroller environments, the primary governing standards in NuttX are POSIX and ANSI standards. Additional standard APIs from Unix and other common RTOSs (such as VxWorks) are adopted for functionality not available under these standards, or for functionality that is not appropriate for deeply-embedded environments (such as fork()).

For brevity, many parts of the documentation will refer to Apache NuttX as simply NuttX.

Getting Started

First time on NuttX? Read the Getting Started guide! If you don't have a board available, NuttX has its own simulator that you can run on terminal.

Documentation

You can find the current NuttX documentation on the Documentation Page.

Alternatively, you can build the documentation yourself by following the Documentation Build Instructions.

The old NuttX documentation is still available in the Apache wiki.

Supported Boards

NuttX supports a wide variety of platforms. See the full list on the Supported Platforms page.

Contributing

If you wish to contribute to the NuttX project, read the Contributing guidelines for information on Git usage, coding standard, workflow and the NuttX principles.

License

The code in this repository is under either the Apache 2 license, or a license compatible with the Apache 2 license. See the License Page for more information.

S
Description
Apache NuttX is a mature, real-time embedded operating system (RTOS)
Readme Multiple Licenses
537 MiB
Languages
C 95.1%
Linker Script 1.4%
Assembly 1.1%
CMake 1%
Makefile 0.7%
Other 0.6%