xref: /linux/include/linux/rwlock.h (revision f5f4745a7f057b58c9728ee4e2c5d6d79f382fe7)
1  #ifndef __LINUX_RWLOCK_H
2  #define __LINUX_RWLOCK_H
3  
4  #ifndef __LINUX_INSIDE_SPINLOCK_H
5  # error "Please do not include this file directly."
6  #endif
7  
8  /*
9   * rwlock related methods
10   *
11   * split out from spinlock.h
12   *
13   * portions Copyright 2005, Red Hat, Inc., Ingo Molnar
14   * Released under the General Public License (GPL).
15   */
16  
17  #ifdef CONFIG_DEBUG_SPINLOCK
18    extern void __rwlock_init(rwlock_t *lock, const char *name,
19  			    struct lock_class_key *key);
20  # define rwlock_init(lock)					\
21  do {								\
22  	static struct lock_class_key __key;			\
23  								\
24  	__rwlock_init((lock), #lock, &__key);			\
25  } while (0)
26  #else
27  # define rwlock_init(lock)					\
28  	do { *(lock) = __RW_LOCK_UNLOCKED(lock); } while (0)
29  #endif
30  
31  #ifdef CONFIG_DEBUG_SPINLOCK
32   extern void do_raw_read_lock(rwlock_t *lock) __acquires(lock);
33   extern int do_raw_read_trylock(rwlock_t *lock);
34   extern void do_raw_read_unlock(rwlock_t *lock) __releases(lock);
35   extern void do_raw_write_lock(rwlock_t *lock) __acquires(lock);
36   extern int do_raw_write_trylock(rwlock_t *lock);
37   extern void do_raw_write_unlock(rwlock_t *lock) __releases(lock);
38  #else
39  # define do_raw_read_lock(rwlock)	do {__acquire(lock); arch_read_lock(&(rwlock)->raw_lock); } while (0)
40  # define do_raw_read_trylock(rwlock)	arch_read_trylock(&(rwlock)->raw_lock)
41  # define do_raw_read_unlock(rwlock)	do {arch_read_unlock(&(rwlock)->raw_lock); __release(lock); } while (0)
42  # define do_raw_write_lock(rwlock)	do {__acquire(lock); arch_write_lock(&(rwlock)->raw_lock); } while (0)
43  # define do_raw_write_trylock(rwlock)	arch_write_trylock(&(rwlock)->raw_lock)
44  # define do_raw_write_unlock(rwlock)	do {arch_write_unlock(&(rwlock)->raw_lock); __release(lock); } while (0)
45  #endif
46  
47  /*
48   * Define the various rw_lock methods.  Note we define these
49   * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various
50   * methods are defined as nops in the case they are not required.
51   */
52  #define read_trylock(lock)	__cond_lock(lock, _raw_read_trylock(lock))
53  #define write_trylock(lock)	__cond_lock(lock, _raw_write_trylock(lock))
54  
55  #define write_lock(lock)	_raw_write_lock(lock)
56  #define read_lock(lock)		_raw_read_lock(lock)
57  
58  #ifdef CONFIG_DEBUG_LOCK_ALLOC
59  #define write_lock_nested(lock, subclass)	_raw_write_lock_nested(lock, subclass)
60  #else
61  #define write_lock_nested(lock, subclass)	_raw_write_lock(lock)
62  #endif
63  
64  #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
65  
66  #define read_lock_irqsave(lock, flags)			\
67  	do {						\
68  		typecheck(unsigned long, flags);	\
69  		flags = _raw_read_lock_irqsave(lock);	\
70  	} while (0)
71  #define write_lock_irqsave(lock, flags)			\
72  	do {						\
73  		typecheck(unsigned long, flags);	\
74  		flags = _raw_write_lock_irqsave(lock);	\
75  	} while (0)
76  
77  #else
78  
79  #define read_lock_irqsave(lock, flags)			\
80  	do {						\
81  		typecheck(unsigned long, flags);	\
82  		_raw_read_lock_irqsave(lock, flags);	\
83  	} while (0)
84  #define write_lock_irqsave(lock, flags)			\
85  	do {						\
86  		typecheck(unsigned long, flags);	\
87  		_raw_write_lock_irqsave(lock, flags);	\
88  	} while (0)
89  
90  #endif
91  
92  #define read_lock_irq(lock)		_raw_read_lock_irq(lock)
93  #define read_lock_bh(lock)		_raw_read_lock_bh(lock)
94  #define write_lock_irq(lock)		_raw_write_lock_irq(lock)
95  #define write_lock_bh(lock)		_raw_write_lock_bh(lock)
96  #define read_unlock(lock)		_raw_read_unlock(lock)
97  #define write_unlock(lock)		_raw_write_unlock(lock)
98  #define read_unlock_irq(lock)		_raw_read_unlock_irq(lock)
99  #define write_unlock_irq(lock)		_raw_write_unlock_irq(lock)
100  
101  #define read_unlock_irqrestore(lock, flags)			\
102  	do {							\
103  		typecheck(unsigned long, flags);		\
104  		_raw_read_unlock_irqrestore(lock, flags);	\
105  	} while (0)
106  #define read_unlock_bh(lock)		_raw_read_unlock_bh(lock)
107  
108  #define write_unlock_irqrestore(lock, flags)		\
109  	do {						\
110  		typecheck(unsigned long, flags);	\
111  		_raw_write_unlock_irqrestore(lock, flags);	\
112  	} while (0)
113  #define write_unlock_bh(lock)		_raw_write_unlock_bh(lock)
114  
115  #define write_trylock_irqsave(lock, flags) \
116  ({ \
117  	local_irq_save(flags); \
118  	write_trylock(lock) ? \
119  	1 : ({ local_irq_restore(flags); 0; }); \
120  })
121  
122  #ifdef arch_rwlock_is_contended
123  #define rwlock_is_contended(lock) \
124  	 arch_rwlock_is_contended(&(lock)->raw_lock)
125  #else
126  #define rwlock_is_contended(lock)	((void)(lock), 0)
127  #endif /* arch_rwlock_is_contended */
128  
129  #endif /* __LINUX_RWLOCK_H */
130