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 |