diff options
author | Rickard Green <[email protected]> | 2011-12-30 15:21:24 +0100 |
---|---|---|
committer | Rickard Green <[email protected]> | 2011-12-30 15:21:24 +0100 |
commit | 34dca57472ba2f4e82bb03d3713e3318613093bb (patch) | |
tree | 9dfc465ec5f64edd5c2304117228ba834b43dcae /erts/lib_src | |
parent | 8769a849dbbb70cb92733f484b2a0e1693e97eb7 (diff) | |
parent | c6d37ba58c505ead46a3e939b3d38236dbd20aa5 (diff) | |
download | otp-34dca57472ba2f4e82bb03d3713e3318613093bb.tar.gz otp-34dca57472ba2f4e82bb03d3713e3318613093bb.tar.bz2 otp-34dca57472ba2f4e82bb03d3713e3318613093bb.zip |
Merge branch 'maint-r15' into maint
Conflicts:
erts/vsn.mk
Diffstat (limited to 'erts/lib_src')
-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; } |