[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 |