]>
Commit | Line | Data |
---|---|---|
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> | |
9 | #include <linux/module.h> | |
10 | #include <linux/rwsem.h> | |
11 | ||
12 | #include <asm/system.h> | |
13 | #include <asm/atomic.h> | |
14 | ||
15 | /* | |
16 | * lock for reading | |
17 | */ | |
18 | void down_read(struct rw_semaphore *sem) | |
19 | { | |
20 | might_sleep(); | |
21 | rwsem_acquire_read(&sem->dep_map, 0, 0, _RET_IP_); | |
22 | ||
23 | __down_read(sem); | |
24 | } | |
25 | ||
26 | EXPORT_SYMBOL(down_read); | |
27 | ||
28 | /* | |
29 | * trylock for reading -- returns 1 if successful, 0 if contention | |
30 | */ | |
31 | int down_read_trylock(struct rw_semaphore *sem) | |
32 | { | |
33 | int ret = __down_read_trylock(sem); | |
34 | ||
35 | if (ret == 1) | |
36 | rwsem_acquire_read(&sem->dep_map, 0, 1, _RET_IP_); | |
37 | return ret; | |
38 | } | |
39 | ||
40 | EXPORT_SYMBOL(down_read_trylock); | |
41 | ||
42 | /* | |
43 | * lock for writing | |
44 | */ | |
45 | void down_write(struct rw_semaphore *sem) | |
46 | { | |
47 | might_sleep(); | |
48 | rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_); | |
49 | ||
50 | __down_write(sem); | |
51 | } | |
52 | ||
53 | EXPORT_SYMBOL(down_write); | |
54 | ||
55 | /* | |
56 | * trylock for writing -- returns 1 if successful, 0 if contention | |
57 | */ | |
58 | int down_write_trylock(struct rw_semaphore *sem) | |
59 | { | |
60 | int ret = __down_write_trylock(sem); | |
61 | ||
62 | if (ret == 1) | |
63 | rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_); | |
64 | return ret; | |
65 | } | |
66 | ||
67 | EXPORT_SYMBOL(down_write_trylock); | |
68 | ||
69 | /* | |
70 | * release a read lock | |
71 | */ | |
72 | void up_read(struct rw_semaphore *sem) | |
73 | { | |
74 | rwsem_release(&sem->dep_map, 1, _RET_IP_); | |
75 | ||
76 | __up_read(sem); | |
77 | } | |
78 | ||
79 | EXPORT_SYMBOL(up_read); | |
80 | ||
81 | /* | |
82 | * release a write lock | |
83 | */ | |
84 | void up_write(struct rw_semaphore *sem) | |
85 | { | |
86 | rwsem_release(&sem->dep_map, 1, _RET_IP_); | |
87 | ||
88 | __up_write(sem); | |
89 | } | |
90 | ||
91 | EXPORT_SYMBOL(up_write); | |
92 | ||
93 | /* | |
94 | * downgrade write lock to read lock | |
95 | */ | |
96 | void downgrade_write(struct rw_semaphore *sem) | |
97 | { | |
98 | /* | |
99 | * lockdep: a downgraded write will live on as a write | |
100 | * dependency. | |
101 | */ | |
102 | __downgrade_write(sem); | |
103 | } | |
104 | ||
105 | EXPORT_SYMBOL(downgrade_write); | |
4ea2176d IM |
106 | |
107 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | |
108 | ||
109 | void down_read_nested(struct rw_semaphore *sem, int subclass) | |
110 | { | |
111 | might_sleep(); | |
112 | rwsem_acquire_read(&sem->dep_map, subclass, 0, _RET_IP_); | |
113 | ||
114 | __down_read(sem); | |
115 | } | |
116 | ||
117 | EXPORT_SYMBOL(down_read_nested); | |
118 | ||
119 | void down_read_non_owner(struct rw_semaphore *sem) | |
120 | { | |
121 | might_sleep(); | |
122 | ||
123 | __down_read(sem); | |
124 | } | |
125 | ||
126 | EXPORT_SYMBOL(down_read_non_owner); | |
127 | ||
128 | void down_write_nested(struct rw_semaphore *sem, int subclass) | |
129 | { | |
130 | might_sleep(); | |
131 | rwsem_acquire(&sem->dep_map, subclass, 0, _RET_IP_); | |
132 | ||
133 | __down_write_nested(sem, subclass); | |
134 | } | |
135 | ||
136 | EXPORT_SYMBOL(down_write_nested); | |
137 | ||
138 | void up_read_non_owner(struct rw_semaphore *sem) | |
139 | { | |
140 | __up_read(sem); | |
141 | } | |
142 | ||
143 | EXPORT_SYMBOL(up_read_non_owner); | |
144 | ||
145 | #endif | |
146 | ||
147 |