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 | 206 | flags |= (1 << GEN_FLAG_VM_SHIFT); |
207 | 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 | 210 | cs_base = env->seg_cache[R_CS].base; |
212 | 211 | pc = cs_base + env->eip; |
213 | - spin_lock(&tb_lock); | |
214 | 212 | tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, |
215 | 213 | flags); |
216 | 214 | if (!tb) { |
215 | + spin_lock(&tb_lock); | |
217 | 216 | /* if no translated code available, then translate it now */ |
218 | 217 | tb = tb_alloc((unsigned long)pc); |
219 | 218 | if (!tb) { |
... | ... | @@ -244,6 +243,7 @@ int cpu_x86_exec(CPUX86State *env1) |
244 | 243 | tb->hash_next = NULL; |
245 | 244 | tb_link(tb); |
246 | 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 | 248 | #ifdef DEBUG_EXEC |
249 | 249 | if (loglevel) { |
... | ... | @@ -252,13 +252,14 @@ int cpu_x86_exec(CPUX86State *env1) |
252 | 252 | lookup_symbol((void *)tb->pc)); |
253 | 253 | } |
254 | 254 | #endif |
255 | - | |
256 | 255 | /* see if we can patch the calling TB */ |
257 | 256 | if (T0 != 0 && !(env->eflags & TF_MASK)) { |
257 | + spin_lock(&tb_lock); | |
258 | 258 | tb_add_jump((TranslationBlock *)(T0 & ~3), T0 & 3, tb); |
259 | + spin_unlock(&tb_lock); | |
259 | 260 | } |
261 | + | |
260 | 262 | tc_ptr = tb->tc_ptr; |
261 | - spin_unlock(&tb_lock); | |
262 | 263 | |
263 | 264 | /* execute the generated code */ |
264 | 265 | gen_func = (void *)tc_ptr; | ... | ... |
exec.h
... | ... | @@ -23,9 +23,9 @@ |
23 | 23 | #define GEN_FLAG_SS32_SHIFT 2 |
24 | 24 | #define GEN_FLAG_VM_SHIFT 3 |
25 | 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 | 30 | struct TranslationBlock; |
31 | 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 | 150 | static inline void tb_add_jump(TranslationBlock *tb, int n, |
151 | 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 | 164 | #ifndef offsetof | ... | ... |