Commit 3098dba01c7daab60762b6f6624ea88c0d6cb65a

Authored by aurel32
1 parent 9e995645

Use a dedicated function to request exit from execution loop

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6762 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-all.h
@@ -760,7 +760,6 @@ extern CPUState *cpu_single_env; @@ -760,7 +760,6 @@ extern CPUState *cpu_single_env;
760 extern int64_t qemu_icount; 760 extern int64_t qemu_icount;
761 extern int use_icount; 761 extern int use_icount;
762 762
763 -#define CPU_INTERRUPT_EXIT 0x01 /* wants exit from main loop */  
764 #define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */ 763 #define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */
765 #define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */ 764 #define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */
766 #define CPU_INTERRUPT_TIMER 0x08 /* internal timer exception pending */ 765 #define CPU_INTERRUPT_TIMER 0x08 /* internal timer exception pending */
@@ -774,6 +773,8 @@ extern int use_icount; @@ -774,6 +773,8 @@ extern int use_icount;
774 void cpu_interrupt(CPUState *s, int mask); 773 void cpu_interrupt(CPUState *s, int mask);
775 void cpu_reset_interrupt(CPUState *env, int mask); 774 void cpu_reset_interrupt(CPUState *env, int mask);
776 775
  776 +void cpu_exit(CPUState *s);
  777 +
777 /* Breakpoint/watchpoint flags */ 778 /* Breakpoint/watchpoint flags */
778 #define BP_MEM_READ 0x01 779 #define BP_MEM_READ 0x01
779 #define BP_MEM_WRITE 0x02 780 #define BP_MEM_WRITE 0x02
darwin-user/signal.c
@@ -215,7 +215,7 @@ static void host_signal_handler(int host_signum, siginfo_t *info, @@ -215,7 +215,7 @@ static void host_signal_handler(int host_signum, siginfo_t *info,
215 #endif 215 #endif
216 if (queue_signal(sig, &tinfo) == 1) { 216 if (queue_signal(sig, &tinfo) == 1) {
217 /* interrupt the virtual CPU as soon as possible */ 217 /* interrupt the virtual CPU as soon as possible */
218 - cpu_interrupt(global_env, CPU_INTERRUPT_EXIT); 218 + cpu_exit(global_env);
219 } 219 }
220 } 220 }
221 221
@@ -523,7 +523,9 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id) @@ -523,7 +523,9 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id)
523 523
524 qemu_get_be32s(f, &env->halted); 524 qemu_get_be32s(f, &env->halted);
525 qemu_get_be32s(f, &env->interrupt_request); 525 qemu_get_be32s(f, &env->interrupt_request);
526 - env->interrupt_request &= ~CPU_INTERRUPT_EXIT; 526 + /* 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the
  527 + version_id is increased. */
  528 + env->interrupt_request &= ~0x01;
