From f4d75d0cd8424c17521d520fd9018ea22b7daaad Mon Sep 17 00:00:00 2001 From: Richard Braun Date: Sat, 4 Mar 2017 16:27:05 +0100 Subject: kern/mutex: implement the --enable-mutex-pi option This option turns all regular mutexes into real-time mutexes. --- INSTALL | 5 +++++ configure.ac | 10 ++++++++++ kern/mutex.c | 4 ++++ kern/mutex.h | 46 +++++++++++++++++++++++++++++++++++++++++++++- kern/mutex_i.h | 3 +++ kern/mutex_types.h | 16 ++++++++++++++++ 6 files changed, 83 insertions(+), 1 deletion(-) 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 ]) 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 . */ +#ifndef X15_MUTEX_PI + #include #include @@ -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 + +#ifdef X15_MUTEX_PI + +#include + +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 #include #include -#include #include 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 #include #include @@ -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 + +/* + * 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 */ -- cgit v1.2.3