about summary refs log tree commit diff
path: root/src/exit
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2012-04-24 16:32:23 -0400
committerRich Felker <dalias@aerifal.cx>2012-04-24 16:32:23 -0400
commit4750cf4202c29a895639b89099a7bdbe9ae422b6 (patch)
treeb682c69140ada09d2c498a80e7d84865d4c51e60 /src/exit
parente7655ed37bc9c2d79d921af4f287ee5cf2788661 (diff)
downloadmusl-4750cf4202c29a895639b89099a7bdbe9ae422b6.tar.gz
musl-4750cf4202c29a895639b89099a7bdbe9ae422b6.tar.xz
musl-4750cf4202c29a895639b89099a7bdbe9ae422b6.zip
ditch the priority inheritance locks; use malloc's version of lock
i did some testing trying to switch malloc to use the new internal
lock with priority inheritance, and my malloc contention test got
20-100 times slower. if priority inheritance futexes are this slow,
it's simply too high a price to pay for avoiding priority inversion.
maybe we can consider them somewhere down the road once the kernel
folks get their act together on this (and perferably don't link it to
glibc's inefficient lock API)...

as such, i've switch __lock to use malloc's implementation of
lightweight locks, and updated all the users of the code to use an
array with a waiter count for their locks. this should give optimal
performance in the vast majority of cases, and it's simple.

malloc is still using its own internal copy of the lock code because
it seems to yield measurably better performance with -O3 when it's
inlined (20% or more difference in the contention stress test).
Diffstat (limited to 'src/exit')
-rw-r--r--src/exit/atexit.c14
-rw-r--r--src/exit/exit.c4
2 files changed, 9 insertions, 9 deletions
diff --git a/src/exit/atexit.c b/src/exit/atexit.c
index 9d9c2fbe..1b40cb9b 100644
--- a/src/exit/atexit.c
+++ b/src/exit/atexit.c
@@ -14,22 +14,22 @@ static struct fl
 	void *a[COUNT];
 } builtin, *head;
 
-static int lock;
+static int lock[2];
 
 void __funcs_on_exit()
 {
 	int i;
 	void (*func)(void *), *arg;
-	LOCK(&lock);
+	LOCK(lock);
 	for (; head; head=head->next) {
 		for (i=COUNT-1; i>=0 && !head->f[i]; i--);
 		if (i<0) continue;
 		func = head->f[i];
 		arg = head->a[i];
 		head->f[i] = 0;
-		UNLOCK(&lock);
+		UNLOCK(lock);
 		func(arg);
-		LOCK(&lock);
+		LOCK(lock);
 	}
 }
 
@@ -41,7 +41,7 @@ int __cxa_atexit(void (*func)(void *), void *arg, void *dso)
 {
 	int i;
 
-	LOCK(&lock);
+	LOCK(lock);
 
 	/* Defer initialization of head so it can be in BSS */
 	if (!head) head = &builtin;
@@ -50,7 +50,7 @@ int __cxa_atexit(void (*func)(void *), void *arg, void *dso)
 	if (head->f[COUNT-1]) {
 		struct fl *new_fl = calloc(sizeof(struct fl), 1);
 		if (!new_fl) {
-			UNLOCK(&lock);
+			UNLOCK(lock);
 			return -1;
 		}
 		new_fl->next = head;
@@ -62,7 +62,7 @@ int __cxa_atexit(void (*func)(void *), void *arg, void *dso)
 	head->f[i] = func;
 	head->a[i] = arg;
 
-	UNLOCK(&lock);
+	UNLOCK(lock);
 	return 0;
 }
 
diff --git a/src/exit/exit.c b/src/exit/exit.c
index 1ff19dbe..ae557c09 100644
--- a/src/exit/exit.c
+++ b/src/exit/exit.c
@@ -13,10 +13,10 @@ weak_alias(dummy, __fflush_on_exit);
 
 void exit(int code)
 {
-	static int lock;
+	static int lock[2];
 
 	/* If more than one thread calls exit, hang until _Exit ends it all */
-	LOCK(&lock);
+	LOCK(lock);
 
 	/* Only do atexit & stdio flush if they were actually used */
 	__funcs_on_exit();