Commit eb51d102bbd541963ac5cb98d5a8c7c2fe9453d9
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 */ | ... | ... |
exec.c
... | ... | @@ -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) | ... | ... |