Index | Thread | Search

From:
Mark Kettenis <mark.kettenis@xs4all.nl>
Subject:
Re: rpki-client: pthreads first unlock then signal
To:
Job Snijders <job@openbsd.org>
Cc:
tech@openbsd.org
Date:
Tue, 24 Jun 2025 11:11:11 +0200

Download raw body.

Thread
> Date: Mon, 23 Jun 2025 22:34:08 +0000
> From: Job Snijders <job@openbsd.org>
> 
> On Tue, Jun 24, 2025 at 12:25:06AM +0200, Mark Kettenis wrote:
> > > Date: Mon, 23 Jun 2025 22:13:51 +0000
> > > From: Job Snijders <job@openbsd.org>
> > > 
> > > While this is not fixing a bug, intuition and literature suggest that
> > > unlocking mutexes before signaling might help prevent the
> > > freshly-woken-up thread from humping against the lock.
> > 
> > Where did you find this questionable advice?
> 
> I quote from The Linux Programming Interface, chapter 30.2 "Signaling
> Changes of State: Condition Variables" (page 647)
> 
> 	""" [Butenhof, 1996] points out that, on some implemenations,
> 	unlocking the mutex and then signaling the condition variable
> 	may yield better performance than performing these steps in the
> 	reverse sequence. If the mutex is unlocked only after the
> 	condition variable is signaled, the thread performing
> 	pthread_cond_wait() may wake up while the mutex is still locked.
> 	This results in two superfluous context switches. Some
> 	implementations eliminate this problem by employing a technique
> 	called "wait morphing", which moves the signaled thread from the
> 	condition variable wait queue to the mutex wait queue without
> 	performing a context switch if the mutex is locked."""

That reference is a bit dated, but Butenhof probably did know what he
was talking about.  I suspect we don't do any "wait morphing" in our
implementation.

> Is there a reason to signal and then unlock?

POSIX says this:

  The pthread_cond_broadcast() or pthread_cond_signal() functions may
  be called by a thread whether or not it currently owns the mutex
  that threads calling pthread_cond_clockwait(),
  pthread_cond_timedwait(), or pthread_cond_wait() have associated
  with the condition variable during their waits; however, if
  predictable scheduling behavior is required, then that mutex shall
  be locked by the thread calling pthread_cond_broadcast() or
  pthread_cond_signal().

Which I have always interpreted as a strong hint to release the mutex
*after* the pthread_cond_signal() call.  So I'd stick to that pattern
unless you can prove doing it the other way results in a measurable
speedup.

> If that is the case, shouldn't the calls around line 1268
> parser.c:proc_parser() be be reversed?

Yes.