shm: add memfd_create() syscall
[deliverable/linux.git] / kernel / locking / rwsem.c
CommitLineData
c4e05116
IM
1/* kernel/rwsem.c: R/W semaphores, public implementation
2 *
3 * Written by David Howells (dhowells@redhat.com).
4 * Derived from asm-i386/semaphore.h
5 */
6
7#include <linux/types.h>
8#include <linux/kernel.h>
c7af77b5 9#include <linux/sched.h>
9984de1a 10#include <linux/export.h>
c4e05116
IM
11#include <linux/rwsem.h>
12
60063497 13#include <linux/atomic.h>
c4e05116 14
5db6c6fe 15#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
4fc828e2
DB
16static inline void rwsem_set_owner(struct rw_semaphore *sem)
17{
18 sem->owner = current;
19}
20
21static inline void rwsem_clear_owner(struct rw_semaphore *sem)
22{
23 sem->owner = NULL;
24}
25
26#else
27static inline void rwsem_set_owner(struct rw_semaphore *sem)
28{
29}
30
31static inline void rwsem_clear_owner(struct rw_semaphore *sem)
32{
33}
34#endif
35
c4e05116
IM
36/*
37 * lock for reading
38 */
c7af77b5 39void __sched down_read(struct rw_semaphore *sem)
c4e05116
IM
40{
41 might_sleep();
42 rwsem_acquire_read(&sem->dep_map, 0, 0, _RET_IP_);
43
4fe87745 44 LOCK_CONTENDED(sem, __down_read_trylock, __down_read);
c4e05116
IM
45}
46
47EXPORT_SYMBOL(down_read);
48
49/*
50 * trylock for reading -- returns 1 if successful, 0 if contention
51 */
52int down_read_trylock(struct rw_semaphore *sem)
53{
54 int ret = __down_read_trylock(sem);
55
56 if (ret == 1)
57 rwsem_acquire_read(&sem->dep_map, 0, 1, _RET_IP_);
58 return ret;
59}
60
61EXPORT_SYMBOL(down_read_trylock);
62
63/*
64 * lock for writing
65 */
c7af77b5 66void __sched down_write(struct rw_semaphore *sem)
c4e05116
IM
67{
68 might_sleep();
69 rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_);
70
4fe87745 71 LOCK_CONTENDED(sem, __down_write_trylock, __down_write);
4fc828e2 72 rwsem_set_owner(sem);
c4e05116
IM
73}
74
75EXPORT_SYMBOL(down_write);
76
77/*
78 * trylock for writing -- returns 1 if successful, 0 if contention
79 */
80int down_write_trylock(struct rw_semaphore *sem)
81{
82 int ret = __down_write_trylock(sem);
83
4fc828e2 84 if (ret == 1) {
428e6ce0 85 rwsem_acquire(&sem->dep_map, 0, 1, _RET_IP_);
4fc828e2
DB
86 rwsem_set_owner(sem);
87 }
88
c4e05116
IM
89 return ret;
90}
91
92EXPORT_SYMBOL(down_write_trylock);
93
94/*
95 * release a read lock
96 */
97void up_read(struct rw_semaphore *sem)
98{
99 rwsem_release(&sem->dep_map, 1, _RET_IP_);
100
101 __up_read(sem);
102}
103
104EXPORT_SYMBOL(up_read);
105
106/*
107 * release a write lock
108 */
109void up_write(struct rw_semaphore *sem)
110{
111 rwsem_release(&sem->dep_map, 1, _RET_IP_);
112
4fc828e2 113 rwsem_clear_owner(sem);
c4e05116
IM
114 __up_write(sem);
115}
116
117EXPORT_SYMBOL(up_write);
118
119/*
120 * downgrade write lock to read lock
121 */
122void downgrade_write(struct rw_semaphore *sem)
123{
124 /*
125 * lockdep: a downgraded write will live on as a write
126 * dependency.
127 */
4fc828e2 128 rwsem_clear_owner(sem);
c4e05116
IM
129 __downgrade_write(sem);
130}
131
132EXPORT_SYMBOL(downgrade_write);
4ea2176d
IM
133
134#ifdef CONFIG_DEBUG_LOCK_ALLOC
135
136void down_read_nested(struct rw_semaphore *sem, int subclass)
137{
138 might_sleep();
139 rwsem_acquire_read(&sem->dep_map, subclass, 0, _RET_IP_);
140
4fe87745 141 LOCK_CONTENDED(sem, __down_read_trylock, __down_read);
4ea2176d
IM
142}
143
144EXPORT_SYMBOL(down_read_nested);
145
1b963c81
JK
146void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map *nest)
147{
148 might_sleep();
149 rwsem_acquire_nest(&sem->dep_map, 0, 0, nest, _RET_IP_);
150
151 LOCK_CONTENDED(sem, __down_write_trylock, __down_write);
4fc828e2 152 rwsem_set_owner(sem);
1b963c81
JK
153}
154
155EXPORT_SYMBOL(_down_write_nest_lock);
156
84759c6d
KO
157void down_read_non_owner(struct rw_semaphore *sem)
158{
159 might_sleep();
160
161 __down_read(sem);
162}
163
164EXPORT_SYMBOL(down_read_non_owner);
165
4ea2176d
IM
166void down_write_nested(struct rw_semaphore *sem, int subclass)
167{
168 might_sleep();
169 rwsem_acquire(&sem->dep_map, subclass, 0, _RET_IP_);
170
4fe87745 171 LOCK_CONTENDED(sem, __down_write_trylock, __down_write);
4fc828e2 172 rwsem_set_owner(sem);
4ea2176d
IM
173}
174
175EXPORT_SYMBOL(down_write_nested);
176
84759c6d
KO
177void up_read_non_owner(struct rw_semaphore *sem)
178{
179 __up_read(sem);
180}
181
182EXPORT_SYMBOL(up_read_non_owner);
183
4ea2176d
IM
184#endif
185
186
This page took 0.556892 seconds and 5 git commands to generate.