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,) bool mmc_disk_is_active(void) { /* this is correct unless early return from write gets implemented */ - return mmc_mutex.locked; + return mutex_test(&mmc_mutex); } 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 struct mutex { struct thread_entry *queue; /* waiter list */ - int count; /* lock owner recursion count */ + int recursion; /* lock owner recursion count */ #ifdef HAVE_PRIORITY_SCHEDULING struct blocker blocker; /* priority inheritance info for waiters */ bool no_preempt; /* don't allow higher-priority thread to be scheduled even if woken */ #else - struct thread_entry *thread; + struct thread_entry *thread; /* Indicates owner thread - an owner + implies a locked state - same goes + for priority scheduling + (in blocker struct for that) */ #endif IF_COP( struct corelock cl; ) /* multiprocessor sync */ - bool locked; /* locked semaphore */ }; #ifdef HAVE_SEMAPHORE_OBJECTS @@ -265,10 +267,17 @@ extern void mutex_init(struct mutex *m); extern void mutex_lock(struct mutex *m); extern void mutex_unlock(struct mutex *m); #ifdef HAVE_PRIORITY_SCHEDULING -/* Temporary function to disable mutex preempting a thread on unlock */ +/* Deprecated temporary function to disable mutex preempting a thread on + * unlock - firmware/drivers/fat.c and a couple places in apps/buffering.c - + * reliance on it is a bug! */ static inline void mutex_set_preempt(struct mutex *m, bool preempt) { m->no_preempt = !preempt; } -#endif +#else +/* Deprecated but needed for now - firmware/drivers/ata_mmc.c */ +static inline bool mutex_test(const struct mutex *m) + { return m->thread != NULL; } +#endif /* HAVE_PRIORITY_SCHEDULING */ + #ifdef HAVE_SEMAPHORE_OBJECTS extern void semaphore_init(struct semaphore *s, int max, int start); 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) * Simple mutex functions ;) ****************************************************************************/ -static inline void mutex_set_thread(struct mutex *mtx, struct thread_entry *td) - __attribute__((always_inline)); -static inline void mutex_set_thread(struct mutex *mtx, struct thread_entry *td) +static inline void __attribute__((always_inline)) +mutex_set_thread(struct mutex *mtx, struct thread_entry *td) { #ifdef HAVE_PRIORITY_SCHEDULING mtx->blocker.thread = td; @@ -838,9 +837,8 @@ static inline void mutex_set_thread(struct mutex *mtx, struct thread_entry *td) #endif } -static inline struct thread_entry* mutex_get_thread(struct mutex *mtx) - __attribute__((always_inline)); -static inline struct thread_entry* mutex_get_thread(struct mutex *mtx) +static inline struct thread_entry * __attribute__((always_inline)) +mutex_get_thread(volatile struct mutex *mtx) { #ifdef HAVE_PRIORITY_SCHEDULING return mtx->blocker.thread; @@ -855,8 +853,7 @@ void mutex_init(struct mutex *m) { corelock_init(&m->cl); m->queue = NULL; - m->count = 0; - m->locked = false; + m->recursion = 0; mutex_set_thread(m, NULL); #ifdef HAVE_PRIORITY_SCHEDULING m->blocker.priority = PRIORITY_IDLE; @@ -873,18 +870,18 @@ void mutex_lock(struct mutex *m) if(current == mutex_get_thread(m)) { /* current thread already owns this mutex */ - m->count++; + m->recursion++; return; } /* lock out other cores */ corelock_lock(&m->cl); - if(LIKELY(!m->locked)) + /* must read thread again inside cs (a multiprocessor concern really) */ + if(LIKELY(mutex_get_thread(m) == NULL)) { /* lock is open */ mutex_set_thread(m, current); - m->locked = true; corelock_unlock(&m->cl); return; } @@ -912,10 +909,10 @@ void mutex_unlock(struct mutex *m) mutex_get_thread(m)->name, thread_id_entry(THREAD_ID_CURRENT)->name); - if(m->count > 0) + if(m->recursion > 0) { /* this thread still owns lock */ - m->count--; + m->recursion--; return; } @@ -927,7 +924,6 @@ void mutex_unlock(struct mutex *m) { /* no threads waiting - open the lock */ mutex_set_thread(m, NULL); - m->locked = false; corelock_unlock(&m->cl); return; }