summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2017-03-04 16:27:05 +0100
committerRichard Braun <rbraun@sceen.net>2017-03-04 16:52:30 +0100
commitf4d75d0cd8424c17521d520fd9018ea22b7daaad (patch)
treea6f4807984c781e3584c79491ecb23e75f012ac6
parent3fcd23576e800ebbfb1378c2e6aff2e9e1027989 (diff)
kern/mutex: implement the --enable-mutex-pi option
This option turns all regular mutexes into real-time mutexes.
-rw-r--r--INSTALL5
-rw-r--r--configure.ac10
-rw-r--r--kern/mutex.c4
-rw-r--r--kern/mutex.h46
-rw-r--r--kern/mutex_i.h3
-rw-r--r--kern/mutex_types.h16
6 files changed, 83 insertions, 1 deletions
diff --git a/INSTALL b/INSTALL
index f9042109..97dcd148 100644
--- a/INSTALL
+++ b/INSTALL
@@ -243,6 +243,11 @@ X15 Options
in a file named `test_pmap_update_mp.c' would be selected with the
option `--enable-test-module=pmap_update_mp'.
+`--enable-mutex-pi'
+ Enable priority inheritance for regular mutexes (note that priority
+ inheritance is always enabled for real-time mutexes).
+ TODO Thoroughly describe the implications of this option
+
`--with-max-cpus=MAX_CPUS'
Set the maximum number of supported processors.
diff --git a/configure.ac b/configure.ac
index 023140bd..8c5b64a9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -34,6 +34,12 @@ AC_ARG_WITH([max-cpus],
[opt_max_cpus=$withval],
[opt_max_cpus=128])
+AC_ARG_ENABLE([mutex-pi],
+ [AS_HELP_STRING([--enable-mutex-pi],
+ [enable priority inheritance for regular mutexes
+ (note that priority inheritance is always
+ enabled for real-time mutexes)])])
+
AC_DEFINE([__KERNEL__], [1], [kernel code])
AC_DEFINE_UNQUOTED([ARCH], [$arch], [arch])
@@ -74,6 +80,10 @@ AC_DEFINE_UNQUOTED([MAX_CPUS], [$opt_max_cpus],
[maximum number of supported processors])
AC_MSG_NOTICE([maximum number of supported processors: $opt_max_cpus])
+AS_IF([test x"$enable_mutex_pi" = xyes],
+ [AC_DEFINE_UNQUOTED([X15_MUTEX_PI], [],
+ [Enable priority inheritance for regular mutexes])])
+
AH_BOTTOM([#include <kern/config.h>])
AC_CONFIG_HEADER([config.h])
AC_CONFIG_FILES([Makefile])
diff --git a/kern/mutex.c b/kern/mutex.c
index 1a1c2ea7..6a1af208 100644
--- a/kern/mutex.c
+++ b/kern/mutex.c
@@ -15,6 +15,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#ifndef X15_MUTEX_PI
+
#include <stddef.h>
#include <kern/mutex.h>
@@ -62,3 +64,5 @@ mutex_unlock_slow(struct mutex *mutex)
sleepq_release(sleepq);
}
+
+#endif /* X15_MUTEX_PI */
diff --git a/kern/mutex.h b/kern/mutex.h
index 2804fc44..c8ae4639 100644
--- a/kern/mutex.h
+++ b/kern/mutex.h
@@ -25,10 +25,52 @@
#ifndef _KERN_MUTEX_H
#define _KERN_MUTEX_H
+#include <kern/mutex_types.h>
+
+#ifdef X15_MUTEX_PI
+
+#include <kern/rtmutex.h>
+
+struct mutex;
+
+#define mutex_assert_locked(mutex) rtmutex_assert_locked(&(mutex)->rtmutex)
+
+static inline void
+mutex_init(struct mutex *mutex)
+{
+ rtmutex_init(&mutex->rtmutex);
+}
+
+static inline int
+mutex_trylock(struct mutex *mutex)
+{
+ return rtmutex_trylock(&mutex->rtmutex);
+}
+
+static inline void
+mutex_lock(struct mutex *mutex)
+{
+ rtmutex_lock(&mutex->rtmutex);
+}
+
+static inline void
+mutex_unlock(struct mutex *mutex)
+{
+ rtmutex_unlock(&mutex->rtmutex);
+
+ /*
+ * If this mutex was used along with a condition variable, wake up
+ * a potential pending waiter. This must be done after the mutex is
+ * unlocked so that a higher priority thread can directly acquire it.
+ */
+ thread_wakeup_last_cond();
+}
+
+#else /* X15_MUTEX_PI */
+
#include <kern/assert.h>
#include <kern/error.h>
#include <kern/mutex_i.h>
-#include <kern/mutex_types.h>
#include <kern/thread.h>
struct mutex;
@@ -114,4 +156,6 @@ mutex_unlock(struct mutex *mutex)
thread_wakeup_last_cond();
}
+#endif /* X15_MUTEX_PI */
+
#endif /* _KERN_MUTEX_H */
diff --git a/kern/mutex_i.h b/kern/mutex_i.h
index a161b1bb..158d8f7f 100644
--- a/kern/mutex_i.h
+++ b/kern/mutex_i.h
@@ -18,6 +18,8 @@
#ifndef _KERN_MUTEX_I_H
#define _KERN_MUTEX_I_H
+#ifndef X15_MUTEX_PI
+
#include <kern/assert.h>
#include <kern/mutex_types.h>
#include <machine/atomic.h>
@@ -46,5 +48,6 @@ void mutex_lock_slow(struct mutex *mutex);
void mutex_unlock_slow(struct mutex *mutex);
+#endif /* X15_MUTEX_PI */
#endif /* _KERN_MUTEX_I_H */
diff --git a/kern/mutex_types.h b/kern/mutex_types.h
index e3126b10..4b7947fc 100644
--- a/kern/mutex_types.h
+++ b/kern/mutex_types.h
@@ -21,8 +21,24 @@
#ifndef _KERN_MUTEX_TYPES_H
#define _KERN_MUTEX_TYPES_H
+#ifdef X15_MUTEX_PI
+
+#include <kern/rtmutex_types.h>
+
+/*
+ * Do not directly alias rtmutex to make sure they cannot be used
+ * with condition variables by mistake.
+ */
+struct mutex {
+ struct rtmutex rtmutex;
+};
+
+#else /* X15_MUTEX_PI */
+
struct mutex {
unsigned int state;
};
+#endif /* X15_MUTEX_PI */
+
#endif /* _KERN_MUTEX_TYPES_H */