more efficient locking

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@186 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2003-05-25 19:20:31 +00:00
parent 0ca790b92e
commit cf25629d1e
2 changed files with 18 additions and 14 deletions

View File

@ -206,14 +206,13 @@ int cpu_x86_exec(CPUX86State *env1)
flags |= (1 << GEN_FLAG_VM_SHIFT); flags |= (1 << GEN_FLAG_VM_SHIFT);
flags |= (3 << GEN_FLAG_CPL_SHIFT); flags |= (3 << GEN_FLAG_CPL_SHIFT);
} }
flags |= (env->eflags & IOPL_MASK) >> (12 - GEN_FLAG_IOPL_SHIFT); flags |= (env->eflags & (IOPL_MASK | TF_MASK));
flags |= (env->eflags & TF_MASK) << (GEN_FLAG_TF_SHIFT - 8);
cs_base = env->seg_cache[R_CS].base; cs_base = env->seg_cache[R_CS].base;
pc = cs_base + env->eip; pc = cs_base + env->eip;
spin_lock(&tb_lock);
tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base,
flags); flags);
if (!tb) { if (!tb) {
spin_lock(&tb_lock);
/* if no translated code available, then translate it now */ /* if no translated code available, then translate it now */
tb = tb_alloc((unsigned long)pc); tb = tb_alloc((unsigned long)pc);
if (!tb) { if (!tb) {
@ -244,6 +243,7 @@ int cpu_x86_exec(CPUX86State *env1)
tb->hash_next = NULL; tb->hash_next = NULL;
tb_link(tb); tb_link(tb);
code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); 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 #ifdef DEBUG_EXEC
if (loglevel) { if (loglevel) {
@ -252,13 +252,14 @@ int cpu_x86_exec(CPUX86State *env1)
lookup_symbol((void *)tb->pc)); lookup_symbol((void *)tb->pc));
} }
#endif #endif
/* see if we can patch the calling TB */ /* see if we can patch the calling TB */
if (T0 != 0 && !(env->eflags & TF_MASK)) { if (T0 != 0 && !(env->eflags & TF_MASK)) {
spin_lock(&tb_lock);
tb_add_jump((TranslationBlock *)(T0 & ~3), T0 & 3, tb); tb_add_jump((TranslationBlock *)(T0 & ~3), T0 & 3, tb);
spin_unlock(&tb_lock);
} }
tc_ptr = tb->tc_ptr; tc_ptr = tb->tc_ptr;
spin_unlock(&tb_lock);
/* execute the generated code */ /* execute the generated code */
gen_func = (void *)tc_ptr; gen_func = (void *)tc_ptr;

21
exec.h
View File

@ -23,9 +23,9 @@
#define GEN_FLAG_SS32_SHIFT 2 #define GEN_FLAG_SS32_SHIFT 2
#define GEN_FLAG_VM_SHIFT 3 #define GEN_FLAG_VM_SHIFT 3
#define GEN_FLAG_ST_SHIFT 4 #define GEN_FLAG_ST_SHIFT 4
#define GEN_FLAG_CPL_SHIFT 7 #define GEN_FLAG_TF_SHIFT 8 /* same position as eflags */
#define GEN_FLAG_IOPL_SHIFT 9 #define GEN_FLAG_CPL_SHIFT 9
#define GEN_FLAG_TF_SHIFT 11 #define GEN_FLAG_IOPL_SHIFT 12 /* same position as eflags */
struct TranslationBlock; struct TranslationBlock;
int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, 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, static inline void tb_add_jump(TranslationBlock *tb, int n,
TranslationBlock *tb_next) TranslationBlock *tb_next)
{ {
/* patch the native jump address */ /* NOTE: this test is only needed for thread safety */
tb_set_jmp_target(tb, n, (unsigned long)tb_next->tc_ptr); if (!tb->jmp_next[n]) {
/* patch the native jump address */
/* add in TB jmp circular list */ tb_set_jmp_target(tb, n, (unsigned long)tb_next->tc_ptr);
tb->jmp_next[n] = tb_next->jmp_first;
tb_next->jmp_first = (TranslationBlock *)((long)(tb) | (n)); /* add in TB jmp circular list */
tb->jmp_next[n] = tb_next->jmp_first;
tb_next->jmp_first = (TranslationBlock *)((long)(tb) | (n));
}
} }
#ifndef offsetof #ifndef offsetof