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) | ... | ... |