diff options
author | Andy McFadden <fadden@android.com> | 2010-05-28 13:31:45 -0700 |
---|---|---|
committer | Andy McFadden <fadden@android.com> | 2010-05-28 16:12:01 -0700 |
commit | fcd00ebbdf3e7f4e1e7782a65ae10fb0fc03a1aa (patch) | |
tree | 859e86f36d6bf63ee284c65fff114bbbfdeff38f /libc/bionic/semaphore.c | |
parent | 4fdbadde921ec17b4ff9e97fbd41096903b21772 (diff) | |
download | bionic-fcd00ebbdf3e7f4e1e7782a65ae10fb0fc03a1aa.zip bionic-fcd00ebbdf3e7f4e1e7782a65ae10fb0fc03a1aa.tar.gz bionic-fcd00ebbdf3e7f4e1e7782a65ae10fb0fc03a1aa.tar.bz2 |
Atomic/SMP update, part 3.
Update ARM atomic ops to use LDREX/STREX. Stripped out #if 0 chunk.
Insert explicit memory barriers in pthread and semaphore code.
For bug 2721865.
Change-Id: I0f153b797753a655702d8be41679273d1d5d6ae7
Diffstat (limited to 'libc/bionic/semaphore.c')
-rw-r--r-- | libc/bionic/semaphore.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/libc/bionic/semaphore.c b/libc/bionic/semaphore.c index 84b9314..b624943 100644 --- a/libc/bionic/semaphore.c +++ b/libc/bionic/semaphore.c @@ -30,6 +30,7 @@ #include <sys/time.h> #include <sys/atomics.h> #include <time.h> +#include <cutils/atomic-inline.h> int sem_init(sem_t *sem, int pshared, unsigned int value) { @@ -103,6 +104,7 @@ __atomic_dec_if_positive( volatile unsigned int* pvalue ) return old; } +/* lock a semaphore */ int sem_wait(sem_t *sem) { if (sem == NULL) { @@ -116,6 +118,7 @@ int sem_wait(sem_t *sem) __futex_wait(&sem->count, 0, 0); } + ANDROID_MEMBAR_FULL(); return 0; } @@ -130,8 +133,10 @@ int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout) /* POSIX says we need to try to decrement the semaphore * before checking the timeout value */ - if (__atomic_dec_if_positive(&sem->count)) + if (__atomic_dec_if_positive(&sem->count)) { + ANDROID_MEMBAR_FULL(); return 0; + } /* check it as per Posix */ if (abs_timeout == NULL || @@ -169,17 +174,21 @@ int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout) return -1; } - if (__atomic_dec_if_positive(&sem->count)) + if (__atomic_dec_if_positive(&sem->count)) { + ANDROID_MEMBAR_FULL(); break; + } } return 0; } +/* unlock a semaphore */ int sem_post(sem_t *sem) { if (sem == NULL) return EINVAL; + ANDROID_MEMBAR_FULL(); if (__atomic_inc((volatile int*)&sem->count) >= 0) __futex_wake(&sem->count, 1); @@ -194,6 +203,7 @@ int sem_trywait(sem_t *sem) } if (__atomic_dec_if_positive(&sem->count) > 0) { + ANDROID_MEMBAR_FULL(); return 0; } else { errno = EAGAIN; |