527 tlb_flush(env, 1); 529 tlb_flush(env, 1);
528 530
529 return 0; 531 return 0;
@@ -1499,28 +1501,36 @@ void cpu_set_log_filename(const char *filename) @@ -1499,28 +1501,36 @@ void cpu_set_log_filename(const char *filename)
1499 cpu_set_log(loglevel); 1501 cpu_set_log(loglevel);
1500 } 1502 }
1501 1503
1502 -/* mask must never be zero, except for A20 change call */  
1503 -void cpu_interrupt(CPUState *env, int mask) 1504 +static void cpu_unlink_tb(CPUState *env)
1504 { 1505 {
1505 -#if !defined(USE_NPTL) 1506 +#if defined(USE_NPTL)
  1507 + /* FIXME: TB unchaining isn't SMP safe. For now just ignore the
  1508 + problem and hope the cpu will stop of its own accord. For userspace
  1509 + emulation this often isn't actually as bad as it sounds. Often
  1510 + signals are used primarily to interrupt blocking syscalls. */
  1511 +#else
1506 TranslationBlock *tb; 1512 TranslationBlock *tb;
1507 static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED; 1513 static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED;
1508 -#endif  
1509 - int old_mask;  
1510 1514
1511 - if (mask & CPU_INTERRUPT_EXIT) {  
1512 - env->exit_request = 1;  
1513 - mask &= ~CPU_INTERRUPT_EXIT; 1515 + tb = env->current_tb;
  1516 + /* if the cpu is currently executing code, we must unlink it and
  1517 + all the potentially executing TB */
  1518 + if (tb && !testandset(&interrupt_lock)) {
  1519 + env->current_tb = NULL;
  1520 + tb_reset_jump_recursive(tb);
  1521 + resetlock(&interrupt_lock);
1514 } 1522 }
  1523 +#endif
  1524 +}
  1525 +
  1526 +/* mask must never be zero, except for A20 change call */
  1527 +void cpu_interrupt(CPUState *env, int mask)
  1528 +{
  1529 + int old_mask;
1515 1530
1516 old_mask = env->interrupt_request; 1531 old_mask = env->interrupt_request;
1517 env->interrupt_request |= mask; 1532 env->interrupt_request |= mask;
1518 -#if defined(USE_NPTL)  
1519 - /* FIXME: TB unchaining isn't SMP safe. For now just ignore the  
1520 - problem and hope the cpu will stop of its own accord. For userspace  
1521 - emulation this often isn't actually as bad as it sounds. Often  
1522 - signals are used primarily to interrupt blocking syscalls. */  
1523 -#else 1533 +
1524 if (use_icount) { 1534 if (use_icount) {
1525 env->icount_decr.u16.high = 0xffff; 1535 env->icount_decr.u16.high = 0xffff;
1526 #ifndef CONFIG_USER_ONLY 1536 #ifndef CONFIG_USER_ONLY
@@ -1530,16 +1540,8 @@ void cpu_interrupt(CPUState *env, int mask) @@ -1530,16 +1540,8 @@ void cpu_interrupt(CPUState *env, int mask)
1530 } 1540 }
1531 #endif 1541 #endif
1532 } else { 1542 } else {
1533 - tb = env->current_tb;  
1534 - /* if the cpu is currently executing code, we must unlink it and  
1535 - all the potentially executing TB */  
1536 - if (tb && !testandset(&interrupt_lock)) {  
1537 - env->current_tb = NULL;  
1538 - tb_reset_jump_recursive(tb);  
1539 - resetlock(&interrupt_lock);  
1540 - } 1543 + cpu_unlink_tb(env);
1541 } 1544 }
1542 -#endif  
1543 } 1545 }
1544 1546
1545 void cpu_reset_interrupt(CPUState *env, int mask) 1547 void cpu_reset_interrupt(CPUState *env, int mask)
@@ -1547,6 +1549,12 @@ void cpu_reset_interrupt(CPUState *env, int mask) @@ -1547,6 +1549,12 @@ void cpu_reset_interrupt(CPUState *env, int mask)
1547 env->interrupt_request &= ~mask; 1549 env->interrupt_request &= ~mask;
1548 } 1550 }
1549 1551
  1552 +void cpu_exit(CPUState *env)
  1553 +{
  1554 + env->exit_request = 1;
  1555 + cpu_unlink_tb(env);
  1556 +}
  1557 +
