diff options
author | Richard Braun <rbraun@sceen.net> | 2017-03-04 16:21:57 +0100 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2017-03-04 16:52:30 +0100 |
commit | 3fcd23576e800ebbfb1378c2e6aff2e9e1027989 (patch) | |
tree | 023c4230e8ff225e967a4213421a973fa4dea88d /kern/rtmutex.h | |
parent | 3ae5551b3368b16ddbc1441710e1f272b1c0ad22 (diff) |
kern/rtmutex: new module
The rtmutex provides real-time mutexes, i.e. mutexes for which priority
inheritance is unconditionally enabled.
Diffstat (limited to 'kern/rtmutex.h')
-rw-r--r-- | kern/rtmutex.h | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/kern/rtmutex.h b/kern/rtmutex.h new file mode 100644 index 00000000..f7cee716 --- /dev/null +++ b/kern/rtmutex.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2017 Richard Braun. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * + * Real-time mutual exclusion locks. + * + * A real-time mutex is similar to a regular mutex, except priority + * inheritance is unconditionnally enabled. + */ + +#ifndef _KERN_RTMUTEX_H +#define _KERN_RTMUTEX_H + +#include <stdint.h> + +#include <kern/assert.h> +#include <kern/error.h> +#include <kern/rtmutex_i.h> +#include <kern/rtmutex_types.h> + +struct rtmutex; + +#define rtmutex_assert_locked(rtmutex) assert((rtmutex)->owner != 0) + +/* + * Initialize a real-time mutex. + */ +static inline void +rtmutex_init(struct rtmutex *rtmutex) +{ + rtmutex->owner = 0; +} + +/* + * Attempt to lock the given real-time mutex. + * + * This function may not sleep. + * + * Return 0 on success, ERROR_BUSY if the mutex is already locked. + */ +static inline int +rtmutex_trylock(struct rtmutex *rtmutex) +{ + uintptr_t prev_owner; + + prev_owner = rtmutex_tryacquire(rtmutex); + + if (prev_owner == 0) { + return 0; + } + + return ERROR_BUSY; +} + +/* + * Lock a real-time mutex. + * + * If the mutex is already locked, the calling thread sleeps until the + * mutex is unlocked, and its priority is propagated as needed to prevent + * unbounded priority inversion. + * + * A mutex can only be locked once. + */ +static inline void +rtmutex_lock(struct rtmutex *rtmutex) +{ + uintptr_t prev_owner; + + prev_owner = rtmutex_tryacquire(rtmutex); + + if (prev_owner == 0) { + return; + } + + rtmutex_lock_slow(rtmutex); +} + +/* + * Unlock a real-time mutex. + * + * The mutex must be locked, and must have been locked by the calling + * thread. + */ +static inline void +rtmutex_unlock(struct rtmutex *rtmutex) +{ + uintptr_t prev_owner; + + prev_owner = rtmutex_tryrelease(rtmutex); + + if (!(prev_owner & RTMUTEX_CONTENDED)) { + return; + } + + rtmutex_unlock_slow(rtmutex); +} + +#endif /* _KERN_RTMUTEX_H */ |