Commit cf25629d1eafe17cc789b2c5ce73e5c9ef986435

Authored by bellard
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;
@@ -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