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  : [email protected]
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
_______________________________________________
rtems-devel mailing list
[email protected]
http://www.rtems.org/mailman/listinfo/rtems-devel

Reply via email to