pthread_once() and rtems_gxx_once()
Sebastian Huber
sebastian.huber at embedded-brains.de
Thu Jul 4 14:18:17 UTC 2013
Hello,
both functions disable currently the preemption to ensure mutual exclusion.
This doesn't work on SMP. This makes also pthread_once() not POSIX conform.
Here we have
http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_once.html
"On return from pthread_once(), it is guaranteed that init_routine() has
completed."
This is not true if the init_routine() blocks on a resource access. I assume
that GCC needs also this guarantee.
To address this issue we have to protect the section with a mutex. So it could
look like this:
int pthread_once(
pthread_once_t *once_control,
void ( *init_routine )( void )
)
{
int eno = 0;
if ( once_control->is_initialized ) {
if ( !once_control->init_executed ) {
_RTEMS_Lock_allocator();
if ( !once_control->init_executed ) {
once_control->init_executed = true;
( *init_routine )();
}
_RTEMS_Unlock_allocator();
}
} else {
eno = EINVAL;
}
return eno;
}
We can also introduce a new API mutex for this, but I don't think this is
necessary.
This implementation has a severe defect. Asynchronous cancellation, restart,
suspend or deletion inside the critical section leads to a permanently locked
mutex. This leads to the next problem. The cancellation support is also in
the POSIX API (e.g. pthread_setcanceltype). I think we have to move this also
to the Classic API (there is a bug in this area
https://www.rtems.org/bugzilla/show_bug.cgi?id=2035). This leads to the next
problem. To use this we may need cleanup handlers (e.g.
pthread_cleanup_push/pop). The current pthread_cleanup_push() implementation
is broken. It uses workspace allocation with a silent failure.
As documented here
http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cleanup_push.html
the cleanup handling can be implemented with data structures on the stack
(instead of the workspace).
I see the following steps to fix the pthread_once() and rtems_gxx_once()
implementation.
1. Change the cleanup handler implementation to use data structures on the
stack (Newlib owned header file, use <sys/queue.h> for lists instead of RTEMS
chains) and move the cleanup support to the Score (available now in all APIs).
2. Implement the once functions with a mutex.
--
Sebastian Huber, embedded brains GmbH
Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone : +49 89 189 47 41-16
Fax : +49 89 189 47 41-09
E-Mail : sebastian.huber at embedded-brains.de
PGP : Public key available on request.
Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
More information about the devel
mailing list