about summary refs log tree commit diff
path: root/src/exit
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 /src/exit
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.
Diffstat (limited to 'src/exit')
-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();