1c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* rwsem.h: R/W semaphores, public interface
2c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
3c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Written by David Howells (dhowells@redhat.com).
4c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Derived from asm-i386/semaphore.h
5c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
6c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
7c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef _LINUX_RWSEM_H
8c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define _LINUX_RWSEM_H
9c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
10c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <linux/linkage.h>
11c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
12c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef __KERNEL__
13c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
14c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <linux/types.h>
15c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <linux/kernel.h>
16c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/system.h>
17c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/atomic.h>
18c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
19c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustruct rw_semaphore;
20c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
21c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_RWSEM_GENERIC_SPINLOCK
22c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <linux/rwsem-spinlock.h> /* use a generic implementation */
23c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
24c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/rwsem.h> /* use an arch-specific implementation */
25c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
26c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
27c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
28c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * lock for reading
29c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
30c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void down_read(struct rw_semaphore *sem);
31c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
32c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
33c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * trylock for reading -- returns 1 if successful, 0 if contention
34c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
35c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int down_read_trylock(struct rw_semaphore *sem);
36c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
37c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
38c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * lock for writing
39c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
40c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void down_write(struct rw_semaphore *sem);
41c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
42c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
43c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * trylock for writing -- returns 1 if successful, 0 if contention
44c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
45c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int down_write_trylock(struct rw_semaphore *sem);
46c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
47c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
48c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * release a read lock
49c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
50c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void up_read(struct rw_semaphore *sem);
51c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
52c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
53c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * release a write lock
54c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
55c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void up_write(struct rw_semaphore *sem);
56c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
57c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
58c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * downgrade write lock to read lock
59c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
60c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void downgrade_write(struct rw_semaphore *sem);
61c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
62c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_DEBUG_LOCK_ALLOC
63c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
64c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * nested locking. NOTE: rwsems are not allowed to recurse
65c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * (which occurs if the same task tries to acquire the same
66c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * lock instance multiple times), but multiple locks of the
67c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * same lock class might be taken, if the order of the locks
68c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * is always the same. This ordering rule can be expressed
69c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * to lockdep via the _nested() APIs, but enumerating the
70c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * subclasses that are used. (If the nesting relationship is
71c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * static then another method for expressing nested locking is
72c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * the explicit definition of lock class keys and the use of
73c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * lockdep_set_class() at lock initialization time.
74c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * See Documentation/lockdep-design.txt for more details.)
75c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
76c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void down_read_nested(struct rw_semaphore *sem, int subclass);
77c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void down_write_nested(struct rw_semaphore *sem, int subclass);
78c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
79c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Take/release a lock when not the owner will release it.
80c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
81c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * [ This API should be avoided as much as possible - the
82c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *   proper abstraction for this case is completions. ]
83c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
84c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void down_read_non_owner(struct rw_semaphore *sem);
85c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void up_read_non_owner(struct rw_semaphore *sem);
86c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
87c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define down_read_nested(sem, subclass)		down_read(sem)
88c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define down_write_nested(sem, subclass)	down_write(sem)
89c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define down_read_non_owner(sem)		down_read(sem)
90c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru# define up_read_non_owner(sem)			up_read(sem)
91c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
92c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
93c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* __KERNEL__ */
94c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* _LINUX_RWSEM_H */
95