diff options
author | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-06-07 20:50:51 +0000 |
---|---|---|
committer | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-06-07 20:50:51 +0000 |
commit | d597536303d762c4209cbab7e379819b8eb14536 (patch) | |
tree | 3330934421d15c1d5d1f95e18fe9bc36da7cc6cd /exec.c | |
parent | 0a878c4760718e1604e2cfe423252729716110ad (diff) |
Multithreaded locking fixes.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4692 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'exec.c')
-rw-r--r-- | exec.c | 13 |
1 files changed, 11 insertions, 2 deletions
@@ -1341,10 +1341,20 @@ void cpu_set_log_filename(const char *filename) /* mask must never be zero, except for A20 change call */ void cpu_interrupt(CPUState *env, int mask) { +#if !defined(USE_NPTL) TranslationBlock *tb; static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED; +#endif + /* FIXME: This is probably not threadsafe. A different thread could + be in the mittle of a read-modify-write operation. */ env->interrupt_request |= mask; +#if defined(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 /* if the cpu is currently executing code, we must unlink it and all the potentially executing TB */ tb = env->current_tb; @@ -1353,6 +1363,7 @@ void cpu_interrupt(CPUState *env, int mask) tb_reset_jump_recursive(tb); resetlock(&interrupt_lock); } +#endif } void cpu_reset_interrupt(CPUState *env, int mask) @@ -2015,7 +2026,6 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) end = TARGET_PAGE_ALIGN(end); if (flags & PAGE_WRITE) flags |= PAGE_WRITE_ORG; - spin_lock(&tb_lock); for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) { p = page_find_alloc(addr >> TARGET_PAGE_BITS); /* if the write protection is set, then we invalidate the code @@ -2027,7 +2037,6 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) } p->flags = flags; } - spin_unlock(&tb_lock); } int page_check_range(target_ulong start, target_ulong len, int flags) |