-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLinux-kernel-locks
More file actions
147 lines (113 loc) · 6.14 KB
/
Linux-kernel-locks
File metadata and controls
147 lines (113 loc) · 6.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
Linux kernel locks quick Reference
This chapter has introduced a substantial set of symbols for the management of concurrency.
The most important of these are summarized here:
1. semaphore:
#include <asm/semaphore.h>
The include file that defines semaphores and the operations on them.
DECLARE_MUTEX(name);
DECLARE_MUTEX_LOCKED(name);
Two macros for declaring and initializing a semaphore used in mutual exclusion mode.
void init_MUTEX(struct semaphore *sem);
void init_MUTEX_LOCKED(struct semaphore *sem);
These two functions can be used to initialize a semaphore at runtime.
void down(struct semaphore *sem);
int down_interruptible(struct semaphore *sem);
int down_trylock(struct semaphore *sem);
void up(struct semaphore *sem);
Lock and unlock a semaphore. down puts the calling process into an uninterruptible sleep if need be; down_interruptible, instead, can be interrupted by a signal. down_trylock does not sleep; instead, it returns immediately if the semaphore is unavailable. Code that locks a semaphore must eventually unlock it with up.
struct rw_semaphore;
init_rwsem(struct rw_semaphore *sem);
The reader/writer version of semaphores and the function that initializes it.
void down_read(struct rw_semaphore *sem);
int down_read_trylock(struct rw_semaphore *sem);
void up_read(struct rw_semaphore *sem);
Functions for obtaining and releasing read access to a reader/writer semaphore.
void down_write(struct rw_semaphore *sem)
int down_write_trylock(struct rw_semaphore *sem)
void up_write(struct rw_semaphore *sem)
void downgrade_write(struct rw_semaphore *sem)
Functions for managing write access to a reader/writer semaphore.
2. completion:
#include <linux/completion.h>
DECLARE_COMPLETION(name);
init_completion(struct completion *c);
INIT_COMPLETION(struct completion c);
The include file describing the Linux completion mechanism, and the normal methods for initializing completions. INIT_COMPLETION should be used only to reinitialize a completion that has been previously used.
void wait_for_completion(struct completion *c);
Wait for a completion event to be signalled.
void complete(struct completion *c);
void complete_all(struct completion *c);
Signal a completion event. complete wakes, at most, one waiting thread, while complete_all wakes all waiters.
void complete_and_exit(struct completion *c, long retval);
Signals a completion event by calling complete and calls exit for the current thread.
3. spinlock:
#include <linux/spinlock.h>
spinlock_t lock = SPIN_LOCK_UNLOCKED;
spin_lock_init(spinlock_t *lock);
The include file defining the spinlock interface and the two ways of initializing locks.
void spin_lock(spinlock_t *lock);
void spin_lock_irqsave(spinlock_t *lock, unsigned long flags);
void spin_lock_irq(spinlock_t *lock);
void spin_lock_bh(spinlock_t *lock);
The various ways of locking a spinlock and, possibly, disabling interrupts.
int spin_trylock(spinlock_t *lock);
int spin_trylock_bh(spinlock_t *lock);
Nonspinning versions of the above functions; these return 0 in case of failure to obtain the lock, nonzero otherwise.
void spin_unlock(spinlock_t *lock);
void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags);
void spin_unlock_irq(spinlock_t *lock);
void spin_unlock_bh(spinlock_t *lock);
The corresponding ways of releasing a spinlock.
4. read write lock:
rwlock_t lock = RW_LOCK_UNLOCKED
rwlock_init(rwlock_t *lock);
The two ways of initializing reader/writer locks.
void read_lock(rwlock_t *lock);
void read_lock_irqsave(rwlock_t *lock, unsigned long flags);
void read_lock_irq(rwlock_t *lock);
void read_lock_bh(rwlock_t *lock);
Functions for obtaining read access to a reader/writer lock.
void read_unlock(rwlock_t *lock);
void read_unlock_irqrestore(rwlock_t *lock, unsigned long flags);
void read_unlock_irq(rwlock_t *lock);
void read_unlock_bh(rwlock_t *lock);
Functions for releasing read access to a reader/writer spinlock.
void write_lock(rwlock_t *lock);
void write_lock_irqsave(rwlock_t *lock, unsigned long flags);
void write_lock_irq(rwlock_t *lock);
void write_lock_bh(rwlock_t *lock);
Functions for obtaining write access to a reader/writer lock.
void write_unlock(rwlock_t *lock);
void write_unlock_irqrestore(rwlock_t *lock, unsigned long flags);
void write_unlock_irq(rwlock_t *lock);
void write_unlock_bh(rwlock_t *lock);
Functions for releasing write access to a reader/writer spinlock.
5. wait queue
/*
* This section is written by dongshan, maybe it is not correct, just according to my own understanding of
* wait queue
*/
A wait queue is used for muti threads synchronisition. It can put a thread into sleep untill the condition
is met, or it received a signal or timeout. Normally, one or more threads are waitting for a condition.
There are two ways to declare a wait queue, satically or dynamically.
static DECLARE_WAIT_QUEUE_HEAD(wq); // statically declare a wait queue.
wait_queue_head_t wq; // dynamiclly decalare a wait queue
init_wait_queue(&wq);
//after initialising a wait queue, then add some wait event onto the queue.
void fastcall add_wait_queue(wait_queue_head_t * wqh, wait_queue_t *wait);
// here, remove this wait queue from wait queue list
void fastcall remove_wait_queue(wait_queue_head_t *wqh, wait_queue_t *wait);
// four macros implete to put threads into sleep
wait_event(wq, condition);
wait_event_interruptible(wq, condition);
wait_event_timeout(wq, condition, timeout);
wait_event_interruptible_timeout(wq, condition, timeout);
These four macros will put threads into wait queue and sleep untill the condition becomes ture, or
timeout meets. if the sleeping thread is intterupted by receiving signals, it returns a nonzero value;
If timeout meets, it return a value 0 regardless of how the condition evaluates.
// to wake up threads which are waitting on the wait queue
void wake_up(wait_queue_head_t *wq);
void wake_up_interruptible(wait_queue_head_t *wq);
// sleep on the wait queue.
sleep_on(wait_queue_t *q); // define a wait queue, then the current task goes to sleep uninterruptible.
interruptbible_sleep_on(wait_queue_head_t *q); // set current task go to sleep, however it can be wake up by interrupt.