-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sys/pal/unix/sync/mutex: Fix Mutex::new() on NuttX #138400
base: master
Are you sure you want to change the base?
Conversation
PTHREAD_MUTEX_INITIALIZER is highly configurable on NuttX, making it difficult to use a hardcoded initializer from libc crate in Rust way. Instead, call pthread_mutex_init() to initialize the mutex with default attributes, ensuring consistent behavior with PTHREAD_MUTEX_INITIALIZER. * Added conditional compilation for NuttX target * Replaced PTHREAD_MUTEX_INITIALIZER with pthread_mutex_init() for NuttX * Ensured consistent mutex initialization behavior across platforms
rustbot has assigned @workingjubilee. Use |
let mut mutex = Mutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) }; | ||
|
||
unsafe { | ||
libc::pthread_mutex_init(mutex.raw(), core::ptr::null()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NuttX allows moving a mutex after calling pthread_mutex_init
? POSIX makes that UB as the mutex could eg be self-referential.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, in this aspect, the situation is somewhat different. When initializing a mutex, NuttX only sets the flags:
int pthread_mutex_init(FAR pthread_mutex_t *mutex,
FAR const pthread_mutexattr_t *attr)
{
int status;
sinfo("mutex=%p attr=%p\n", mutex, attr);
if (!mutex)
{
return EINVAL;
}
/* Initialize the mutex like a semaphore with initial count = 1 */
status = mutex_init(&mutex->mutex);
if (status < 0)
{
return -status;
}
/* Were attributes specified? If so, use them */
#ifdef CONFIG_PTHREAD_MUTEX_TYPES
mutex->type = attr ? attr->type : PTHREAD_MUTEX_DEFAULT;
#endif
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
mutex->flink = NULL;
# ifdef CONFIG_PTHREAD_MUTEX_BOTH
mutex->flags = attr && attr->robust == PTHREAD_MUTEX_ROBUST ?
_PTHREAD_MFLAGS_ROBUST : 0;
# else
mutex->flags = 0;
# endif
#endif
#if defined(CONFIG_PRIORITY_INHERITANCE) || defined(CONFIG_PRIORITY_PROTECT)
if (attr)
{
status = mutex_set_protocol(&mutex->mutex, attr->proto);
if (status < 0)
{
mutex_destroy(&mutex->mutex);
return -status;
}
# ifdef CONFIG_PRIORITY_PROTECT
if (attr->proto == PTHREAD_PRIO_PROTECT)
{
status = mutex_setprioceiling(&mutex->mutex, attr->ceiling, NULL);
if (status < 0)
{
mutex_destroy(&mutex->mutex);
return -status;
}
}
# endif
}
#endif
return 0;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a documented guarantee or does NuttX reserve the right to change the implementation in such a way that this becomes UB?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately I can't find such a document, I think I can add it to the test cases on the relevant side and incorporate it into the NuttX side to remind developers and prevent accidental changes to this behavior.
PTHREAD_MUTEX_INITIALIZER is highly configurable on NuttX, making it difficult to use a hardcoded initializer from libc crate in Rust way.
Instead, call pthread_mutex_init() to initialize the mutex with default attributes, ensuring consistent behavior with PTHREAD_MUTEX_INITIALIZER.