sem_post: How does the implementation work?

John Steele Scott toojays@toojays.net
Fri Jan 23 06:00:00 GMT 2015


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