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,4 +542,104 @@ static inline TranslationBlock *tb_find(TranslationBlock ***pptb, | ||
| 542 | #define offsetof(type, field) ((size_t) &((type *)0)->field) | 542 | #define offsetof(type, field) ((size_t) &((type *)0)->field) |
| 543 | #endif | 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 | #endif /* CPU_I386_H */ | 645 | #endif /* CPU_I386_H */ |
exec.c
| @@ -42,6 +42,8 @@ | @@ -42,6 +42,8 @@ | ||
| 42 | TranslationBlock tbs[CODE_GEN_MAX_BLOCKS]; | 42 | TranslationBlock tbs[CODE_GEN_MAX_BLOCKS]; |
| 43 | TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE]; | 43 | TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE]; |
| 44 | int nb_tbs; | 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 | uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE]; | 48 | uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE]; |
| 47 | uint8_t *code_gen_ptr; | 49 | uint8_t *code_gen_ptr; |
| @@ -172,6 +174,7 @@ void page_set_flags(unsigned long start, unsigned long end, int flags) | @@ -172,6 +174,7 @@ void page_set_flags(unsigned long start, unsigned long end, int flags) | ||
| 172 | end = TARGET_PAGE_ALIGN(end); | 174 | end = TARGET_PAGE_ALIGN(end); |
| 173 | if (flags & PAGE_WRITE) | 175 | if (flags & PAGE_WRITE) |
| 174 | flags |= PAGE_WRITE_ORG; | 176 | flags |= PAGE_WRITE_ORG; |
| 177 | + spin_lock(&tb_lock); | ||
| 175 | for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) { | 178 | for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) { |
| 176 | p = page_find_alloc(addr >> TARGET_PAGE_BITS); | 179 | p = page_find_alloc(addr >> TARGET_PAGE_BITS); |
| 177 | /* if the write protection is set, then we invalidate the code | 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,6 +186,7 @@ void page_set_flags(unsigned long start, unsigned long end, int flags) | ||
| 183 | } | 186 | } |
| 184 | p->flags = flags; | 187 | p->flags = flags; |
| 185 | } | 188 | } |
| 189 | + spin_unlock(&tb_lock); | ||
| 186 | } | 190 | } |
| 187 | 191 | ||
| 188 | void cpu_x86_tblocks_init(void) | 192 | void cpu_x86_tblocks_init(void) |