On 17/07/15 14:36, Torvald Riegel wrote:
On Fri, 2015-07-17 at 13:33 +0200, Sebastian Huber wrote:
>On 17/07/15 13:26, Jakub Jelinek wrote:
> >On Fri, Jul 17, 2015 at 01:17:32PM +0200, Sebastian Huber wrote:
> >> >On 17/07/15 08:40, Sebastian Huber wrote:
> >>> > >Hello,
> >>> > >
> >>> > >the libgomp configuration for RTEMS uses currently the POSIX
> >>> > >implementation. Unfortunately the performance is unacceptable bad, so I
> >>> > >work currently on a specialized RTEMS configuration. I would like to 
reuse
> >>> > >the code of the Linux futex barrier. On RTEMS there is no kernel/user
> >>> > >space separation. In order to make the futex management simpler, I 
would
> >>> > >like to optionally embed a futex object in the barrier. Would a change
> >>> > >like this be acceptable?
> >> >
> >> >Attached is a more complete example.
> >I'd prefer not to share the two implementations, just copy and adjust
> >the linux/bar.[ch] into rtems/bar.[ch].
>
>Ok, I understand that you want to separate support for a niche system
>from the mainline Linux, but then I have to deal with all the problems
>involved with copy and paste of source code, e.g. RTEMS would not
>automatically profit from bug fixes and improvements of the Linux futex
>barrier.
I agree with Jakub.  If your OS implements blocking differently than
Linux futexes, you are probably better off with a barrier implementation
whose blocking is designed for your OS' blocking mechanism.

Ok, I already changed the patch and don't touch the Linux code any more.


How does your blocking mechanism work, roughly?  Is _Futex_Control a
wake queue associated with the uaddr, basically?

Yes, exactly. It is very simple:

struct _Futex_Control {
    struct _Thread_queue_Queue _Queue;
};

int _Futex_Wait( struct _Futex_Control *futex, int *uaddr, int val )
{
  ISR_lock_Context  lock_context;
  Thread_Control   *executing;
  int               eno;

  executing = _Futex_Queue_acquire( futex, &lock_context );

  if ( *uaddr == val ) {
    _Thread_queue_Enqueue_critical(
      _Futex_Get_thread_queue( futex ),
      FUTEX_TQ_OPERATIONS,
      executing,
      STATES_WAITING_FOR_MUTEX,
      0,
      0,
      &lock_context
    );
    eno = 0;
  } else {
    _Futex_Queue_release( futex, &lock_context );
    eno = EWOULDBLOCK;
  }

  return eno;
}

Perhaps something
along Java's park/unpark could be more natural for your OS.  Or you
could even simplify the barrier implementation if you can check
arbitrary conditions, not just equality of a value and the futex word.

Its certainly possible to optimize it, but using the Linux futex barrier was very easy, yields acceptable results and I don't have to reverse engineer the expected behaviour. I don't have an unlimited budget for this work and have to focus on the hot spots. My next step is to change the thread pool management of libgomp so that it better fits to the partitioned/clustered schedulers we have in RTEMS.

--
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.hu...@embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.

Reply via email to