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 760 extern int64_t qemu_icount;
761 761 extern int use_icount;
762 762  
763   -#define CPU_INTERRUPT_EXIT 0x01 /* wants exit from main loop */
764 763 #define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */
765 764 #define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */
766 765 #define CPU_INTERRUPT_TIMER 0x08 /* internal timer exception pending */
... ... @@ -774,6 +773,8 @@ extern int use_icount;
774 773 void cpu_interrupt(CPUState *s, int mask);
775 774 void cpu_reset_interrupt(CPUState *env, int mask);
776 775  
  776 +void cpu_exit(CPUState *s);
  777 +
777 778 /* Breakpoint/watchpoint flags */
778 779 #define BP_MEM_READ 0x01
779 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 215 #endif
216 216 if (queue_signal(sig, &tinfo) == 1) {
217 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 523  
524 524 qemu_get_be32s(f, &env->halted);
525 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 529 tlb_flush(env, 1);
528 530  
529 531 return 0;
... ... @@ -1499,28 +1501,36 @@ void cpu_set_log_filename(const char *filename)
1499 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 1512 TranslationBlock *tb;
1507 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 1531 old_mask = env->interrupt_request;
1517 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 1534 if (use_icount) {
1525 1535 env->icount_decr.u16.high = 0xffff;
1526 1536 #ifndef CONFIG_USER_ONLY
... ... @@ -1530,16 +1540,8 @@ void cpu_interrupt(CPUState *env, int mask)
1530 1540 }
1531 1541 #endif
1532 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 1547 void cpu_reset_interrupt(CPUState *env, int mask)
... ... @@ -1547,6 +1549,12 @@ void cpu_reset_interrupt(CPUState *env, int mask)
1547 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 1558 const CPULogItem cpu_log_items[] = {
1551 1559 { CPU_LOG_TB_OUT_ASM, "out_asm",
1552 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 2012 #ifdef CONFIG_USER_ONLY
2013 2013 gdb_handlesig(s->c_cpu, 0);
2014 2014 #else
2015   - cpu_interrupt(s->c_cpu, CPU_INTERRUPT_EXIT);
  2015 + cpu_exit(s->c_cpu);
2016 2016 #endif
2017 2017 }
2018 2018  
... ...
hw/dma.c
... ... @@ -449,7 +449,7 @@ void DMA_schedule(int nchan)
449 449 {
450 450 CPUState *env = cpu_single_env;
451 451 if (env)
452   - cpu_interrupt(env, CPU_INTERRUPT_EXIT);
  452 + cpu_exit(env);
453 453 }
454 454  
455 455 static void dma_reset(void *opaque)
... ...
hw/mac_dbdma.c
... ... @@ -653,7 +653,7 @@ void DBDMA_schedule(void)
653 653 {
654 654 CPUState *env = cpu_single_env;
655 655 if (env)
656   - cpu_interrupt(env, CPU_INTERRUPT_EXIT);
  656 + cpu_exit(env);
657 657 }
658 658  
659 659 static void
... ...
linux-user/main.c
... ... @@ -200,7 +200,7 @@ static inline void start_exclusive(void)
200 200 for (other = first_cpu; other; other = other->next_cpu) {
201 201 if (other->running) {
202 202 pending_cpus++;
203   - cpu_interrupt(other, CPU_INTERRUPT_EXIT);
  203 + cpu_exit(other);
204 204 }
205 205 }
206 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 460 host_to_target_siginfo_noswap(&tinfo, info);
461 461 if (queue_signal(thread_env, sig, &tinfo) == 1) {
462 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 1181 }
1182 1182 /* Interrupt execution to force deadline recalculation. */
1183 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 1348  
1349 1349 if (env) {
1350 1350 /* stop the currently executing cpu because a timer occured */
1351   - cpu_interrupt(env, CPU_INTERRUPT_EXIT);
  1351 + cpu_exit(env);
1352 1352 #ifdef USE_KQEMU
1353 1353 if (env->kqemu_enabled) {
1354 1354 kqemu_cpu_interrupt(env);
... ... @@ -3326,7 +3326,7 @@ void qemu_service_io(void)
3326 3326 {
3327 3327 CPUState *env = cpu_single_env;
3328 3328 if (env) {
3329   - cpu_interrupt(env, CPU_INTERRUPT_EXIT);
  3329 + cpu_exit(env);
3330 3330 #ifdef USE_KQEMU
3331 3331 if (env->kqemu_enabled) {
3332 3332 kqemu_cpu_interrupt(env);
... ... @@ -3407,7 +3407,7 @@ void qemu_bh_schedule(QEMUBH *bh)
3407 3407 bh->idle = 0;
3408 3408 /* stop the currently executing CPU to execute the BH ASAP */
3409 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 3618 reset_requested = 1;
3619 3619 }
3620 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 3624 void qemu_system_shutdown_request(void)
3625 3625 {
3626 3626 shutdown_requested = 1;
3627 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 3631 void qemu_system_powerdown_request(void)
3632 3632 {
3633 3633 powerdown_requested = 1;
3634 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 3638 #ifdef _WIN32
... ...