mailing list of musl libc
 help / color / mirror / code / Atom feed
* sem_getvalue conformance considerations
@ 2014-08-27  2:33 Rich Felker
  2014-08-27  7:05 ` Jens Gustedt
  0 siblings, 1 reply; 19+ messages in thread
From: Rich Felker @ 2014-08-27  2:33 UTC (permalink / raw)
  To: musl

POSIX says:

"The sem_getvalue() function shall update the location referenced by
the sval argument to have the value of the semaphore referenced by sem
without affecting the state of the semaphore. The updated value
represents an actual semaphore value that occurred at some unspecified
time during the call, but it need not be the actual value of the
semaphore when it is returned to the calling process."

musl currently implements this as:

	int val = sem->__val[0];
	*valp = val < 0 ? 0 : val;

However, I don't think this is correct. The "semaphore value" read
from __val[0] is not the formal semaphore value, but an implementation
detail: while there are waiters, after a post there is a window where
__val[0] is positive (to allow a waiter to take the semaphore) despite
the formal value never becoming positive. sem_post is documented as:

"If the semaphore value resulting from this operation is positive,
then no threads were blocked waiting for the semaphore to become
unlocked; the semaphore value is simply incremented."

"If the value of the semaphore resulting from this operation is zero,
then one of the threads blocked waiting for the semaphore shall be
allowed to return successfully from its call to sem_wait()."

So the formal "semaphore value" should always be zero while there are
more waiters than posts, even if those waiters have not yet woken to
take the semaphore.

It seems at least semi-possible to observe incorrect behavior with the
current implementation:

Example 1: Initially two waiters. One call to sem_post followed by
sem_getvalue should read a value of 0, not 1.

In principle we could compensate for this by declaring the value zero
if there are any waiters. But then:

Example 2: Initially one waiter. Two calls to sem_post followed by
sem_getvalue should read a value of 1, not 0.

What if we try to get fancy and subtract waiters from __val[0]?
Unfortunately we can't necessarily read __val[0] and waiters
(__val[1]) atomically together, so it's possible that one is outdated
by the time we read the other, such that the resulting difference is
not the correct formal semaphore value at any time during the
sem_getvalue call.

The one easy cop-out: We could claim the current behavior is
conforming anyway, since there is no way to prove that a thread is
actually blocked on a semaphore. (This is in contrast to cond vars,
where having unlocked the mutex proves they've formally become
waiters.) The state "blocked on semaphore" is fundamentally
indistinguishable from the state of "about to enter sem_wait". Thus,
we could say that, formally, there are never any waiters; sem_post
always makes the semaphore value positive, and a would-be waiter
formally arrives and decrements the semaphore value at some time after
the post makes the value positive.

Of course this is a really pathetic solution, but is there any way we
can provide real, consistent, meaningful results from sem_getvalue? Or
is the whole concept of sem_getvalue just so messed up that this is
the best possible way to handle it?

Rich


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2015-03-02 22:45 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-27  2:33 sem_getvalue conformance considerations Rich Felker
2014-08-27  7:05 ` Jens Gustedt
2014-08-27  7:43   ` Rich Felker
2014-08-27 10:43     ` Alexander Monakov
2014-08-27 13:32       ` Alexander Monakov
2014-08-27 19:06         ` Alexander Monakov
2014-08-27 21:06           ` Alexander Monakov
2014-08-28 20:47             ` Alexander Monakov
2014-08-29 22:51               ` Alexander Monakov
2014-08-30  5:12                 ` Rich Felker
2014-09-01 17:50                 ` Alexander Monakov
2015-02-27 23:21                   ` semaphore redesign Alexander Monakov
2015-02-28 15:42                     ` Rich Felker
2015-03-01 18:54                       ` Alexander Monakov
2015-03-01 17:30                     ` Szabolcs Nagy
2015-03-01 17:50                       ` Szabolcs Nagy
2015-03-02 22:40                         ` Alexander Monakov
2015-03-02 22:45                           ` Rich Felker
2015-03-01 18:24                       ` Alexander Monakov

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).