Commit eb51d102bbd541963ac5cb98d5a8c7c2fe9453d9

Authored by bellard
1 parent 25eb4484

better locks


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@169 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 104 additions and 0 deletions
cpu-i386.h
... ... @@ -542,4 +542,104 @@ static inline TranslationBlock *tb_find(TranslationBlock ***pptb,
542 542 #define offsetof(type, field) ((size_t) &((type *)0)->field)
543 543 #endif
544 544  
  545 +#ifdef __powerpc__
  546 +static inline int testandset (int *p)
  547 +{
  548 + int ret;
  549 + __asm__ __volatile__ (
  550 + "0: lwarx %0,0,%1 ;"
  551 + " xor. %0,%3,%0;"
  552 + " bne 1f;"
  553 + " stwcx. %2,0,%1;"
  554 + " bne- 0b;"
  555 + "1: "
  556 + : "=&r" (ret)
  557 + : "r" (p), "r" (1), "r" (0)
  558 + : "cr0", "memory");
  559 + return ret;
  560 +}
  561 +#endif
  562 +
  563 +#ifdef __i386__
  564 +static inline int testandset (int *p)
  565 +{
  566 + char ret;
  567 + long int readval;
  568 +
  569 + __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
  570 + : "=q" (ret), "=m" (*p), "=a" (readval)
  571 + : "r" (1), "m" (*p), "a" (0)
  572 + : "memory");
  573 + return ret;
  574 +}
  575 +#endif
  576 +
  577 +#ifdef __s390__
  578 +static inline int testandset (int *p)
  579 +{
  580 + int ret;
  581 +
  582 + __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n"
  583 + " jl 0b"
  584 + : "=&d" (ret)
  585 + : "r" (1), "a" (p), "0" (*p)
  586 + : "cc", "memory" );
  587 + return ret;
  588 +}
  589 +#endif
  590 +
  591 +#ifdef __alpha__
  592 +int testandset (int *p)
  593 +{
  594 + int ret;
  595 + unsigned long one;
  596 +
  597 + __asm__ __volatile__ ("0: mov 1,%2\n"
  598 + " ldl_l %0,%1\n"
  599 + " stl_c %2,%1\n"
  600 + " beq %2,1f\n"
  601 + ".subsection 2\n"
  602 + "1: br 0b\n"
  603 + ".previous"
  604 + : "=r" (ret), "=m" (*p), "=r" (one)
  605 + : "m" (*p));
  606 + return ret;
  607 +}
  608 +#endif
  609 +
  610 +#ifdef __sparc__
  611 +static inline int testandset (int *p)
  612 +{
  613 + int ret;
  614 +
  615 + __asm__ __volatile__("ldstub [%1], %0"
  616 + : "=r" (ret)
  617 + : "r" (p)
  618 + : "memory");
  619 +
  620 + return (ret ? 1 : 0);
  621 +}
  622 +#endif
  623 +
  624 +typedef int spinlock_t;
  625 +
  626 +#define SPIN_LOCK_UNLOCKED 0
  627 +
  628 +static inline void spin_lock(spinlock_t *lock)
  629 +{
  630 + while (testandset(lock));
  631 +}
  632 +
  633 +static inline void spin_unlock(spinlock_t *lock)
  634 +{
  635 + *lock = 0;
  636 +}
  637 +
  638 +static inline int spin_trylock(spinlock_t *lock)
  639 +{
  640 + return !testandset(lock);
  641 +}
  642 +
  643 +extern spinlock_t tb_lock;
  644 +
545 645 #endif /* CPU_I386_H */
... ...
... ... @@ -42,6 +42,8 @@
42 42 TranslationBlock tbs[CODE_GEN_MAX_BLOCKS];
43 43 TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE];
44 44 int nb_tbs;
  45 +/* any access to the tbs or the page table must use this lock */
  46 +spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
45 47  
46 48 uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
47 49 uint8_t *code_gen_ptr;
... ... @@ -172,6 +174,7 @@ void page_set_flags(unsigned long start, unsigned long end, int flags)
172 174 end = TARGET_PAGE_ALIGN(end);
173 175 if (flags & PAGE_WRITE)
174 176 flags |= PAGE_WRITE_ORG;
  177 + spin_lock(&tb_lock);
175 178 for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
176 179 p = page_find_alloc(addr >> TARGET_PAGE_BITS);
177 180 /* if the write protection is set, then we invalidate the code
... ... @@ -183,6 +186,7 @@ void page_set_flags(unsigned long start, unsigned long end, int flags)
183 186 }
184 187 p->flags = flags;
185 188 }
  189 + spin_unlock(&tb_lock);
186 190 }
187 191  
188 192 void cpu_x86_tblocks_init(void)
... ...