aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorRickard Green <[email protected]>2011-12-23 14:36:59 +0100
committerRickard Green <[email protected]>2011-12-27 15:17:44 +0100
commit54507ec64c0b1e6b2b150c69b55eb84d08b07a15 (patch)
tree30db0ee345544a1938ebdb68aab5fb51dccdf53f /erts
parent6088c2c426d71a21874673ca6ddf93aa9e2ed4ab (diff)
downloadotp-54507ec64c0b1e6b2b150c69b55eb84d08b07a15.tar.gz
otp-54507ec64c0b1e6b2b150c69b55eb84d08b07a15.tar.bz2
otp-54507ec64c0b1e6b2b150c69b55eb84d08b07a15.zip
Fix lwsync instruction feature test
A feature test for the lwsync instruction performed on PowerPC hardware at runtime system startup got into an eternal loop if the instruction was not supported. This bug was introduced in erts-5.9/OTP-R15B.
Diffstat (limited to 'erts')
-rw-r--r--erts/lib_src/pthread/ethread.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/erts/lib_src/pthread/ethread.c b/erts/lib_src/pthread/ethread.c
index ad29249bac..fb7d135418 100644
--- a/erts/lib_src/pthread/ethread.c
+++ b/erts/lib_src/pthread/ethread.c
@@ -123,34 +123,53 @@ ethr_ts_event *ethr_get_tse__(void)
#if defined(ETHR_PPC_RUNTIME_CONF__)
-static volatile int lwsync_caused_sigill;
+#include <sys/wait.h>
static void
handle_lwsync_sigill(int signum)
{
- lwsync_caused_sigill = 1;
+ _exit(1);
}
static int
ppc_init__(void)
{
- struct sigaction act, oact;
- lwsync_caused_sigill = 0;
+ int pid;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0;
- act.sa_handler = handle_lwsync_sigill;
- if (sigaction(SIGILL, &act, &oact) != 0)
- return errno;
+ /* If anything what so ever failes we assume no lwsync for safety */
+ ethr_runtime__.conf.have_lwsync = 0;
+
+ /*
+ * We perform the lwsync test (which might cause an illegal
+ * instruction signal) in a separate process in order to be
+ * completely certain that we do not mess up our own state.
+ */
+ pid = fork();
+ if (pid == 0) {
+ struct sigaction act, oact;
- __asm__ __volatile__ ("lwsync\n\t" : : : "memory");
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_RESETHAND;
+ act.sa_handler = handle_lwsync_sigill;
+ if (sigaction(SIGILL, &act, &oact) != 0)
+ _exit(2);
- act.sa_flags = 0;
- act.sa_handler = SIG_DFL;
- if (sigaction(SIGILL, &act, &oact) != 0)
- return errno;
+ __asm__ __volatile__ ("lwsync\n\t" : : : "memory");
+
+ _exit(0);
+ }
- ethr_runtime__.conf.have_lwsync = (int) !lwsync_caused_sigill;
+ if (pid != -1) {
+ while (1) {
+ int status, res;
+ res = waitpid(pid, &status, 0);
+ if (res == pid) {
+ if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
+ ethr_runtime__.conf.have_lwsync = 1;
+ break;
+ }
+ }
+ }
return 0;
}