Prototype implementation for self-contained objects

Sebastian Huber sebastian.huber at embedded-brains.de
Sat Jul 25 09:40:37 UTC 2015


----- Gedare Bloom <gedare at gwu.edu> schrieb:
> On Thu, Jul 23, 2015 at 8:54 AM, Sebastian Huber
> <sebastian.huber at embedded-brains.de> wrote:
> > https://lists.rtems.org/pipermail/devel/2015-July/011989.html
> >
> > Its fully functional and well tested.  It is based on the FreeBSD support:
> >
> > https://git.rtems.org/rtems-libbsd/tree/rtemsbsd/include/machine/rtems-bsd-muteximpl.h
> > https://git.rtems.org/rtems-libbsd/tree/rtemsbsd/rtems/rtems-bsd-muteximpl.c
> >
> > It is used to implement the Newlib internal locks and the libgomp (GCC OpenMP
> > support) operating system services.
> >
> > There is one issue I am not that happy about.  There are two thread queue
> > definitions:
> >
> > 1. in Newlib <sys/lock.h>
> >
> > struct _Thread_queue_Queue {
> >         struct _Thread_queue_Heads *_heads;
> >         struct _Ticket_lock_Control _Lock;
> > };
> >
> > 2. in <rtems/score/threadq.h>
> >
> > typedef struct {
> >   Thread_queue_Heads *heads;
> >
> >   /**
> >    * @brief Lock to protect this thread queue.
> >    *
> >    * It may be used to protect additional state of the object embedding this
> >    * thread queue.
> >    *
> >    * @see _Thread_queue_Acquire(), _Thread_queue_Acquire_critical() and
> >    * _Thread_queue_Release().
> >    */
> > #if defined(RTEMS_SMP)
> >   SMP_ticket_lock_Control Lock;
> > #endif
> > } Thread_queue_Queue;
> >
> The only cost to remove the conditional is an extra 8 bytes per
> Thread_queue? My intuition here is that non-SMP targets create few
> enough of these queues that the overhead is not so bad. However,
> analysis of the number of queues made in a base system would be good.

You have one Thread_queue_Queue per object which allows a thread to block.  If we use an MCS lock instead of the ticket lock, then the overhead is only 4 bytes.

> 
> > In RTEMS the lock is optional.  In Newlib the storage must be always present
> > for the lock to be independent of the actual RTEMS build configuration.  I
> > ensure with static assertions that the layout of these two structures is
> > compatible (see top of cpukit/score/src/mutex.c).  For the Newlib definition it
> > would be sufficient to provide a structure with arbitrary content.  Only the
> > alignment and size must fit (see glibc header files for objects shared by
> > user/kernel space).  For debugging purposes it is quite handy to have an
> > identical layout.  I use a cast to get the score definition, e.g.
> >
> > static Thread_queue_Queue *_Futex_Get_thread_queue(
> >   struct _Futex_Control *futex
> > )
> > {
> >   return (Thread_queue_Queue *) &futex->_Queue;
> > }
> >
> > This may, however, lead to strict aliasing problems.  I am not sure how to
> > solve this technically best.
> Probably you can make futex._Queue a union of Thread_queue_Queue and
> _Thread_queue_Queue.

The Thread_queue_Queue is not visible in Newlib. One option would be something like this

typedef union {
  struct _Thread_queue_Queue Newlib_queue;
  Thread_queue_Score_queue Score_queue;
} Thread_queue_Queue;

I think one way to avoid the strict aliasing problems is to define a seconds set of the structures defined by Newlib <sys/lock.h> in the score and simply cast to the score structure on function entry and never use the Newlib type.

-- 
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