auto import from //branches/cupcake/...@127101

This commit is contained in:
The Android Open Source Project
2009-01-20 14:03:55 -08:00
parent e5cc1f386b
commit d37527501c
7 changed files with 186 additions and 37 deletions

View File

@@ -29,6 +29,7 @@
#include <errno.h>
#include <sys/time.h>
#include <sys/atomics.h>
#include <time.h>
int sem_init(sem_t *sem, int pshared, unsigned int value)
{
@@ -118,6 +119,62 @@ int sem_wait(sem_t *sem)
return 0;
}
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout)
{
int ret;
if (sem == NULL) {
errno = EINVAL;
return -1;
}
/* POSIX says we need to try to decrement the semaphore
* before checking the timeout value */
if (__atomic_dec_if_positive(&sem->count))
return 0;
/* check it as per Posix */
if (abs_timeout == NULL ||
abs_timeout->tv_sec < 0 ||
abs_timeout->tv_nsec < 0 ||
abs_timeout->tv_nsec >= 1000000000)
{
errno = EINVAL;
return -1;
}
for (;;) {
struct timespec ts;
int ret;
/* Posix mandates CLOCK_REALTIME here */
clock_gettime( CLOCK_REALTIME, &ts );
ts.tv_sec = abs_timeout->tv_sec - ts.tv_sec;
ts.tv_nsec = abs_timeout->tv_nsec - ts.tv_nsec;
if (ts.tv_nsec < 0) {
ts.tv_nsec += 1000000000;
ts.tv_sec -= 1;
}
if (ts.tv_sec < 0 || ts.tv_nsec < 0) {
errno = ETIMEDOUT;
return -1;
}
ret = __futex_wait(&sem->count, 0, &ts);
/* return in case of timeout or interrupt */
if (ret == -ETIMEDOUT || ret == -EINTR) {
errno = -ret;
return -1;
}
if (__atomic_dec_if_positive(&sem->count))
break;
}
return 0;
}
int sem_post(sem_t *sem)
{
if (sem == NULL)