diff options
author | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-06-02 16:16:42 +0000 |
---|---|---|
committer | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-06-02 16:16:42 +0000 |
commit | c8a706fe6242a553960ccc3071a4e75ceba6f3d2 (patch) | |
tree | e68691a013a24d3082b51b85a0837ccd50029e7c /exec.c | |
parent | 30813cea9b6166f2302a973d57c5818273f6c4d2 (diff) |
Multithreaded locking for mmap().
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4654 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'exec.c')
-rw-r--r-- | exec.c | 20 |
1 files changed, 19 insertions, 1 deletions
@@ -234,6 +234,7 @@ static void page_init(void) FILE *f; int n; + mmap_lock(); last_brk = (unsigned long)sbrk(0); f = fopen("/proc/self/maps", "r"); if (f) { @@ -251,6 +252,7 @@ static void page_init(void) } while (!feof(f)); fclose(f); } + mmap_unlock(); } #endif } @@ -326,6 +328,8 @@ static inline PhysPageDesc *phys_page_find(target_phys_addr_t index) static void tlb_protect_code(ram_addr_t ram_addr); static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr, target_ulong vaddr); +#define mmap_lock() do { } while(0) +#define mmap_unlock() do { } while(0) #endif #define DEFAULT_CODE_GEN_BUFFER_SIZE (32 * 1024 * 1024) @@ -1049,6 +1053,9 @@ void tb_link_phys(TranslationBlock *tb, unsigned int h; TranslationBlock **ptb; + /* Grab the mmap lock to stop another thread invalidating this TB + before we are done. */ + mmap_lock(); /* add in the physical hash table */ h = tb_phys_hash_func(phys_pc); ptb = &tb_phys_hash[h]; @@ -1075,6 +1082,7 @@ void tb_link_phys(TranslationBlock *tb, #ifdef DEBUG_TB_CHECK tb_page_check(); #endif + mmap_unlock(); } /* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr < @@ -2002,6 +2010,7 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) PageDesc *p; target_ulong addr; + /* mmap_lock should already be held. */ start = start & TARGET_PAGE_MASK; end = TARGET_PAGE_ALIGN(end); if (flags & PAGE_WRITE) @@ -2065,11 +2074,18 @@ int page_unprotect(target_ulong address, unsigned long pc, void *puc) PageDesc *p, *p1; target_ulong host_start, host_end, addr; + /* Technically this isn't safe inside a signal handler. However we + know this only ever happens in a synchronous SEGV handler, so in + practice it seems to be ok. */ + mmap_lock(); + host_start = address & qemu_host_page_mask; page_index = host_start >> TARGET_PAGE_BITS; p1 = page_find(page_index); - if (!p1) + if (!p1) { + mmap_unlock(); return 0; + } host_end = host_start + qemu_host_page_size; p = p1; prot = 0; @@ -2091,9 +2107,11 @@ int page_unprotect(target_ulong address, unsigned long pc, void *puc) #ifdef DEBUG_TB_CHECK tb_invalidate_check(address); #endif + mmap_unlock(); return 1; } } + mmap_unlock(); return 0; } |