about summary refs log tree commit diff
path: root/src/thread/sem_timedwait.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2014-08-25 16:38:25 -0400
committerRich Felker <dalias@aerifal.cx>2014-08-25 16:38:25 -0400
commit2ff714c6138da8abb50fd532503fd8d68a18811a (patch)
treed962f59e257148b70dbfd60284738e004d5b0d02 /src/thread/sem_timedwait.c
parent8b3d7d0d35f97051bc994800c928a7db53316dd2 (diff)
downloadmusl-2ff714c6138da8abb50fd532503fd8d68a18811a.tar.gz
musl-2ff714c6138da8abb50fd532503fd8d68a18811a.tar.xz
musl-2ff714c6138da8abb50fd532503fd8d68a18811a.zip
spin in sem_[timed]wait before performing futex wait
empirically, this increases the maximum rate of wait/post operations
between two threads by 20-150 times on machines I tested, including
x86 and arm. conceptually, it makes sense to do some spinning because
semaphores are intended to be usable as a notification mechanism
between threads, not just as locks, and low-latency notification is a
valuable property to have.
Diffstat (limited to 'src/thread/sem_timedwait.c')
-rw-r--r--src/thread/sem_timedwait.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/src/thread/sem_timedwait.c b/src/thread/sem_timedwait.c
index bfcb6dcd..df5f3a6c 100644
--- a/src/thread/sem_timedwait.c
+++ b/src/thread/sem_timedwait.c
@@ -8,6 +8,11 @@ static void cleanup(void *p)
 
 int sem_timedwait(sem_t *restrict sem, const struct timespec *restrict at)
 {
+	if (!sem_trywait(sem)) return 0;
+
+	int spins = 100;
+	while (spins-- && sem->__val[0] <= 0) a_spin();
+
 	while (sem_trywait(sem)) {
 		int r;
 		a_inc(sem->__val+1);