1550 const CPULogItem cpu_log_items[] = { 1558 const CPULogItem cpu_log_items[] = {
1551 { CPU_LOG_TB_OUT_ASM, "out_asm", 1559 { CPU_LOG_TB_OUT_ASM, "out_asm",
1552 "show generated host assembly code for each compiled TB" }, 1560 "show generated host assembly code for each compiled TB" },
gdbstub.c
@@ -2012,7 +2012,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...) @@ -2012,7 +2012,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
2012 #ifdef CONFIG_USER_ONLY 2012 #ifdef CONFIG_USER_ONLY
2013 gdb_handlesig(s->c_cpu, 0); 2013 gdb_handlesig(s->c_cpu, 0);
2014 #else 2014 #else
2015 - cpu_interrupt(s->c_cpu, CPU_INTERRUPT_EXIT); 2015 + cpu_exit(s->c_cpu);
2016 #endif 2016 #endif
2017 } 2017 }
2018 2018
hw/dma.c
@@ -449,7 +449,7 @@ void DMA_schedule(int nchan) @@ -449,7 +449,7 @@ void DMA_schedule(int nchan)
449 { 449 {
450 CPUState *env = cpu_single_env; 450 CPUState *env = cpu_single_env;
451 if (env) 451 if (env)
452 - cpu_interrupt(env, CPU_INTERRUPT_EXIT); 452 + cpu_exit(env);
453 } 453 }
454 454
455 static void dma_reset(void *opaque) 455 static void dma_reset(void *opaque)
hw/mac_dbdma.c
@@ -653,7 +653,7 @@ void DBDMA_schedule(void) @@ -653,7 +653,7 @@ void DBDMA_schedule(void)
653 { 653 {
654 CPUState *env = cpu_single_env; 654 CPUState *env = cpu_single_env;
655 if (env) 655 if (env)
656 - cpu_interrupt(env, CPU_INTERRUPT_EXIT); 656 + cpu_exit(env);
657 } 657 }
658 658
659 static void 659 static void
linux-user/main.c
@@ -200,7 +200,7 @@ static inline void start_exclusive(void) @@ -200,7 +200,7 @@ static inline void start_exclusive(void)
200 for (other = first_cpu; other; other = other->next_cpu) { 200 for (other = first_cpu; other; other = other->next_cpu) {
201 if (other->running) { 201 if (other->running) {
202 pending_cpus++; 202 pending_cpus++;
203 - cpu_interrupt(other, CPU_INTERRUPT_EXIT); 203 + cpu_exit(other);
204 } 204 }
205 } 205 }
206 if (pending_cpus > 1) { 206 if (pending_cpus > 1) {
linux-user/signal.c
@@ -460,7 +460,7 @@ static void host_signal_handler(int host_signum, siginfo_t *info, @@ -460,7 +460,7 @@ static void host_signal_handler(int host_signum, siginfo_t *info,
460 host_to_target_siginfo_noswap(&tinfo, info); 460 host_to_target_siginfo_noswap(&tinfo, info);
461 if (queue_signal(thread_env, sig, &tinfo) == 1) { 461 if (queue_signal(thread_env, sig, &tinfo) == 1) {
462 /* interrupt the virtual CPU as soon as possible */ 462 /* interrupt the virtual CPU as soon as possible */
463 - cpu_interrupt(thread_env, CPU_INTERRUPT_EXIT); 463 + cpu_exit(thread_env);
464 } 464 }
465 } 465 }
466 466
@@ -1181,7 +1181,7 @@ void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time) @@ -1181,7 +1181,7 @@ void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
1181 } 1181 }
1182 /* Interrupt execution to force deadline recalculation. */ 1182 /* Interrupt execution to force deadline recalculation. */
1183 if (use_icount && cpu_single_env) { 1183 if (use_icount && cpu_single_env) {
1184 - cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); 1184 + cpu_exit(cpu_single_env);
1185 } 1185 }
1186 } 1186 }
1187 } 1187 }
@@ -1348,7 +1348,7 @@ static void host_alarm_handler(int host_signum) @@ -1348,7 +1348,7 @@ static void host_alarm_handler(int host_signum)
1348 1348
1349 if (env) { 1349 if (env) {
1350 /* stop the currently executing cpu because a timer occured */ 1350 /* stop the currently executing cpu because a timer occured */
1351 - cpu_interrupt(env, CPU_INTERRUPT_EXIT); 1351 + cpu_exit(env);
1352 #ifdef USE_KQEMU 1352 #ifdef USE_KQEMU
1353 if (env->kqemu_enabled) { 1353 if (env->kqemu_enabled) {
1354 kqemu_cpu_interrupt(env); 1354 kqemu_cpu_interrupt(env);
@@ -3326,7 +3326,7 @@ void qemu_service_io(void) @@ -3326,7 +3326,7 @@ void qemu_service_io(void)
3326 { 3326 {
3327 CPUState *env = cpu_single_env; 3327 CPUState *env = cpu_single_env;
3328 if (env) { 3328 if (env) {
3329 - cpu_interrupt(env, CPU_INTERRUPT_EXIT); 3329 + cpu_exit(env);
3330 #ifdef USE_KQEMU 3330 #ifdef USE_KQEMU
3331 if (env->kqemu_enabled) { 3331 if (env->kqemu_enabled) {
3332 kqemu_cpu_interrupt(env); 3332 kqemu_cpu_interrupt(env);
@@ -3407,7 +3407,7 @@ void qemu_bh_schedule(QEMUBH *bh) @@ -3407,7 +3407,7 @@ void qemu_bh_schedule(QEMUBH *bh)
3407 bh->idle = 0; 3407 bh->idle = 0;
3408 /* stop the currently executing CPU to execute the BH ASAP */ 3408 /* stop the currently executing CPU to execute the BH ASAP */
3409 if (env) { 3409 if (env) {
3410 - cpu_interrupt(env, CPU_INTERRUPT_EXIT); 3410 + cpu_exit(env);
3411 } 3411 }
3412 } 3412 }
3413 3413
@@ -3618,21 +3618,21 @@ void qemu_system_reset_request(void) @@ -3618,21 +3618,21 @@ void qemu_system_reset_request(void)
3618 reset_requested = 1; 3618 reset_requested = 1;
3619 } 3619 }
3620 if (cpu_single_env) 3620 if (cpu_single_env)
3621 - cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); 3621 + cpu_exit(cpu_single_env);
3622 } 3622 }
3623 3623
3624 void qemu_system_shutdown_request(void) 3624 void qemu_system_shutdown_request(void)
3625 { 3625 {
3626 shutdown_requested = 1; 3626 shutdown_requested = 1;
3627 if (cpu_single_env) 3627 if (cpu_single_env)
3628 - cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); 3628 + cpu_exit(cpu_single_env);
3629 } 3629 }
3630 3630
3631 void qemu_system_powerdown_request(void) 3631 void qemu_system_powerdown_request(void)
3632 { 3632 {
3633 powerdown_requested = 1; 3633 powerdown_requested = 1;
3634 if (cpu_single_env) 3634 if (cpu_single_env)
3635 - cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); 3635 + cpu_exit(cpu_single_env);
3636 } 3636 }
3637 3637
3638 #ifdef _WIN32 3638 #ifdef _WIN32