Re: pthread_mutex_unlock (was Re: sched_yield() makes OpenLDAP slow)

From: Philipp Matthias Hahn
Date: Fri Jan 27 2006 - 14:23:46 EST


Hello!

On Fri, Jan 27, 2006 at 12:08:13AM -0800, Howard Chu wrote:
> >No, not immediately, I said "for a very long time". As in: A does not
> >need the exclusion provided by the lock for a very long time so it
> >drops it to avoid needless contention, then reaquires it when it finally
> >does need the lock.
>
> OK. I think this is really a separate situation. Just to recap: A takes
> lock, does some work, releases lock, a very long time passes, then A
> takes the lock again. In the "time passes" part, that mutex could be
> locked and unlocked any number of times by other threads and A won't
> know or care. Particularly on an SMP machine, other threads that were
> blocked on that mutex could do useful work in the interim without
> impacting A's progress at all. So here, when A leaves the mutex unlocked
> for a long time, it's desirable to give the mutex to one of the waiters
> ASAP.

When you release a lock, you unblock at most one thread, which is
waiting for that lock and put that released thread in the runnable
state.
Than it's up to the scheduler, what happens next:
- if you have multiple processors, you _can_ run the released thread on
anther processor, so both thread run.
- if you are single processor or don't want to schedule the released
thread on a second cpu, you must decide to
- either _continue running the releasing thread_ and let the released
thread stay some more time in the runnable queue,
- or _preempt the releasing thread_ to the runnable queue and make the
released thread running.
If you have different priorities, your decision is easy: run the most
important thread.
But if you don't have priorities, you base your decision on other
metrics: Since it takes more time to switch a thread (save/restore
state) compared to continue running the same thread, from a throuput
perspective you'll prefer to not change threads.

Similar thinking for yield(): You put the running thread back to the
runnable queue and choose one thread from it as the new running thread.
Note, that you might choose the old thread as the new thread again,
since with SCHED_OTHER this is perfectly fine, if you decided to honor
throuput more than fairness.
Other with SCHED_FIFO/RR, since there you are forced to put the old
thread at the end of your runnable queue and choose the new one from the
front of the queue, so all other threads with the same priority will run
before you yielding thread gets the cpu again.

Summary: yield() only makes sense with a SCHED_FIFO/RR policy, because
with SCHED_OTHER you know too little about the exact policy to make any
use of it.

BYtE
Philipp
--
Dipl.-Inform. Philipp.Hahn@xxxxxxxxxxxxxxxxxxxxxxxxxxx
Abteilung Systemsoftware und verteilte Systeme, Fk. II
Carl von Ossietzky Universitaet Oldenburg, 26111 Oldenburg, Germany
http://www.svs.informatik.uni-oldenburg.de/contact/pmhahn/
Telefon: +49 441 798-2866 Telefax: +49 441 798-2756
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/