1#ifndef _X86_64_SEMAPHORE_H
2#define _X86_64_SEMAPHORE_H
3
4#include <linux/linkage.h>
5
6#ifdef __KERNEL__
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#include <asm/system.h>
40#include <asm/atomic.h>
41#include <asm/rwlock.h>
42#include <linux/wait.h>
43#include <linux/rwsem.h>
44#include <linux/stringify.h>
45
46struct semaphore {
47 atomic_t count;
48 int sleepers;
49 wait_queue_head_t wait;
50};
51
52#define __SEMAPHORE_INITIALIZER(name, n) \
53{ \
54 .count = ATOMIC_INIT(n), \
55 .sleepers = 0, \
56 .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
57}
58
59#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
60 struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
61
62#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
63
64static inline void sema_init (struct semaphore *sem, int val)
65{
66
67
68
69
70
71
72 atomic_set(&sem->count, val);
73 sem->sleepers = 0;
74 init_waitqueue_head(&sem->wait);
75}
76
77static inline void init_MUTEX (struct semaphore *sem)
78{
79 sema_init(sem, 1);
80}
81
82static inline void init_MUTEX_LOCKED (struct semaphore *sem)
83{
84 sema_init(sem, 0);
85}
86
87asmlinkage void __down_failed(void );
88asmlinkage int __down_failed_interruptible(void );
89asmlinkage int __down_failed_trylock(void );
90asmlinkage void __up_wakeup(void );
91
92asmlinkage void __down(struct semaphore * sem);
93asmlinkage int __down_interruptible(struct semaphore * sem);
94asmlinkage int __down_trylock(struct semaphore * sem);
95asmlinkage void __up(struct semaphore * sem);
96
97
98
99
100
101
102static inline void down(struct semaphore * sem)
103{
104 might_sleep();
105
106 __asm__ __volatile__(
107 "# atomic down operation\n\t"
108 LOCK_PREFIX "decl %0\n\t"
109 "jns 1f\n\t"
110 "call __down_failed\n"
111 "1:"
112 :"=m" (sem->count)
113 :"D" (sem)
114 :"memory");
115}
116
117
118
119
120
121static inline int down_interruptible(struct semaphore * sem)
122{
123 int result;
124
125 might_sleep();
126
127 __asm__ __volatile__(
128 "# atomic interruptible down operation\n\t"
129 "xorl %0,%0\n\t"
130 LOCK_PREFIX "decl %1\n\t"
131 "jns 2f\n\t"
132 "call __down_failed_interruptible\n"
133 "2:\n"
134 :"=&a" (result), "=m" (sem->count)
135 :"D" (sem)
136 :"memory");
137 return result;
138}
139
140
141
142
143
144static inline int down_trylock(struct semaphore * sem)
145{
146 int result;
147
148 __asm__ __volatile__(
149 "# atomic interruptible down operation\n\t"
150 "xorl %0,%0\n\t"
151 LOCK_PREFIX "decl %1\n\t"
152 "jns 2f\n\t"
153 "call __down_failed_trylock\n\t"
154 "2:\n"
155 :"=&a" (result), "=m" (sem->count)
156 :"D" (sem)
157 :"memory","cc");
158 return result;
159}
160
161
162
163
164
165
166
167static inline void up(struct semaphore * sem)
168{
169 __asm__ __volatile__(
170 "# atomic up operation\n\t"
171 LOCK_PREFIX "incl %0\n\t"
172 "jg 1f\n\t"
173 "call __up_wakeup\n"
174 "1:"
175 :"=m" (sem->count)
176 :"D" (sem)
177 :"memory");
178}
179#endif
180#endif
181