[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: Poor condvar performance



Ulrich Drepper wrote:
> Jamie Lokier wrote:
> > Why do you need to remember the mutex address in each process, if it's
> > in shared memory?  Is it because the requeue operation would have to
> > move a waiter from a shared memory futex to a process-local memory futex?
> 
> There need not be any relationship at all between the addresses of the
> condvar and mutex in the different processes.

Ah, I see now.  Bothered to read the documentation of cond_wait() :)

> Any functionality which requires a pshared mode of operation must _not_
> use pointers.  We might be able to do something with physical addresses
> but I doubt the kernel people want to export that kind of knowledge.

Hmm.  We don't use physical addresses any more in the kernel; that was
the point of the recent rewrite :)

The "key" of a futex is now either (mm,virtual address) or
(file,offset) depending on whether it's private or shared memory.

You can't refer to a (mm,vaddr) pair in _another_ process in
futex_requeue, so it's impossible to requeue a pshared condvar waiter
onto its private mutex.

Here's an idea:

pshared condvars would need to keep a list or hash of all distinct
mutexes which any cond_wait() waiters are using.  Distinct as in
unique (pid,mutex_addr) pairs.  (The pid is not needed for pshared mutexes;
then you'd use (inode,offset) instead).  A reference count with each
entry is fine.

cond_wait() would add its mutex argument to that list,
or increment the count if the mutex is already there.  Then it would
wait on the _entry_ address: futex_wait2(entry_addr, mutex_addr, ...).

cond_signal() would run through the list, calling
futex_requeue2(entry_addr, 1, infinity) for each entry.

And we'd add two new primitives:

    futex_wait2 - takes a second address argument, which is converted
                  to a key.  If this waiter is _requeued_ using
                  futex_requeue2 it will requeue to this second address key.

    futex_requeue2 - like futex_requeue, but doesn't take a second address.
                     Any waiters that are requeued will be to the address
                     they specified in futex_wait2.

This isn't a great interface because you can't requeue2 to move a
waiter a second time.  But it is fine for pshared condvars, I think.

(I did think of some other primitives, but the above two are the ones
that seem like they could be implemented easily).

-- Jamie




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]