summaryrefslogtreecommitdiff
path: root/sem_getvalue.c
diff options
context:
space:
mode:
authorrpj <rpj>2004-10-19 13:24:40 +0000
committerrpj <rpj>2004-10-19 13:24:40 +0000
commit8c8bcc5d1737002a9d153105c16b262d2e201efa (patch)
treeba43c6049cc7e361a3eb875015aeb4032c01c559 /sem_getvalue.c
parent45b1b8cb2a6588f9316f780d8cefe11c181a9a17 (diff)
Semaphore speedups - alpha, but passes testsuite
Diffstat (limited to 'sem_getvalue.c')
-rw-r--r--sem_getvalue.c60
1 files changed, 6 insertions, 54 deletions
diff --git a/sem_getvalue.c b/sem_getvalue.c
index c34739a..be80bea 100644
--- a/sem_getvalue.c
+++ b/sem_getvalue.c
@@ -77,15 +77,14 @@ sem_getvalue (sem_t * sem, int *sval)
* pointed to by sem in the int pointed to by sval.
*/
{
- int result = 0;
- long value;
-
if (sem == NULL || *sem == NULL || sval == NULL)
{
- result = EINVAL;
+ errno = EINVAL;
+ return -1;
}
else
{
+ long value;
register sem_t s = *sem;
#ifdef NEED_SEM
@@ -96,59 +95,12 @@ sem_getvalue (sem_t * sem, int *sval)
#else
- /*
- * There appears to be NO atomic means of determining the
- * value of the semaphore. Using only ReleaseSemaphore()
- * with either a zero or oversized count parameter has been
- * suggested but this trick doesn't produce consistent results
- * across Windows versions (the technique uses values that are
- * knowingly illegal but hopes to extract the current value
- * anyway - the zero parameter appears to work for Win9x but
- * neither work reliably for WinNT).
- *
- * The intrusive method below will give false results
- * at times but it at least errs on the side of
- * caution. Competing threads might occasionally believe
- * the semaphore has a count of one less than it actually
- * would have and possibly block momentarily unecessarily,
- * but they will never see a higher semaphore value than
- * there should be.
- *
- *
- * Multiple threads calling sem_getvalue() at the same time
- * may not all return the same value (assuming no calls to
- * other semaphore routines). They will always return the
- * correct value or a lesser value. This problem could be fixed
- * with a global or a per-semaphore critical section here.
- *
- * An equally approximate but IMO slightly riskier approach
- * would be to keep a separate per-semaphore counter and
- * decrement/increment it inside of sem_wait() and sem_post()
- * etc using the Interlocked* functions.
- */
- if (WaitForSingleObject (s->sem, 0) == WAIT_TIMEOUT)
- {
- /* Failed - must be zero */
- value = 0;
- }
- else
- {
- /* Decremented semaphore - release it and note the value */
- (void) ReleaseSemaphore (s->sem, 1L, &value);
- value++;
- }
+ value = s->value;
#endif
- }
-
- if (result != 0)
- {
- errno = result;
- return -1;
+ *sval = value;
+ return 0;
}
- *sval = value;
- return 0;
-
} /* sem_getvalue */