123f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar/*
223f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar * RT Mutexes: blocking mutual exclusion locks with PI support
323f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar *
423f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar * started by Ingo Molnar and Thomas Gleixner:
523f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar *
623f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar *  Copyright (C) 2004-2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
723f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar *  Copyright (C) 2006, Timesys Corp., Thomas Gleixner <tglx@timesys.com>
823f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar *
923f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar * This file contains the public data structure and API definitions.
1023f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar */
1123f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar
1223f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar#ifndef __LINUX_RT_MUTEX_H
1323f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar#define __LINUX_RT_MUTEX_H
1423f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar
1523f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar#include <linux/linkage.h>
1623f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar#include <linux/plist.h>
1723f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar#include <linux/spinlock_types.h>
1823f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar
194f0e056fdebc15d3f4724ebc7bbf323158add1d7Dave Youngextern int max_lock_depth; /* for sysctl */
204f0e056fdebc15d3f4724ebc7bbf323158add1d7Dave Young
2145f8bde0d0d6deb168b45998c72b4fbeb2f57efbRobert P. J. Day/**
2223f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar * The rt_mutex structure
2323f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar *
2423f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar * @wait_lock:	spinlock to protect the structure
2523f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar * @wait_list:	pilist head to enqueue waiters in priority order
2623f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar * @owner:	the mutex owner
2723f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar */
2823f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnarstruct rt_mutex {
29d209d74d52ab39dc071656533cac095294f70de7Thomas Gleixner	raw_spinlock_t		wait_lock;
3023f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar	struct plist_head	wait_list;
3123f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar	struct task_struct	*owner;
3223f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar#ifdef CONFIG_DEBUG_RT_MUTEXES
3323f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar	int			save_state;
3423f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar	const char 		*name, *file;
3523f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar	int			line;
3623f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar	void			*magic;
3723f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar#endif
3823f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar};
3923f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar
4023f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnarstruct rt_mutex_waiter;
4123f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnarstruct hrtimer_sleeper;
4223f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar
4323f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar#ifdef CONFIG_DEBUG_RT_MUTEXES
44e7eebaf6a81b956c989f184ee4b27277c88f8afeIngo Molnar extern int rt_mutex_debug_check_no_locks_freed(const void *from,
45e7eebaf6a81b956c989f184ee4b27277c88f8afeIngo Molnar						unsigned long len);
46e7eebaf6a81b956c989f184ee4b27277c88f8afeIngo Molnar extern void rt_mutex_debug_check_no_locks_held(struct task_struct *task);
47e7eebaf6a81b956c989f184ee4b27277c88f8afeIngo Molnar#else
48e7eebaf6a81b956c989f184ee4b27277c88f8afeIngo Molnar static inline int rt_mutex_debug_check_no_locks_freed(const void *from,
49e7eebaf6a81b956c989f184ee4b27277c88f8afeIngo Molnar						       unsigned long len)
50e7eebaf6a81b956c989f184ee4b27277c88f8afeIngo Molnar {
51e7eebaf6a81b956c989f184ee4b27277c88f8afeIngo Molnar	return 0;
52e7eebaf6a81b956c989f184ee4b27277c88f8afeIngo Molnar }
53e7eebaf6a81b956c989f184ee4b27277c88f8afeIngo Molnar# define rt_mutex_debug_check_no_locks_held(task)	do { } while (0)
54e7eebaf6a81b956c989f184ee4b27277c88f8afeIngo Molnar#endif
55e7eebaf6a81b956c989f184ee4b27277c88f8afeIngo Molnar
56e7eebaf6a81b956c989f184ee4b27277c88f8afeIngo Molnar#ifdef CONFIG_DEBUG_RT_MUTEXES
5723f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar# define __DEBUG_RT_MUTEX_INITIALIZER(mutexname) \
5823f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar	, .name = #mutexname, .file = __FILE__, .line = __LINE__
59d5c003b4d1690e666dbab02bc8e705947baa848cHarvey Harrison# define rt_mutex_init(mutex)			__rt_mutex_init(mutex, __func__)
6023f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar extern void rt_mutex_debug_task_free(struct task_struct *tsk);
6123f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar#else
6223f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar# define __DEBUG_RT_MUTEX_INITIALIZER(mutexname)
6323f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar# define rt_mutex_init(mutex)			__rt_mutex_init(mutex, NULL)
64e7eebaf6a81b956c989f184ee4b27277c88f8afeIngo Molnar# define rt_mutex_debug_task_free(t)			do { } while (0)
6523f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar#endif
6623f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar
6723f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar#define __RT_MUTEX_INITIALIZER(mutexname) \
68d209d74d52ab39dc071656533cac095294f70de7Thomas Gleixner	{ .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \
69732375c6a5a4cc825b676c922d547aba96b8ce15Dima Zavin	, .wait_list = PLIST_HEAD_INIT(mutexname.wait_list) \
7023f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar	, .owner = NULL \
7123f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar	__DEBUG_RT_MUTEX_INITIALIZER(mutexname)}
7223f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar
7323f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar#define DEFINE_RT_MUTEX(mutexname) \
7423f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar	struct rt_mutex mutexname = __RT_MUTEX_INITIALIZER(mutexname)
7523f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar
7645f8bde0d0d6deb168b45998c72b4fbeb2f57efbRobert P. J. Day/**
7723f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar * rt_mutex_is_locked - is the mutex locked
7823f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar * @lock: the mutex to be queried
7923f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar *
8023f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar * Returns 1 if the mutex is locked, 0 if unlocked.
8123f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar */
8223f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnarstatic inline int rt_mutex_is_locked(struct rt_mutex *lock)
8323f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar{
8423f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar	return lock->owner != NULL;
8523f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar}
8623f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar
8723f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnarextern void __rt_mutex_init(struct rt_mutex *lock, const char *name);
8823f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnarextern void rt_mutex_destroy(struct rt_mutex *lock);
8923f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar
9023f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnarextern void rt_mutex_lock(struct rt_mutex *lock);
9123f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnarextern int rt_mutex_lock_interruptible(struct rt_mutex *lock,
9223f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar						int detect_deadlock);
9323f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnarextern int rt_mutex_timed_lock(struct rt_mutex *lock,
9423f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar					struct hrtimer_sleeper *timeout,
9523f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar					int detect_deadlock);
9623f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar
9723f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnarextern int rt_mutex_trylock(struct rt_mutex *lock);
9823f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar
9923f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnarextern void rt_mutex_unlock(struct rt_mutex *lock);
10023f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar
10123f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar#ifdef CONFIG_RT_MUTEXES
10223f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar# define INIT_RT_MUTEXES(tsk)						\
103732375c6a5a4cc825b676c922d547aba96b8ce15Dima Zavin	.pi_waiters	= PLIST_HEAD_INIT(tsk.pi_waiters),	\
10423f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar	INIT_RT_MUTEX_DEBUG(tsk)
10523f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar#else
10623f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar# define INIT_RT_MUTEXES(tsk)
10723f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar#endif
10823f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar
10923f78d4a03c53cbd75d87a795378ea540aa08c86Ingo Molnar#endif
110