about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2012-05-10 22:16:15 -0400
committerRich Felker <dalias@aerifal.cx>2012-05-10 22:16:15 -0400
commit47c2a22fd6adcaf3f27b093df49bd97e3fdc16e7 (patch)
tree6e2c087aacb0887f69c347ab1ec0bddcc479d48a
parent7e310e591e61cde57cf3960d6a064a1de2e94e6c (diff)
downloadmusl-47c2a22fd6adcaf3f27b093df49bd97e3fdc16e7.tar.gz
musl-47c2a22fd6adcaf3f27b093df49bd97e3fdc16e7.tar.xz
musl-47c2a22fd6adcaf3f27b093df49bd97e3fdc16e7.zip
remove __lock dependency from exit
there's no sense in using a powerful lock in exit, because it will
never be unlocked. a thread that arrives at exit while exit is already
in progress just needs to hang forever. use the pause syscall for this
because it's cheap and easy and universally available.
-rw-r--r--src/exit/exit.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/src/exit/exit.c b/src/exit/exit.c
index ae557c09..fc291484 100644
--- a/src/exit/exit.c
+++ b/src/exit/exit.c
@@ -2,6 +2,8 @@
 #include <unistd.h>
 #include <stdio.h>
 #include "libc.h"
+#include "atomic.h"
+#include "syscall.h"
 
 static void dummy()
 {
@@ -13,10 +15,10 @@ weak_alias(dummy, __fflush_on_exit);
 
 void exit(int code)
 {
-	static int lock[2];
+	static int lock;
 
 	/* If more than one thread calls exit, hang until _Exit ends it all */
-	LOCK(lock);
+	while (a_swap(&lock, 1)) __syscall(SYS_pause);
 
 	/* Only do atexit & stdio flush if they were actually used */
 	__funcs_on_exit();