From 72d4d8f40da85c0058c850cb02312ea4c82a43fb Mon Sep 17 00:00:00 2001
From: Glauber Costa <glommer@cloudius-systems.com>
Date: Sat, 11 Jan 2014 01:03:28 +0400
Subject: [PATCH] msleep: make it accept any kind of mutex

First of all, I am sorry. I am sorry Avi, Dor, Pekka, God, Dennis Ritchie, et caterva.
I am so very sorry. This is probably one of the ugliest things ever written by a C
programmer in the history of programming.

The story is: ZFS defines its own mutex of type kmutex_t, which is basically just a OSv
in our implementation. In a piece of code currently commented out (not for long), it calls:

    msleep(&needfree, &arc_reclaim_thr_lock, 0, "zfs:lowmem", 0);

The problem is that our msleep implementation expects a "struct mtx" which is our own
wrapper around mutex (Maybe that should be changed? Does anybody remember why it was
done this way?)

Keep in mind that we are going to great lenghts not to change ZFS (ifdefing code out
is generally fine), so the casting solution could not be used. I've tried to change the
for-ZFS definitions of mutex in the BSD glue code, but then, after a couple of hours
I was still resolving conflicts with all the other parts that would break because they
were expecting a certain type that was now changed.

I eventually set for the current ugly but functional solution: code msleep in a
way that it can accept any kind of mutex. That is really ugly because by "any
kind of mutex" I really mean any kind of crap the user passes and good bye type
safety altogether. But it works with minimal changes, and more importantly, with
all the changes being in *our* glue code.

If anybody have other ideas, I would be happy to try them out. But at this time,
I believe that to be the best compromise.

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
---
 bsd/porting/synch.cc | 12 ++++++------
 bsd/porting/synch.h  |  3 ++-
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/bsd/porting/synch.cc b/bsd/porting/synch.cc
index 489ed8226..fb3a46ad6 100644
--- a/bsd/porting/synch.cc
+++ b/bsd/porting/synch.cc
@@ -42,7 +42,7 @@ public:
         return (_instance);
     }
 
-    int msleep(void *chan, struct mtx *mtx, int priority, const char *wmesg,
+    int _msleep(void *chan, struct mtx *mtx, int priority, const char *wmesg,
          int timo);
 
     void wakeup(void* chan);
@@ -60,7 +60,7 @@ private:
 
 synch_port* synch_port::_instance = nullptr;
 
-int synch_port::msleep(void *chan, struct mtx *mtx,
+int synch_port::_msleep(void *chan, struct mtx *mtx,
     int priority, const char *wmesg, int timo_hz)
 {
     trace_synch_msleep(chan, mtx, timo_hz);
@@ -170,20 +170,20 @@ void synch_port::wakeup_one(void* chan)
     mutex_unlock(&_lock);
 }
 
-extern "C" int msleep(void *chan, struct mtx *mtx, int priority, const char *wmesg,
+extern "C" int _msleep(void *chan, struct mtx *mtx, int priority, const char *wmesg,
      int timo)
 {
-    return (synch_port::instance()->msleep(chan, mtx, priority, wmesg, timo));
+    return (synch_port::instance()->_msleep(chan, mtx, priority, wmesg, timo));
 }
 
 extern "C" int tsleep(void *chan, int priority, const char *wmesg, int timo)
 {
-    return (msleep(chan, 0, priority, wmesg, timo));
+    return (_msleep(chan, 0, priority, wmesg, timo));
 }
 
 extern "C" void bsd_pause(const char *wmesg, int timo)
 {
-    msleep(0, 0, 0, wmesg, timo);
+    _msleep(0, 0, 0, wmesg, timo);
 }
 
 extern "C" void wakeup(void* chan)
diff --git a/bsd/porting/synch.h b/bsd/porting/synch.h
index 7a106f1be..06a113416 100644
--- a/bsd/porting/synch.h
+++ b/bsd/porting/synch.h
@@ -15,9 +15,10 @@
 /* See the FreeBSD sleep(9) manual entry for usage */
 
 __BEGIN_DECLS
-int msleep(void *chan, struct mtx *mtx, int priority, const char *wmesg,
+int _msleep(void *chan, struct mtx *mtx, int priority, const char *wmesg,
      int timo);
 
+#define msleep(_c, _m, _p, _w, _t) _msleep((_c), (struct mtx *)(_m), (_p), (_w), (_t))
 int tsleep(void *chan, int priority, const char *wmesg, int timo);
 
 void bsd_pause(const char *wmesg, int timo);
-- 
GitLab