[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
RE: [PATCH 2.5.64] Real-time futexes (priority inheritance/protection/robust support) take 4
- From: "Perez-Gonzalez, Inaky" <inaky perez-gonzalez intel com>
- To: "'phil-list redhat com'" <phil-list redhat com>,"'Ulrich Drepper (drepper redhat com)'" <drepper redhat com>
- Subject: RE: [PATCH 2.5.64] Real-time futexes (priority inheritance/protection/robust support) take 4
- Date: Mon, 24 Mar 2003 15:39:55 -0800
> -----Original Message-----
> From: Ulrich Drepper
>
> > - Does not modify original futexes - a new interface is added
>
> This is the killer.
I know, but it is the only way I found - either that or you help me convince
Rusty, that I doubt, and I understand his reasons. OTOH, you still need the
normal futexes (see below, for barriers).
Reasons for it:
* We are completely modifying the interface to access the futex
functionality, and in a way, it is a different functionality; we cannot use
counts any more, we need to use fixed values [PIDs] and atomic
compare-and-swap. This is diametrically different and some arches don't
support it (the atomic compare-and-swap, I mean).
* We cannot wake more than one waiter at a time: "correctness" && real time
wise this is calling for trouble.
Why I thus decided to go to a second interface is because we are changing so
much stuff we'd break more than one teeth and that is a no-no. And there is
no way I could find to do a decent and effective implementation using the
current interface that could provide owner identification for PI, PP,
deadlock-detection and robust support across different address spaces
without going to the kernel every time - I'd love to hear of one, though.
So it makes sense to have a separate interface, a new one, that we still
access through the sys_futex() syscall. I guess you would agree with me here
that blending this into the actual futex interface is almost impossible, not
to speak of how much stuff it would break.
> If it's not the same futex interface which is used it is not possible to
> use the non-rt version of the libpthread and the rt version on the same
> system. The whole thing is complicated by statically binaries.
Agreed - that's what one of my buddies is looking for - how to do a simple
switch, that consistently, and across different processes with redirect each
instance of a mutex to the proper futex API (unless using rtfutex for all
cuts it well enough and without any impact - falling back in compile time to
the normal futex interface for the arches that do not support atomic
compare-and-swap).
> The problem is obvious: what do you do for mutex/condvars/barriers/etc
For mutexes: two options:
1. on _init time, you determine what interface is to be used and set a bit
or setup a function pointer in the mutex structure that indicates which
interface to use for all the call redirection to be done properly (for
example, pthread_mutex_t.__data.__kind). The trick here is to get it right
so that (a) overhead is close to nil [I know, understand and agree on you
being anal about this - me too] (b) it is correctly propagated/shared. If we
are using shared memory to share the mutex, well, the other guy will see the
same bit in pthread_mutex_t [in this case is where a function pointer does
not work, cross that out] and do the proper call forwarding.
2. or use the rtfutex interface all the time on arches that support atomic
CAS instead of having to switch - falling back to the futex interface
[compile time]. This would also depend on if we can get good performance out
of the rtfutex, close to that of the futex. I think so, although I still
haven been able to measure it properly.
On condvars, I am not that sure - but to me it looks like they can use the
same mechanism as mutexes. It even makes sense to enable PI/PP/robust.
Barriers cannot use the rtfutex interface: think about it, it makes little
sense. For once, you need to wake up N waiters, not just one of them -
barriers don't care about the order, so it makes little sense to do it. In
the same motto, PI/PP does not makes sense for barriers, neither deadlock
detection or robust futex support. Asides, rtfutexes can be woken up only by
the same process that locked them.
Rwlocks: the only thing they can use is deadlock detection, maybe, and also
maybe, robust support - but not that well. How do you determine or record
the fact that two thousand readers own the lock ... well, it'd need a lot of
glue, so rwlocks can keep using the normal futex interface or internally
glue rtfutex and do their stuff manually (as it is done now, btw).
Am I missing anything ... oh, spinlocks. These guys play their own game and
do their own stuff, although it might make sense to convert them to do the
loop using rtfutex_trylock() for so many loops and then falling back to the
kernel to wait if we are too concerned about burning sooooo much CPU from
other processes.
In sum - the idea is not that rtfutex replaces the futex interface - it is
meant to live along with it, as each one has an specific use.
> actually initializes the object to do some more work and tell the kernel
> something. But if the static initializers are used not even this is
> possible. For pshared object it is possible since there is no static
> initializer to create such objects.
I think that the scenarios/methods I explained get it done - without needing
any help in the kernel or whatsoever. Let me know if I missed anything.
> If you insist on not having a unified object the only possibility is to
> have separate libpthreads. Because of the confusion this creates and
> the support nightmare I strongly oppose this but of course cannot
> prevent it from happening in a separate project.
I am known to be nuts, but not to that extent ...
Iñaky Pérez-González -- Not speaking for Intel -- all opinions are my own
(and my fault)
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]