diff options
author | Erlang/OTP <[email protected]> | 2011-12-27 15:20:41 +0100 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2011-12-27 15:20:41 +0100 |
commit | 23a74bb235342e374b4da9eade8faf2d36fc66c2 (patch) | |
tree | a268a57acc7e3bf3df8988f5f2dd308afdcd9a9c | |
parent | a67091debf20c972dd7ce1a8379fee6673fbe571 (diff) | |
parent | 54507ec64c0b1e6b2b150c69b55eb84d08b07a15 (diff) | |
download | otp-23a74bb235342e374b4da9eade8faf2d36fc66c2.tar.gz otp-23a74bb235342e374b4da9eade8faf2d36fc66c2.tar.bz2 otp-23a74bb235342e374b4da9eade8faf2d36fc66c2.zip |
Merge branch 'rickard/lwsync/OTP-9843' into maint-r15
* rickard/lwsync/OTP-9843:
Fix lwsync instruction feature test
-rw-r--r-- | erts/lib_src/pthread/ethread.c | 49 |
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; } |