[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT PATCH 3/3] lib/uklock: Make mutex recursive


  • To: minios-devel@xxxxxxxxxxxxx
  • From: Costin Lupu <costin.lupu@xxxxxxxxx>
  • Date: Mon, 2 Sep 2019 16:22:21 +0300
  • Cc: felipe.huici@xxxxxxxxx, simon.kuenzer@xxxxxxxxx, sharan.santhanam@xxxxxxxxx
  • Delivery-date: Mon, 02 Sep 2019 13:22:46 +0000
  • Ironport-phdr: 9a23:QIUflxM9OhOfw26Z6bcl6mtUPXoX/o7sNwtQ0KIMzox0I/j9rarrMEGX3/hxlliBBdydt6sezbOJ6+u+AyQp2tWoiDg6aptCVhsI2409vjcLJ4q7M3D9N+PgdCcgHc5PBxdP9nC/NlVJSo6lPwWB6nK94iQPFRrhKAF7Ovr6GpLIj8Swyuu+54Dfbx9HiTagf79+Ngi6oAfNusUZgIZuNLs6xwfUrHdPZ+lY335jK0iJnxb76Mew/Zpj/DpVtvk86cNOUrj0crohQ7BAAzsoL2465MvwtRneVgSP/WcTUn8XkhVTHQfI6gzxU4rrvSv7sup93zSaPdHzQLspVzmu87tnRRn1gyoBKjU38nzYitZogaxbvhyvuhJxzY3Tbo6XOvpzZb/Rcc8ASGZdRMtdSzBND4WhZIUPFeoBOuNYopHjqlsJthu+GQisBOXywTFOm3/2xbA62PkmHA7a2wwgBM4OsHXSrNnvMKcSTPi1zLTTwDrfdPNawy/96JXTfRw7u/GMWqt9fMzMwkcsDwPIlkicpIP4Mz+P1ekAs3KX4/R+We+tkWIqpRl9riWgy8sxkIXEhYIYxkra+Sh3zos5P8C0RUFlbdOiDZBerTuVN5FsTcMnW2xovSE6xaAYtpOjZygKzYgnxwbYa/yab4iE+hLjW/iVITd/nH9lZre/iAyz8Uik0OHzStK03ExSripYidbArGoN1xvL5siGTPty4Fuh1C6S2w3c9+1IO0M5mKrBJ5I/3LI9lIAfvErbEi/zgkr2jauWdks++uiv7uTqeqnpppiHN49oiwH+NL4imsiiAeQgLwgDRHSU+f+m2L374E32W69GjucxkqXBqpDVOdwbprKlAw9Syosj7he/DzGn0NQfhnkLNU9KdwyZj4f3P1HDO/T4Dfakg1Swizdn3f/HMaPnApnXKXjDirjhd65n60FA0Aoz0cxf55VMB7EPPv3zXk7xtMTGARMjMwy03ufnB8l81o4FX2KAHLOWMKfIvlCT/O4gPfSMbpcPuDnhM/gl++LujXghlF8Gfammx4EXZ2q+Hvh8OEWWe3zsgssBEWgQuAoxVunqhUaEUTFNe3myW7gz6SohBI24EIfJXpqtj6CZ3CenAp1WYXhLCkuNEXftcIWEXe0AaCGPIsB/lDwFVKauS5U62BGoqgD1175nIfDP9SECq53jyYs92+qGkBA09DtvSsiQzWyJZ2V1hX8TAS872uZ4u0Mu5E2E1P1ThOdEFNobw+5RT09uPpnH0+18TdTvQh/pdczPUEusBM+hV2JiBuktysMDNh4uU+6piQrOinKn
  • Ironport-sdr: ILOqie0c2WyRxl5C+aGJfFmcw/mJJCPmrqNannqEU2YM5AjHl8LG+fBxt1Kdnm9NumnFqYdZWu TwMZTuiip0Sw==
  • List-id: Mini-os development list <minios-devel.lists.xenproject.org>

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 | 29 +++++++++++++++++++++++------
 lib/uklock/mutex.c            |  2 ++
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/lib/uklock/include/uk/mutex.h b/lib/uklock/include/uk/mutex.h
index ff852b45..f9a41a93 100644
--- a/lib/uklock/include/uk/mutex.h
+++ b/lib/uklock/include/uk/mutex.h
@@ -55,41 +55,55 @@ extern "C" {
  */
 struct uk_mutex {
        int locked;
+       int depth;
+       struct uk_thread *owner;
        struct uk_waitq wait;
 };
 
 #define        UK_MUTEX_INITIALIZER(name)                              \
-       { 0, __WAIT_QUEUE_INITIALIZER((name).wait) }
+       { 0, 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->locked == 0 || m->owner == current);
                irqf = ukplat_lcpu_save_irqf();
-               if (!m->locked)
+               if (m->locked == 0 || m->owner == current)
                        break;
                ukplat_lcpu_restore_irqf(irqf);
        }
        m->locked = 1;
+       m->depth++;
+       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)
+       if (m->locked == 0 || m->owner == current) {
                ret = m->locked = 1;
+               m->depth++;
+               m->owner = current;
+       }
        ukplat_lcpu_restore_irqf(irqf);
        return ret;
 }
@@ -107,8 +121,11 @@ static inline void uk_mutex_unlock(struct uk_mutex *m)
 
        irqf = ukplat_lcpu_save_irqf();
        UK_ASSERT(m->locked);
-       m->locked = 0;
-       uk_waitq_wake_up(&m->wait);
+       if (--m->depth == 0) {
+               m->locked = 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..07faf1e7 100644
--- a/lib/uklock/mutex.c
+++ b/lib/uklock/mutex.c
@@ -3,5 +3,7 @@
 void uk_mutex_init(struct uk_mutex *m)
 {
        m->locked = 0;
+       m->depth = 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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.