This source file includes following definitions.
- __mp_lock_init
- __mp_lock
- __mp_lock_try
- __mp_unlock
- __mp_release_all
- __mp_release_all_but_one
- __mp_acquire_count
- __mp_lock_held
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 #ifndef _MPLOCK_H_
28 #define _MPLOCK_H_
29
30
31
32
33
34
35 struct __mp_lock {
36 __cpu_simple_lock_t mpl_lock;
37 cpuid_t mpl_cpu;
38 int mpl_count;
39 };
40
41 static __inline void __mp_lock_init(struct __mp_lock *);
42 static __inline void __mp_lock(struct __mp_lock *);
43 static __inline void __mp_unlock(struct __mp_lock *);
44 static __inline int __mp_release_all(struct __mp_lock *);
45 static __inline void __mp_acquire_count(struct __mp_lock *, int);
46 static __inline int __mp_lock_held(struct __mp_lock *);
47
48
49
50
51 #define SIMPLELOCK __mp_lock
52 #define SIMPLE_LOCK_INIT __mp_lock_init
53 #define SIMPLE_LOCK __mp_lock
54 #define SIMPLE_UNLOCK __mp_unlock
55
56 static __inline void
57 __mp_lock_init(struct __mp_lock *lock)
58 {
59 __cpu_simple_lock_init(&lock->mpl_lock);
60 lock->mpl_cpu = LK_NOCPU;
61 lock->mpl_count = 0;
62 }
63
64 #if defined(MP_LOCKDEBUG)
65 #ifndef DDB
66 #error "MP_LOCKDEBUG requires DDB"
67 #endif
68
69 extern void Debugger(void);
70 extern int db_printf(const char *, ...)
71 __attribute__((__format__(__kprintf__,1,2)));
72
73
74 extern int __mp_lock_spinout;
75 #endif
76
77 static __inline void
78 __mp_lock(struct __mp_lock *lock)
79 {
80 int s = spllock();
81
82 if (lock->mpl_cpu != cpu_number()) {
83 #ifndef MP_LOCKDEBUG
84 __cpu_simple_lock(&lock->mpl_lock);
85 #else
86 {
87 int got_it;
88 do {
89 int ticks = __mp_lock_spinout;
90
91 do {
92 got_it = __cpu_simple_lock_try(
93 &lock->mpl_lock);
94 } while (!got_it && ticks-- > 0);
95 if (!got_it) {
96 db_printf(
97 "__mp_lock(0x%x): lock spun out",
98 lock);
99 Debugger();
100 }
101 } while (!got_it);
102 }
103 #endif
104 lock->mpl_cpu = cpu_number();
105 }
106 lock->mpl_count++;
107 splx(s);
108 }
109
110
111
112
113
114 static __inline int
115 __mp_lock_try(struct __mp_lock *lock, cpuid_t *cpu)
116 {
117 int s = spllock();
118
119 if (lock->mpl_cpu != cpu_number()) {
120 if (!__cpu_simple_lock_try(&lock->mpl_lock)) {
121 *cpu = lock->mpl_cpu;
122 splx(s);
123 return 0;
124 }
125 lock->mpl_cpu = cpu_number();
126 }
127 lock->mpl_count++;
128 splx(s);
129 return 1;
130 }
131
132 static __inline void
133 __mp_unlock(struct __mp_lock *lock)
134 {
135 int s = spllock();
136
137 #ifdef MP_LOCKDEBUG
138 if (lock->mpl_count == 0 || lock->mpl_cpu == LK_NOCPU) {
139 db_printf("__mp_unlock(0x%x): releasing not locked lock\n",
140 lock);
141 Debugger();
142 }
143 #endif
144
145 if (--lock->mpl_count == 0) {
146 lock->mpl_cpu = LK_NOCPU;
147 __cpu_simple_unlock(&lock->mpl_lock);
148 }
149 splx(s);
150 }
151
152 static __inline int
153 __mp_release_all(struct __mp_lock *lock) {
154 int s = spllock();
155 int rv = lock->mpl_count;
156
157 #ifdef MP_LOCKDEBUG
158 if (lock->mpl_count == 0 || lock->mpl_cpu == LK_NOCPU) {
159 db_printf(
160 "__mp_release_all(0x%x): releasing not locked lock\n",
161 lock);
162 Debugger();
163 }
164 #endif
165
166 lock->mpl_cpu = LK_NOCPU;
167 lock->mpl_count = 0;
168 __cpu_simple_unlock(&lock->mpl_lock);
169 splx(s);
170 return (rv);
171 }
172
173 static __inline int
174 __mp_release_all_but_one(struct __mp_lock *lock) {
175 int s = spllock();
176 int rv = lock->mpl_count - 1;
177
178 #ifdef MP_LOCKDEBUG
179 if (lock->mpl_count == 0 || lock->mpl_cpu == LK_NOCPU) {
180 db_printf(
181 "__mp_release_all_but_one(0x%x): releasing not locked lock\n",
182 lock);
183 Debugger();
184 }
185 #endif
186
187 lock->mpl_count = 1;
188 splx(s);
189 return (rv);
190 }
191
192 static __inline void
193 __mp_acquire_count(struct __mp_lock *lock, int count) {
194 int s = spllock();
195
196 while (count--)
197 __mp_lock(lock);
198 splx(s);
199 }
200
201 static __inline int
202 __mp_lock_held(struct __mp_lock *lock) {
203 return lock->mpl_count && lock->mpl_cpu == cpu_number();
204 }
205
206 extern struct __mp_lock kernel_lock;
207
208 #endif