diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/ata_mmc.c | 2 | ||||
-rw-r--r-- | firmware/export/kernel.h | 19 | ||||
-rw-r--r-- | firmware/kernel.c | 24 |
3 files changed, 25 insertions, 20 deletions
diff --git a/firmware/drivers/ata_mmc.c b/firmware/drivers/ata_mmc.c index c27c3b5d05..dfc63021c9 100644 --- a/firmware/drivers/ata_mmc.c +++ b/firmware/drivers/ata_mmc.c | |||
@@ -760,7 +760,7 @@ int mmc_write_sectors(IF_MD2(int drive,) | |||
760 | bool mmc_disk_is_active(void) | 760 | bool mmc_disk_is_active(void) |
761 | { | 761 | { |
762 | /* this is correct unless early return from write gets implemented */ | 762 | /* this is correct unless early return from write gets implemented */ |
763 | return mmc_mutex.locked; | 763 | return mutex_test(&mmc_mutex); |
764 | } | 764 | } |
765 | 765 | ||
766 | static void mmc_thread(void) | 766 | static void mmc_thread(void) |
diff --git a/firmware/export/kernel.h b/firmware/export/kernel.h index 405f6b6838..c7fcd93284 100644 --- a/firmware/export/kernel.h +++ b/firmware/export/kernel.h | |||
@@ -142,17 +142,19 @@ struct event_queue | |||
142 | struct mutex | 142 | struct mutex |
143 | { | 143 | { |
144 | struct thread_entry *queue; /* waiter list */ | 144 | struct thread_entry *queue; /* waiter list */ |
145 | int count; /* lock owner recursion count */ | 145 | int recursion; /* lock owner recursion count */ |
146 | #ifdef HAVE_PRIORITY_SCHEDULING | 146 | #ifdef HAVE_PRIORITY_SCHEDULING |
147 | struct blocker blocker; /* priority inheritance info | 147 | struct blocker blocker; /* priority inheritance info |
148 | for waiters */ | 148 | for waiters */ |
149 | bool no_preempt; /* don't allow higher-priority thread | 149 | bool no_preempt; /* don't allow higher-priority thread |
150 | to be scheduled even if woken */ | 150 | to be scheduled even if woken */ |
151 | #else | 151 | #else |
152 | struct thread_entry *thread; | 152 | struct thread_entry *thread; /* Indicates owner thread - an owner |
153 | implies a locked state - same goes | ||
154 | for priority scheduling | ||
155 | (in blocker struct for that) */ | ||
153 | #endif | 156 | #endif |
154 | IF_COP( struct corelock cl; ) /* multiprocessor sync */ | 157 | IF_COP( struct corelock cl; ) /* multiprocessor sync */ |
155 | bool locked; /* locked semaphore */ | ||
156 | }; | 158 | }; |
157 | 159 | ||
158 | #ifdef HAVE_SEMAPHORE_OBJECTS | 160 | #ifdef HAVE_SEMAPHORE_OBJECTS |
@@ -265,10 +267,17 @@ extern void mutex_init(struct mutex *m); | |||
265 | extern void mutex_lock(struct mutex *m); | 267 | extern void mutex_lock(struct mutex *m); |
266 | extern void mutex_unlock(struct mutex *m); | 268 | extern void mutex_unlock(struct mutex *m); |
267 | #ifdef HAVE_PRIORITY_SCHEDULING | 269 | #ifdef HAVE_PRIORITY_SCHEDULING |
268 | /* Temporary function to disable mutex preempting a thread on unlock */ | 270 | /* Deprecated temporary function to disable mutex preempting a thread on |
271 | * unlock - firmware/drivers/fat.c and a couple places in apps/buffering.c - | ||
272 | * reliance on it is a bug! */ | ||
269 | static inline void mutex_set_preempt(struct mutex *m, bool preempt) | 273 | static inline void mutex_set_preempt(struct mutex *m, bool preempt) |
270 | { m->no_preempt = !preempt; } | 274 | { m->no_preempt = !preempt; } |
271 | #endif | 275 | #else |
276 | /* Deprecated but needed for now - firmware/drivers/ata_mmc.c */ | ||
277 | static inline bool mutex_test(const struct mutex *m) | ||
278 | { return m->thread != NULL; } | ||
279 | #endif /* HAVE_PRIORITY_SCHEDULING */ | ||
280 | |||
272 | #ifdef HAVE_SEMAPHORE_OBJECTS | 281 | #ifdef HAVE_SEMAPHORE_OBJECTS |
273 | extern void semaphore_init(struct semaphore *s, int max, int start); | 282 | extern void semaphore_init(struct semaphore *s, int max, int start); |
274 | extern void semaphore_wait(struct semaphore *s); | 283 | extern void semaphore_wait(struct semaphore *s); |
diff --git a/firmware/kernel.c b/firmware/kernel.c index 9d72a7eeda..aaa675241b 100644 --- a/firmware/kernel.c +++ b/firmware/kernel.c | |||
@@ -827,9 +827,8 @@ int queue_broadcast(long id, intptr_t data) | |||
827 | * Simple mutex functions ;) | 827 | * Simple mutex functions ;) |
828 | ****************************************************************************/ | 828 | ****************************************************************************/ |
829 | 829 | ||
830 | static inline void mutex_set_thread(struct mutex *mtx, struct thread_entry *td) | 830 | static inline void __attribute__((always_inline)) |
831 | __attribute__((always_inline)); | 831 | mutex_set_thread(struct mutex *mtx, struct thread_entry *td) |
832 | static inline void mutex_set_thread(struct mutex *mtx, struct thread_entry *td) | ||
833 | { | 832 | { |
834 | #ifdef HAVE_PRIORITY_SCHEDULING | 833 | #ifdef HAVE_PRIORITY_SCHEDULING |
835 | mtx->blocker.thread = td; | 834 | mtx->blocker.thread = td; |
@@ -838,9 +837,8 @@ static inline void mutex_set_thread(struct mutex *mtx, struct thread_entry *td) | |||
838 | #endif | 837 | #endif |
839 | } | 838 | } |
840 | 839 | ||
841 | static inline struct thread_entry* mutex_get_thread(struct mutex *mtx) | 840 | static inline struct thread_entry * __attribute__((always_inline)) |
842 | __attribute__((always_inline)); | 841 | mutex_get_thread(volatile struct mutex *mtx) |
843 | static inline struct thread_entry* mutex_get_thread(struct mutex *mtx) | ||
844 | { | 842 | { |
845 | #ifdef HAVE_PRIORITY_SCHEDULING | 843 | #ifdef HAVE_PRIORITY_SCHEDULING |
846 | return mtx->blocker.thread; | 844 | return mtx->blocker.thread; |
@@ -855,8 +853,7 @@ void mutex_init(struct mutex *m) | |||
855 | { | 853 | { |
856 | corelock_init(&m->cl); | 854 | corelock_init(&m->cl); |
857 | m->queue = NULL; | 855 | m->queue = NULL; |
858 | m->count = 0; | 856 | m->recursion = 0; |
859 | m->locked = false; | ||
860 | mutex_set_thread(m, NULL); | 857 | mutex_set_thread(m, NULL); |
861 | #ifdef HAVE_PRIORITY_SCHEDULING | 858 | #ifdef HAVE_PRIORITY_SCHEDULING |
862 | m->blocker.priority = PRIORITY_IDLE; | 859 | m->blocker.priority = PRIORITY_IDLE; |
@@ -873,18 +870,18 @@ void mutex_lock(struct mutex *m) | |||
873 | if(current == mutex_get_thread(m)) | 870 | if(current == mutex_get_thread(m)) |
874 | { | 871 | { |
875 | /* current thread already owns this mutex */ | 872 | /* current thread already owns this mutex */ |
876 | m->count++; | 873 | m->recursion++; |
877 | return; | 874 | return; |
878 | } | 875 | } |
879 | 876 | ||
880 | /* lock out other cores */ | 877 | /* lock out other cores */ |
881 | corelock_lock(&m->cl); | 878 | corelock_lock(&m->cl); |
882 | 879 | ||
883 | if(LIKELY(!m->locked)) | 880 | /* must read thread again inside cs (a multiprocessor concern really) */ |
881 | if(LIKELY(mutex_get_thread(m) == NULL)) | ||
884 | { | 882 | { |
885 | /* lock is open */ | 883 | /* lock is open */ |
886 | mutex_set_thread(m, current); | 884 | mutex_set_thread(m, current); |
887 | m->locked = true; | ||
888 | corelock_unlock(&m->cl); | 885 | corelock_unlock(&m->cl); |
889 | return; | 886 | return; |
890 | } | 887 | } |
@@ -912,10 +909,10 @@ void mutex_unlock(struct mutex *m) | |||
912 | mutex_get_thread(m)->name, | 909 | mutex_get_thread(m)->name, |
913 | thread_id_entry(THREAD_ID_CURRENT)->name); | 910 | thread_id_entry(THREAD_ID_CURRENT)->name); |
914 | 911 | ||
915 | if(m->count > 0) | 912 | if(m->recursion > 0) |
916 | { | 913 | { |
917 | /* this thread still owns lock */ | 914 | /* this thread still owns lock */ |
918 | m->count--; | 915 | m->recursion--; |
919 | return; | 916 | return; |
920 | } | 917 | } |
921 | 918 | ||
@@ -927,7 +924,6 @@ void mutex_unlock(struct mutex *m) | |||
927 | { | 924 | { |
928 | /* no threads waiting - open the lock */ | 925 | /* no threads waiting - open the lock */ |
929 | mutex_set_thread(m, NULL); | 926 | mutex_set_thread(m, NULL); |
930 | m->locked = false; | ||
931 | corelock_unlock(&m->cl); | 927 | corelock_unlock(&m->cl); |
932 | return; | 928 | return; |
933 | } | 929 | } |