sem_post: How does the implementation work?

Adhemerval Zanella
Fri Jan 23 10:40:00 GMT 2015

The GLIBC semaphore operations has been rewritten recently to fix BZ#12674 [1],
which does not show a deadlock, but rather than a race conditional that lead
to invalid memory access.

Now all architectures (with the exception of SPARC) uses the C implementation
at nptl [2].  Now back with your question, this new version do synchronize the token 
operation using just one atomic operation (either by isem->data for 64b or 
isem->value for 32b).

So I would suggest you to check your program using an updated
GLIBC version (we are about to release 2.21 which contains this new implementation). 


On 23-01-2015 03:58, John Steele Scott wrote:
> An attempt to debug a deadlock has led me and a colleague to look at the implementation of sem_wait()/sem_post().
> Looking at sem_post.c and sem_wait.c in nptl/sysdeps/unix/sysv/linux/x86_64, what stops a race between updating nwaiters in __new_sem_wait(), and querying nwaiters in __new_sem_post()?
> It looks like it's possible for __new_sem_post() to read a zero value for nwaiters just before __new_sem_wait() increments nwaiters (just after __new_sem_wait() failed to decrement value).
> Can someone explain what stops this from happening?
> Also, (I assume) we're actually running the hand-coded x86_64 assembly implementation, which looks to work the same way as the C. What stops the race there?
> I have a bit of an understanding about how atomic operations work, but it's non-obvious how they are actually preventing a deadlock on the contended path here. It looks like we really need value and nwaiters to be considered as a single atomic value, rather than two separate atomics. How are changes to these two made atomically?
> Cheers,
> John

More information about the Libc-help mailing list