blob: 4423baa8237efeca79818897c9205ee788c2eec6 [file] [log] [blame]
Nicholas Flintham1e3d3112013-04-10 10:48:38 +01001/*
2 * Mutexes: blocking mutual exclusion locks
3 *
4 * started by Ingo Molnar:
5 *
6 * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
7 *
8 * This file contains the main data structure and API definitions.
9 */
10#ifndef __LINUX_MUTEX_H
11#define __LINUX_MUTEX_H
12
13#include <linux/list.h>
14#include <linux/spinlock_types.h>
15#include <linux/linkage.h>
16#include <linux/lockdep.h>
17
18#include <linux/atomic.h>
19
20struct mutex {
21
22 atomic_t count;
23 spinlock_t wait_lock;
24 struct list_head wait_list;
25#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)
26 struct task_struct *owner;
27#endif
28#ifdef CONFIG_DEBUG_MUTEXES
29 const char *name;
30 void *magic;
31#endif
32#ifdef CONFIG_DEBUG_LOCK_ALLOC
33 struct lockdep_map dep_map;
34#endif
35};
36
37struct mutex_waiter {
38 struct list_head list;
39 struct task_struct *task;
40#ifdef CONFIG_DEBUG_MUTEXES
41 void *magic;
42#endif
43};
44
45#ifdef CONFIG_DEBUG_MUTEXES
46# include <linux/mutex-debug.h>
47#else
48# define __DEBUG_MUTEX_INITIALIZER(lockname)
49# define mutex_init(mutex) \
50do { \
51 static struct lock_class_key __key; \
52 \
53 __mutex_init((mutex), #mutex, &__key); \
54} while (0)
55static inline void mutex_destroy(struct mutex *lock) {}
56#endif
57
58#ifdef CONFIG_DEBUG_LOCK_ALLOC
59# define __DEP_MAP_MUTEX_INITIALIZER(lockname) \
60 , .dep_map = { .name = #lockname }
61#else
62# define __DEP_MAP_MUTEX_INITIALIZER(lockname)
63#endif
64
65#define __MUTEX_INITIALIZER(lockname) \
66 { .count = ATOMIC_INIT(1) \
67 , .wait_lock = __SPIN_LOCK_UNLOCKED(lockname.wait_lock) \
68 , .wait_list = LIST_HEAD_INIT(lockname.wait_list) \
69 __DEBUG_MUTEX_INITIALIZER(lockname) \
70 __DEP_MAP_MUTEX_INITIALIZER(lockname) }
71
72#define DEFINE_MUTEX(mutexname) \
73 struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
74
75extern void __mutex_init(struct mutex *lock, const char *name,
76 struct lock_class_key *key);
77
78static inline int mutex_is_locked(struct mutex *lock)
79{
80 return atomic_read(&lock->count) != 1;
81}
82
83#ifdef CONFIG_DEBUG_LOCK_ALLOC
84extern void mutex_lock_nested(struct mutex *lock, unsigned int subclass);
85extern void _mutex_lock_nest_lock(struct mutex *lock, struct lockdep_map *nest_lock);
86extern int __must_check mutex_lock_interruptible_nested(struct mutex *lock,
87 unsigned int subclass);
88extern int __must_check mutex_lock_killable_nested(struct mutex *lock,
89 unsigned int subclass);
90
91#define mutex_lock(lock) mutex_lock_nested(lock, 0)
92#define mutex_lock_interruptible(lock) mutex_lock_interruptible_nested(lock, 0)
93#define mutex_lock_killable(lock) mutex_lock_killable_nested(lock, 0)
94
95#define mutex_lock_nest_lock(lock, nest_lock) \
96do { \
97 typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \
98 _mutex_lock_nest_lock(lock, &(nest_lock)->dep_map); \
99} while (0)
100
101#else
102extern void mutex_lock(struct mutex *lock);
103extern int __must_check mutex_lock_interruptible(struct mutex *lock);
104extern int __must_check mutex_lock_killable(struct mutex *lock);
105
106# define mutex_lock_nested(lock, subclass) mutex_lock(lock)
107# define mutex_lock_interruptible_nested(lock, subclass) mutex_lock_interruptible(lock)
108# define mutex_lock_killable_nested(lock, subclass) mutex_lock_killable(lock)
109# define mutex_lock_nest_lock(lock, nest_lock) mutex_lock(lock)
110#endif
111
112extern int mutex_trylock(struct mutex *lock);
113extern void mutex_unlock(struct mutex *lock);
114extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock);
115
116#ifndef CONFIG_HAVE_ARCH_MUTEX_CPU_RELAX
117#define arch_mutex_cpu_relax() cpu_relax()
118#endif
119
120#endif