diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2007-03-09 08:03:18 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2007-03-09 08:03:18 +0000 |
commit | dee43ece2086e15894934b754e47cb7ce5882cda (patch) | |
tree | 9238a5c80fe4382975387ec90eca61bda8d4ed8f /firmware/kernel.c | |
parent | f4b83e68594f076cdfe510cd2e23b7f57fd158b5 (diff) | |
download | rockbox-dee43ece2086e15894934b754e47cb7ce5882cda.tar.gz rockbox-dee43ece2086e15894934b754e47cb7ce5882cda.zip |
Put an end to priority inversion in the ata driver. Gave up trying to have fully atomic dual use mutexes so just replaced the ata driver locking with spins. Maybe I'll have better luck later. Things should run smoothly with database updates and such happening in the background.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12688 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/kernel.c')
-rw-r--r-- | firmware/kernel.c | 79 |
1 files changed, 52 insertions, 27 deletions
diff --git a/firmware/kernel.c b/firmware/kernel.c index 313530ffba..db7249fdee 100644 --- a/firmware/kernel.c +++ b/firmware/kernel.c | |||
@@ -656,48 +656,73 @@ void mutex_init(struct mutex *m) | |||
656 | m->thread = NULL; | 656 | m->thread = NULL; |
657 | } | 657 | } |
658 | 658 | ||
659 | #ifdef CPU_PP | 659 | /* PortalPlayer chips have 2 cores, therefore need atomic mutexes |
660 | /* PortalPlayer chips have 2 cores, therefore need atomic mutexes */ | 660 | * Just use it for ARM, Coldfire and whatever else well...why not? |
661 | */ | ||
661 | 662 | ||
662 | static inline bool test_and_set(bool *x, bool v) | 663 | /* Macros generate better code than an inline function is this case */ |
663 | { | 664 | #if defined (CPU_PP) || defined (CPU_ARM) |
664 | asm volatile ( | 665 | #define test_and_set(x_, v_) \ |
665 | "swpb %0, %0, [%1]\n" | 666 | ({ \ |
666 | : "+r"(v) | 667 | uint32_t old; \ |
667 | : "r"(x) | 668 | asm volatile ( \ |
668 | ); | 669 | "swpb %[old], %[v], [%[x]] \r\n" \ |
669 | return v; | 670 | : [old]"=r"(old) \ |
670 | } | 671 | : [v]"r"((uint32_t)v_), [x]"r"((uint32_t *)x_) \ |
672 | ); \ | ||
673 | old; \ | ||
674 | }) | ||
675 | #elif defined (CPU_COLDFIRE) | ||
676 | #define test_and_set(x_, v_) \ | ||
677 | ({ \ | ||
678 | uint8_t old; \ | ||
679 | asm volatile ( \ | ||
680 | "bset.l %[v], (%[x]) \r\n" \ | ||
681 | "sne.b %[old] \r\n" \ | ||
682 | : [old]"=d,d"(old) \ | ||
683 | : [v]"i,d"((uint32_t)v_), [x]"a,a"((uint32_t *)x_) \ | ||
684 | ); \ | ||
685 | old; \ | ||
686 | }) | ||
687 | #else | ||
688 | /* default for no asm version */ | ||
689 | #define test_and_set(x_, v_) \ | ||
690 | ({ \ | ||
691 | uint32_t old = *(uint32_t *)x_; \ | ||
692 | *(uint32_t *)x_ = v_; \ | ||
693 | old; \ | ||
694 | }) | ||
695 | #endif | ||
671 | 696 | ||
672 | void mutex_lock(struct mutex *m) | 697 | void mutex_lock(struct mutex *m) |
673 | { | 698 | { |
674 | if (test_and_set(&m->locked,true)) | 699 | if (test_and_set(&m->locked, 1)) |
675 | { | 700 | { |
676 | /* Wait until the lock is open... */ | 701 | /* Wait until the lock is open... */ |
677 | block_thread(&m->thread); | 702 | block_thread(&m->thread); |
678 | } | 703 | } |
679 | } | 704 | } |
680 | 705 | ||
681 | #else | 706 | void mutex_unlock(struct mutex *m) |
682 | void mutex_lock(struct mutex *m) | ||
683 | { | 707 | { |
684 | if (m->locked) | 708 | if (m->thread == NULL) |
709 | m->locked = 0; | ||
710 | else | ||
711 | wakeup_thread(&m->thread); | ||
712 | } | ||
713 | |||
714 | void spinlock_lock(struct mutex *m) | ||
715 | { | ||
716 | while (test_and_set(&m->locked, 1)) | ||
685 | { | 717 | { |
686 | /* Wait until the lock is open... */ | 718 | /* wait until the lock is open... */ |
687 | block_thread(&m->thread); | 719 | switch_thread(true, NULL); |
688 | } | 720 | } |
689 | |||
690 | /* ...and lock it */ | ||
691 | m->locked = true; | ||
692 | } | 721 | } |
693 | #endif | ||
694 | 722 | ||
695 | void mutex_unlock(struct mutex *m) | 723 | void spinlock_unlock(struct mutex *m) |
696 | { | 724 | { |
697 | if (m->thread == NULL) | 725 | m->locked = 0; |
698 | m->locked = false; | ||
699 | else | ||
700 | wakeup_thread(&m->thread); | ||
701 | } | 726 | } |
702 | 727 | ||
703 | #endif | 728 | #endif /* ndef SIMULATOR */ |