Commit cf25629d1eafe17cc789b2c5ce73e5c9ef986435
1 parent
0ca790b9
more efficient locking
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@186 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
18 additions
and
14 deletions
exec-i386.c
| @@ -206,14 +206,13 @@ int cpu_x86_exec(CPUX86State *env1) | @@ -206,14 +206,13 @@ int cpu_x86_exec(CPUX86State *env1) | ||
| 206 | flags |= (1 << GEN_FLAG_VM_SHIFT); | 206 | flags |= (1 << GEN_FLAG_VM_SHIFT); |
| 207 | flags |= (3 << GEN_FLAG_CPL_SHIFT); | 207 | flags |= (3 << GEN_FLAG_CPL_SHIFT); |
| 208 | } | 208 | } |
| 209 | - flags |= (env->eflags & IOPL_MASK) >> (12 - GEN_FLAG_IOPL_SHIFT); | ||
| 210 | - flags |= (env->eflags & TF_MASK) << (GEN_FLAG_TF_SHIFT - 8); | 209 | + flags |= (env->eflags & (IOPL_MASK | TF_MASK)); |
| 211 | cs_base = env->seg_cache[R_CS].base; | 210 | cs_base = env->seg_cache[R_CS].base; |
| 212 | pc = cs_base + env->eip; | 211 | pc = cs_base + env->eip; |
| 213 | - spin_lock(&tb_lock); | ||
| 214 | tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, | 212 | tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, |
| 215 | flags); | 213 | flags); |
| 216 | if (!tb) { | 214 | if (!tb) { |
| 215 | + spin_lock(&tb_lock); | ||
| 217 | /* if no translated code available, then translate it now */ | 216 | /* if no translated code available, then translate it now */ |
| 218 | tb = tb_alloc((unsigned long)pc); | 217 | tb = tb_alloc((unsigned long)pc); |
| 219 | if (!tb) { | 218 | if (!tb) { |
| @@ -244,6 +243,7 @@ int cpu_x86_exec(CPUX86State *env1) | @@ -244,6 +243,7 @@ int cpu_x86_exec(CPUX86State *env1) | ||
| 244 | tb->hash_next = NULL; | 243 | tb->hash_next = NULL; |
| 245 | tb_link(tb); | 244 | tb_link(tb); |
| 246 | code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); | 245 | code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); |
| 246 | + spin_unlock(&tb_lock); | ||
| 247 | } | 247 | } |
| 248 | #ifdef DEBUG_EXEC | 248 | #ifdef DEBUG_EXEC |
| 249 | if (loglevel) { | 249 | if (loglevel) { |
| @@ -252,13 +252,14 @@ int cpu_x86_exec(CPUX86State *env1) | @@ -252,13 +252,14 @@ int cpu_x86_exec(CPUX86State *env1) | ||
| 252 | lookup_symbol((void *)tb->pc)); | 252 | lookup_symbol((void *)tb->pc)); |
| 253 | } | 253 | } |
| 254 | #endif | 254 | #endif |
| 255 | - | ||
| 256 | /* see if we can patch the calling TB */ | 255 | /* see if we can patch the calling TB */ |
| 257 | if (T0 != 0 && !(env->eflags & TF_MASK)) { | 256 | if (T0 != 0 && !(env->eflags & TF_MASK)) { |
| 257 | + spin_lock(&tb_lock); | ||
| 258 | tb_add_jump((TranslationBlock *)(T0 & ~3), T0 & 3, tb); | 258 | tb_add_jump((TranslationBlock *)(T0 & ~3), T0 & 3, tb); |
| 259 | + spin_unlock(&tb_lock); | ||
| 259 | } | 260 | } |
| 261 | + | ||
| 260 | tc_ptr = tb->tc_ptr; | 262 | tc_ptr = tb->tc_ptr; |
| 261 | - spin_unlock(&tb_lock); | ||
| 262 | 263 | ||
| 263 | /* execute the generated code */ | 264 | /* execute the generated code */ |
| 264 | gen_func = (void *)tc_ptr; | 265 | gen_func = (void *)tc_ptr; |
exec.h
| @@ -23,9 +23,9 @@ | @@ -23,9 +23,9 @@ | ||
| 23 | #define GEN_FLAG_SS32_SHIFT 2 | 23 | #define GEN_FLAG_SS32_SHIFT 2 |
| 24 | #define GEN_FLAG_VM_SHIFT 3 | 24 | #define GEN_FLAG_VM_SHIFT 3 |
| 25 | #define GEN_FLAG_ST_SHIFT 4 | 25 | #define GEN_FLAG_ST_SHIFT 4 |
| 26 | -#define GEN_FLAG_CPL_SHIFT 7 | ||
| 27 | -#define GEN_FLAG_IOPL_SHIFT 9 | ||
| 28 | -#define GEN_FLAG_TF_SHIFT 11 | 26 | +#define GEN_FLAG_TF_SHIFT 8 /* same position as eflags */ |
| 27 | +#define GEN_FLAG_CPL_SHIFT 9 | ||
| 28 | +#define GEN_FLAG_IOPL_SHIFT 12 /* same position as eflags */ | ||
| 29 | 29 | ||
| 30 | struct TranslationBlock; | 30 | struct TranslationBlock; |
| 31 | int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, | 31 | int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, |
| @@ -150,12 +150,15 @@ static inline void tb_set_jmp_target(TranslationBlock *tb, | @@ -150,12 +150,15 @@ static inline void tb_set_jmp_target(TranslationBlock *tb, | ||
| 150 | static inline void tb_add_jump(TranslationBlock *tb, int n, | 150 | static inline void tb_add_jump(TranslationBlock *tb, int n, |
| 151 | TranslationBlock *tb_next) | 151 | TranslationBlock *tb_next) |
| 152 | { | 152 | { |
| 153 | - /* patch the native jump address */ | ||
| 154 | - tb_set_jmp_target(tb, n, (unsigned long)tb_next->tc_ptr); | ||
| 155 | - | ||
| 156 | - /* add in TB jmp circular list */ | ||
| 157 | - tb->jmp_next[n] = tb_next->jmp_first; | ||
| 158 | - tb_next->jmp_first = (TranslationBlock *)((long)(tb) | (n)); | 153 | + /* NOTE: this test is only needed for thread safety */ |
| 154 | + if (!tb->jmp_next[n]) { | ||
| 155 | + /* patch the native jump address */ | ||
| 156 | + tb_set_jmp_target(tb, n, (unsigned long)tb_next->tc_ptr); | ||
| 157 | + | ||
| 158 | + /* add in TB jmp circular list */ | ||
| 159 | + tb->jmp_next[n] = tb_next->jmp_first; | ||
| 160 | + tb_next->jmp_first = (TranslationBlock *)((long)(tb) | (n)); | ||
| 161 | + } | ||
| 159 | } | 162 | } |
| 160 | 163 | ||
| 161 | #ifndef offsetof | 164 | #ifndef offsetof |