more efficient locking
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 25 May 2003 19:20:31 +0000 (19:20 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 25 May 2003 19:20:31 +0000 (19:20 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@186 c046a42c-6fe2-441c-8c8c-71466251a162

exec-i386.c
exec.h

index 978b1da..68e0371 100644 (file)
@@ -206,14 +206,13 @@ int cpu_x86_exec(CPUX86State *env1)
                 flags |= (1 << GEN_FLAG_VM_SHIFT);
                 flags |= (3 << GEN_FLAG_CPL_SHIFT);
             }
-            flags |= (env->eflags & IOPL_MASK) >> (12 - GEN_FLAG_IOPL_SHIFT);
-            flags |= (env->eflags & TF_MASK) << (GEN_FLAG_TF_SHIFT - 8);
+            flags |= (env->eflags & (IOPL_MASK | TF_MASK));
             cs_base = env->seg_cache[R_CS].base;
             pc = cs_base + env->eip;
-            spin_lock(&tb_lock);
             tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, 
                          flags);
             if (!tb) {
+                spin_lock(&tb_lock);
                 /* if no translated code available, then translate it now */
                 tb = tb_alloc((unsigned long)pc);
                 if (!tb) {
@@ -244,6 +243,7 @@ int cpu_x86_exec(CPUX86State *env1)
                 tb->hash_next = NULL;
                 tb_link(tb);
                 code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
+                spin_unlock(&tb_lock);
             }
 #ifdef DEBUG_EXEC
            if (loglevel) {
@@ -252,13 +252,14 @@ int cpu_x86_exec(CPUX86State *env1)
                        lookup_symbol((void *)tb->pc));
            }
 #endif
-
             /* see if we can patch the calling TB */
             if (T0 != 0 && !(env->eflags & TF_MASK)) {
+                spin_lock(&tb_lock);
                 tb_add_jump((TranslationBlock *)(T0 & ~3), T0 & 3, tb);
+                spin_unlock(&tb_lock);
             }
+
             tc_ptr = tb->tc_ptr;
-            spin_unlock(&tb_lock);
 
             /* execute the generated code */
             gen_func = (void *)tc_ptr;
diff --git a/exec.h b/exec.h
index c6a6d1b..29a7ab1 100644 (file)
--- a/exec.h
+++ b/exec.h
@@ -23,9 +23,9 @@
 #define GEN_FLAG_SS32_SHIFT   2
 #define GEN_FLAG_VM_SHIFT     3
 #define GEN_FLAG_ST_SHIFT     4
-#define GEN_FLAG_CPL_SHIFT    7
-#define GEN_FLAG_IOPL_SHIFT   9
-#define GEN_FLAG_TF_SHIFT     11
+#define GEN_FLAG_TF_SHIFT     8 /* same position as eflags */
+#define GEN_FLAG_CPL_SHIFT    9
+#define GEN_FLAG_IOPL_SHIFT   12 /* same position as eflags */
 
 struct TranslationBlock;
 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,
 static inline void tb_add_jump(TranslationBlock *tb, int n, 
                                TranslationBlock *tb_next)
 {
-    /* patch the native jump address */
-    tb_set_jmp_target(tb, n, (unsigned long)tb_next->tc_ptr);
-
-    /* add in TB jmp circular list */
-    tb->jmp_next[n] = tb_next->jmp_first;
-    tb_next->jmp_first = (TranslationBlock *)((long)(tb) | (n));
+    /* NOTE: this test is only needed for thread safety */
+    if (!tb->jmp_next[n]) {
+        /* patch the native jump address */
+        tb_set_jmp_target(tb, n, (unsigned long)tb_next->tc_ptr);
+        
+        /* add in TB jmp circular list */
+        tb->jmp_next[n] = tb_next->jmp_first;
+        tb_next->jmp_first = (TranslationBlock *)((long)(tb) | (n));
+    }
 }
 
 #ifndef offsetof