|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH v3 4/4] lib/uklock: Make mutex recursive
This patch changes the existing mutex implementation to support multiple locking
by the same thread.
Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
---
lib/uklock/include/uk/mutex.h | 36 ++++++++++++++++++++++++-----------
lib/uklock/mutex.c | 3 ++-
2 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/lib/uklock/include/uk/mutex.h b/lib/uklock/include/uk/mutex.h
index ff852b45..d4435ebd 100644
--- a/lib/uklock/include/uk/mutex.h
+++ b/lib/uklock/include/uk/mutex.h
@@ -54,49 +54,61 @@ extern "C" {
* uses wait queues for threads
*/
struct uk_mutex {
- int locked;
+ int lock_count;
+ struct uk_thread *owner;
struct uk_waitq wait;
};
#define UK_MUTEX_INITIALIZER(name) \
- { 0, __WAIT_QUEUE_INITIALIZER((name).wait) }
+ { 0, NULL, __WAIT_QUEUE_INITIALIZER((name).wait) }
void uk_mutex_init(struct uk_mutex *m);
static inline void uk_mutex_lock(struct uk_mutex *m)
{
+ struct uk_thread *current;
unsigned long irqf;
UK_ASSERT(m);
+ current = uk_thread_current();
+
for (;;) {
- uk_waitq_wait_event(&m->wait, m->locked == 0);
+ uk_waitq_wait_event(&m->wait,
+ m->lock_count == 0 || m->owner == current);
irqf = ukplat_lcpu_save_irqf();
- if (!m->locked)
+ if (m->lock_count == 0 || m->owner == current)
break;
ukplat_lcpu_restore_irqf(irqf);
}
- m->locked = 1;
+ m->lock_count++;
+ m->owner = current;
ukplat_lcpu_restore_irqf(irqf);
}
static inline int uk_mutex_trylock(struct uk_mutex *m)
{
+ struct uk_thread *current;
unsigned long irqf;
int ret = 0;
UK_ASSERT(m);
+ current = uk_thread_current();
+
irqf = ukplat_lcpu_save_irqf();
- if (!m->locked)
- ret = m->locked = 1;
+ if (m->lock_count == 0 || m->owner == current) {
+ ret = 1;
+ m->lock_count++;
+ m->owner = current;
+ }
ukplat_lcpu_restore_irqf(irqf);
return ret;
}
static inline int uk_mutex_is_locked(struct uk_mutex *m)
{
- return m->locked;
+ return m->lock_count > 0;
}
static inline void uk_mutex_unlock(struct uk_mutex *m)
@@ -106,9 +118,11 @@ static inline void uk_mutex_unlock(struct uk_mutex *m)
UK_ASSERT(m);
irqf = ukplat_lcpu_save_irqf();
- UK_ASSERT(m->locked);
- m->locked = 0;
- uk_waitq_wake_up(&m->wait);
+ UK_ASSERT(m->lock_count > 0);
+ if (--m->lock_count == 0) {
+ m->owner = NULL;
+ uk_waitq_wake_up(&m->wait);
+ }
ukplat_lcpu_restore_irqf(irqf);
}
diff --git a/lib/uklock/mutex.c b/lib/uklock/mutex.c
index 183a01db..5e5ec9a6 100644
--- a/lib/uklock/mutex.c
+++ b/lib/uklock/mutex.c
@@ -2,6 +2,7 @@
void uk_mutex_init(struct uk_mutex *m)
{
- m->locked = 0;
+ m->lock_count = 0;
+ m->owner = NULL;
uk_waitq_init(&m->wait);
}
--
2.20.1
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |