Repository navigation
[BUG] Rust: libc::PTHREAD_MUTEX_INITIALIZER is incorrect #20407
Description
Description / Steps to reproduce the issue
Rust libc initializes PTHREAD_MUTEX_INITIALIZER to 0: https://github.com/rust-lang/libc/blob/c2744242b816317ea8b5c8e306eb829c080cb2b9/src/unix/nuttx/mod.rs#L310
But in NuttX this is generally not 0.
For example, defined here: https://github.com/apache/nuttx/blob/master/include/pthread.h#L359
Going into https://github.com/apache/nuttx/blob/master/include/pthread.h#L353
Which makes use of NXSEM_NO_MHOLDER, defined here: https://github.com/apache/nuttx/blob/master/include/nuttx/semaphore.h#L70
Furthermore, the initialization also depends on the configuration.
In Rust, std makes use of the constant to init mutexes, e.g. here: https://github.com/rust-lang/rust/blob/7d2cd0fbc092625ea371da704f15f80216d2220e/library/std/src/sys/pal/unix/sync/mutex.rs#L12
I'm not sure what the best solution is, I see some options:
- remove the symbol definition from Rust (and update std to use
pthread_mutex_initinstead) - init the Rust definition to a matching value and either require a certain config or make sure the position of the non-zero values is independent from the config
- update NuttX so the definition is always 0 (in addition to requiring a specific config)
On which OS does this issue occur?
[OS: Linux], [OS: BSD], [OS: Mac], [OS: Windows]
What is the version of your OS?
Irrelevant
NuttX Version
master
Issue Architecture
[Arch: all]
Issue Area
[Area: Posix], [Area: Applications]
Host information
No response
Verification
- I have verified before submitting the report.
Activity
tgross35 commentedon Oct 1, 2026
Feel free to just submit a PR to rust's libc if our default value is wrong
bkueng commentedon Oct 2, 2026
Since there are a few options on how to proceed I was interested in your opinion.
Removing it is the simplest option. On the other hand since
PTHREAD_MUTEX_INITIALIZERis part of POSIX it would be nice to have it and would avoid having to use ifdef's on the Rust side.u7k4rs6 commentedon Oct 19, 2026
I dug into this a bit on current master to help pick a direction.
The C initializer isn't zero. It sets
mholder = NXSEM_NO_MHOLDERandflags = SEM_TYPE_MUTEX, and where those land depends on the config: offset 16 on sim:nsh (64-bit), 0 withCONFIG_PTHREAD_MUTEX_UNSAFE, and 8 on 32-bit. So a single constant on the Rust side can't be right everywhere.A zeroed mutex doesn't work either. On sim,
pthread_mutex_trylock()on a never-locked mutex that was memset to 0 returnsEBUSY, so locking it would just hang.PTHREAD_RWLOCK_INITIALIZERhas the same problem since it embeds the mutex. The cond initializer really is all zeros, so that one's fine.std::sync::Mutexisn't affected today because std always callspthread_mutex_init()after using the constant. Only code that useslibc::PTHREAD_MUTEX_INITIALIZERdirectly is hit, like statics and FFI. That also means removing it from libc would need a change in std too, since the unix mutex refers to it.I think the cleanest fix is on the NuttX side: make an all-zero
pthread_mutex_tvalid like on glibc/musl, e.g. the pthread mutex code lazily initializing one whensem.flags == 0. That touches the lock path though, so I'd like to hear what you think before sending a patch. Happy to do the libc/std side instead if you'd rather go that way.