]> rtime.felk.cvut.cz Git - lisovros/qemu_apohw.git/commitdiff
linux-user: enable tb unlinking when compiled with NPTL
authorRiku Voipio <riku.voipio@nokia.com>
Fri, 4 Dec 2009 13:16:30 +0000 (15:16 +0200)
committerAurelien Jarno <aurelien@aurel32.net>
Sat, 19 Dec 2009 18:45:26 +0000 (19:45 +0100)
Fixes receiving signals when guest code is being executed in a tight
loop. For an example, try interrupting the following code with ctrl-c.

http://nchipin.kos.to/test-loop.c

The tight loop is ofcourse brainless, but it is also exactly how the waitpid* testcases
are implemented.

Signed-off-by: Riku Voipio <riku.voipio@nokia.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
exec.c

diff --git a/exec.c b/exec.c
index 21a02f6c456a6822310bba27aa1ec0b55552479a..1190591e936f488d2b2e3573c2be99f07854886d 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -1530,24 +1530,22 @@ void cpu_set_log_filename(const char *filename)
 
 static void cpu_unlink_tb(CPUState *env)
 {
-#if defined(CONFIG_USE_NPTL)
     /* FIXME: TB unchaining isn't SMP safe.  For now just ignore the
        problem and hope the cpu will stop of its own accord.  For userspace
        emulation this often isn't actually as bad as it sounds.  Often
        signals are used primarily to interrupt blocking syscalls.  */
-#else
     TranslationBlock *tb;
     static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED;
 
     tb = env->current_tb;
     /* if the cpu is currently executing code, we must unlink it and
        all the potentially executing TB */
-    if (tb && !testandset(&interrupt_lock)) {
+    if (tb) {
+        spin_lock(&interrupt_lock);
         env->current_tb = NULL;
         tb_reset_jump_recursive(tb);
-        resetlock(&interrupt_lock);
+        spin_unlock(&interrupt_lock);
     }
-#endif
 }
 
 /* mask must never be zero, except for A20 change call */