summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/drivers/ata_mmc.c2
-rw-r--r--firmware/export/kernel.h19
-rw-r--r--firmware/kernel.c24
3 files changed, 25 insertions, 20 deletions
diff --git a/firmware/drivers/ata_mmc.c b/firmware/drivers/ata_mmc.c
index c27c3b5..dfc6302 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 405f6b6..c7fcd93 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 9d72a7e..aaa6752 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;
}