Skip to content

thread.h: Broadcast not signal when waking lock waiters - #24652

Open
khwilliamson wants to merge 1 commit into
Perl:bleadfrom
khwilliamson:cond_broadcast
Open

thread.h: Broadcast not signal when waking lock waiters#24652
khwilliamson wants to merge 1 commit into
Perl:bleadfrom
khwilliamson:cond_broadcast

Conversation

@khwilliamson

Copy link
Copy Markdown
Contributor

Better throughput is possible, when a lock is released, by waking all threads waiting for it, instead of just one thread. The POSIX Standard says this.

  • This set of changes does not require a perldelta entry.

@Leont

Leont commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Better throughput is possible, when a lock is released, by waking all threads waiting for it, instead of just one thread.

I would find that counter-intuitive for PERL_READ_UNLOCK, though I see the point for PERL_WRITE_UNLOCK

The POSIX Standard says this.

Only when one expects to unblock multiple threads.

But also: we should probably use pthread_rwlock_t instead of reinventing this wheel. That's probably a much better approach.

Better throughput is possible, when a lock is released, by waking all
threads waiting for it, instead of just one thread.  The POSIX Standard
says this.
@khwilliamson

Copy link
Copy Markdown
Contributor Author

I would find that counter-intuitive for PERL_READ_UNLOCK

There are situations where it is better to signal one thread, and ones where it is better to broadcast. We don't know in any given situation which it would be. I think libc could be in a better position to know, but perhaps the cost of record keeping would out weigh any payoff.

So is it better to always throttle down the cases where it would be better to do the broadcast, or is it better to be optimistic with the potential negative consekuence of some extra bits of work?

I'm thinking it's better to be optimistic that even if there is extra work now, future advances in libc implementations would tilt it the other way in more cases.

One case where the read unlocking doing a broadcast would be better could be when you have a bunch of readers waiting for the release of a write lock. Many libc calls want a constant environment during their execution, so this is a fairly common case when somebody is changing it. That thread releases and broadcasts. Only one of those is going to get to execute to lock it again, but very briefly. It might be that this all takes place before any of the other threads are even scheduled, so the original broadcast stands. But if not, should the reader unlocking the mutex do a broadcast or a signal? Based on your comment, I've changed it to just a signal, but I don't know.

As far as using pthread_rwlock_t, I investigated that when I originally put this in some years ago. I remember having concerns about getting it to work on non-POSIX platforms (assuming the POSIX ones actually implement it to spec), but also this crucial bit:

The calling thread may deadlock if at the time the call is made it holds a write lock.

Our code would need to be significantly restructured to not run afoul of that. (And I see no valid reason why an implementation would not to easily be able to handle this case properly. I've seen that too many times, where the implementation takes the easy way out; and anyone who needs to get it to work reliably is forced to compensate, so the cost to society is higher than if the implementation had DTRT)

The opposite direction, of holding a read-lock and trying to convert it to write could easily cause deadlock.

(A long time ago, I could not type the letter that comes between p and r into text boxes on my browser. Somehow that went away; maybe I found a way around it, maybe it got fixed. But it has just come back, and so I used a 'k' instead above)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants