xref: /f-stack/lib/ff_lock.c (revision 22ce4aff)
1 /*
2  * Copyright (c) 2010 Kip Macy. All rights reserved.
3  * Copyright (C) 2017 THL A29 Limited, a Tencent company.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice, this
10  *   list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  *   this list of conditions and the following disclaimer in the documentation
13  *   and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * Derived in part from libplebnet's pn_lock.c.
27  */
28 
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/bus.h>
32 #include <sys/conf.h>
33 #include <sys/kdb.h>
34 #include <sys/kernel.h>
35 #include <sys/ktr.h>
36 #include <sys/lock.h>
37 #include <sys/malloc.h>
38 #include <sys/mutex.h>
39 #include <sys/rmlock.h>
40 #include <sys/rwlock.h>
41 #include <sys/sx.h>
42 #include <sys/proc.h>
43 #include <sys/resourcevar.h>
44 #include <sys/sched.h>
45 #include <sys/sbuf.h>
46 #include <sys/sysctl.h>
47 #include <sys/turnstile.h>
48 #include <sys/vmmeter.h>
49 #include <sys/lock_profile.h>
50 
51 #include "ff_host_interface.h"
52 
53 struct mtx Giant;
54 
55 static void
56 assert_mtx(const struct lock_object *lock, int what)
57 {
58 
59 }
60 
61 static void
62 lock_mtx(struct lock_object *lock, uintptr_t how)
63 {
64 
65 }
66 
67 static uintptr_t
68 unlock_mtx(struct lock_object *lock)
69 {
70     return (0);
71 }
72 
73 /*
74  * Lock classes for sleep and spin mutexes.
75  */
76 struct lock_class lock_class_mtx_sleep = {
77     .lc_name = "sleep mutex",
78     .lc_flags = LC_SLEEPLOCK | LC_RECURSABLE,
79     .lc_assert = assert_mtx,
80     .lc_lock = lock_mtx,
81     .lc_unlock = unlock_mtx,
82 #ifdef DDB
83     .lc_ddb_show = db_show_mtx,
84 #endif
85 #ifdef KDTRACE_HOOKS
86     .lc_owner = owner_mtx,
87 #endif
88 };
89 
90 void
91 ff_mtx_init(struct lock_object *lo, const char *name, const char *type, int opts)
92 {
93     lock_init(lo, &lock_class_mtx_sleep, name, type, opts);
94 }
95 
96 void
97 mtx_sysinit(void *arg)
98 {
99     struct mtx_args *margs = arg;
100     mtx_init((struct mtx *)margs->ma_mtx, margs->ma_desc, NULL, margs->ma_opts);
101 }
102 
103 void _mtx_destroy(volatile uintptr_t *c)
104 {
105 
106 }
107 
108 static void
109 lock_rw(struct lock_object *lock, uintptr_t how)
110 {
111 
112 }
113 
114 static uintptr_t
115 unlock_rw(struct lock_object *lock)
116 {
117     return (0);
118 }
119 
120 #ifdef KDTRACE_HOOKS
121 static int
122 owner_rw(struct lock_object *lock, struct thread **owner)
123 {
124     return 1;//??
125 }
126 #endif
127 
128 
129 static void
130 assert_rw(const struct lock_object *lock, int what)
131 {
132 
133 }
134 
135 struct lock_class lock_class_rw = {
136     .lc_name = "rw",
137     .lc_flags = LC_SLEEPLOCK | LC_RECURSABLE | LC_UPGRADABLE,
138     .lc_assert = assert_rw,
139 #ifdef DDB
140     .lc_ddb_show = db_show_rwlock,
141 #endif
142     .lc_lock = lock_rw,
143     .lc_unlock = unlock_rw,
144 #ifdef KDTRACE_HOOKS
145     .lc_owner = owner_rw,
146 #endif
147 };
148 
149 void
150 rw_sysinit(void *arg)
151 {
152     struct rw_args *args = arg;
153     rw_init((struct rwlock *)args->ra_rw, args->ra_desc);
154 }
155 
156 #if 0
157 void
158 rw_sysinit_flags(void *arg)
159 {
160     rw_sysinit(arg);
161 }
162 #endif
163 
164 void
165 ff_rw_init_flags(struct lock_object *lo, const char *name, int opts)
166 {
167     int flags;
168 
169     MPASS((opts & ~(RW_DUPOK | RW_NOPROFILE | RW_NOWITNESS | RW_QUIET |
170         RW_RECURSE)) == 0);
171 
172     flags = LO_UPGRADABLE;
173     if (opts & RW_DUPOK)
174         flags |= LO_DUPOK;
175     if (opts & RW_NOPROFILE)
176         flags |= LO_NOPROFILE;
177     if (!(opts & RW_NOWITNESS))
178         flags |= LO_WITNESS;
179     if (opts & RW_RECURSE)
180         flags |= LO_RECURSABLE;
181     if (opts & RW_QUIET)
182         flags |= LO_QUIET;
183 
184     lock_init(lo, &lock_class_rw, name, NULL, flags);
185 }
186 
187 void _rw_destroy(volatile uintptr_t *c)
188 {
189 
190 }
191 
192 static void
193 assert_rm(const struct lock_object *lock, int what)
194 {
195 
196 }
197 
198 struct lock_class lock_class_rm = {
199     .lc_name = "rm",
200     .lc_flags = LC_SLEEPLOCK | LC_RECURSABLE,
201     .lc_assert = assert_rm,
202 #if 0
203 #ifdef DDB
204     .lc_ddb_show = db_show_rwlock,
205 #endif
206 #endif
207 #ifdef KDTRACE_HOOKS
208     .lc_owner = owner_rm,
209 #endif
210 };
211 
212 void
213 rm_init(struct rmlock *rm, const char *name)
214 {
215     rm_init_flags(rm, name, 0);
216 }
217 
218 void
219 rm_init_flags(struct rmlock *rm, const char *name, int opts)
220 {
221     int liflags = 0;
222     if (!(opts & RM_NOWITNESS))
223         liflags |= LO_WITNESS;
224     if (opts & RM_RECURSE)
225         liflags |= LO_RECURSABLE;
226 
227     lock_init(&rm->lock_object, &lock_class_rm, name, NULL, liflags);
228 }
229 
230 void
231 rm_sysinit(void *arg)
232 {
233     struct rm_args *args = arg;
234     rm_init((struct rmlock *)args->ra_rm, args->ra_desc);
235 }
236 
237 #if 0
238 void
239 rm_sysinit_flags(void *arg)
240 {
241     rm_sysinit(arg);
242 }
243 #endif
244 
245 void
246 rm_destroy(struct rmlock *rm)
247 {
248 
249 }
250 
251 void
252 _rm_wlock(struct rmlock *rm)
253 {
254 
255 }
256 
257 void
258 _rm_wunlock(struct rmlock *rm)
259 {
260 
261 }
262 
263 int
264 _rm_rlock(struct rmlock *rm, struct rm_priotracker *tracker, int trylock)
265 {
266     return (1);
267 }
268 
269 void
270 _rm_runlock(struct rmlock *rm,  struct rm_priotracker *tracker)
271 {
272 
273 }
274 
275 int
276 rm_wowned(const struct rmlock *rm)
277 {
278     return (1);
279 }
280 
281 struct lock_class lock_class_sx = {
282     .lc_name = "sx",
283     .lc_flags = LC_SLEEPLOCK | LC_SLEEPABLE | LC_RECURSABLE | LC_UPGRADABLE,
284 #ifdef DDB
285     .lc_ddb_show = db_show_sx,
286 #endif
287 #ifdef KDTRACE_HOOKS
288     .lc_owner = owner_sx,
289 #endif
290 };
291 
292 void
293 sx_init_flags(struct sx *sx, const char *description, int opts)
294 {
295     int flags;
296 
297     MPASS((opts & ~(SX_QUIET | SX_RECURSE | SX_NOWITNESS | SX_DUPOK |
298         SX_NOPROFILE | SX_NEW)) == 0);
299 
300     flags = LO_SLEEPABLE | LO_UPGRADABLE;
301     if (opts & SX_DUPOK)
302         flags |= LO_DUPOK;
303     if (opts & SX_NOPROFILE)
304         flags |= LO_NOPROFILE;
305     if (!(opts & SX_NOWITNESS))
306         flags |= LO_WITNESS;
307     if (opts & SX_RECURSE)
308         flags |= LO_RECURSABLE;
309     if (opts & SX_QUIET)
310         flags |= LO_QUIET;
311     if (opts & SX_NEW)
312         flags |= LO_NEW;
313 
314     lock_init(&sx->lock_object, &lock_class_sx, description, NULL, flags);
315     //sx->sx_lock = SX_LOCK_UNLOCKED;
316     //sx->sx_recurse = 0;
317 }
318 
319 void
320 sx_destroy(struct sx *sx)
321 {
322 
323 }
324 
325 int
326 _sx_xlock(struct sx *sx, int opts,
327     const char *file, int line)
328 {
329     return (0);
330 }
331 
332 int
333 _sx_slock(struct sx *sx, int opts, const char *file, int line)
334 {
335     return (0);
336 }
337 
338 void
339 _sx_xunlock(struct sx *sx, const char *file, int line)
340 {
341 
342 }
343 
344 void
345 _sx_sunlock(struct sx *sx, const char *file, int line)
346 {
347 
348 }
349 
350 int
351 sx_try_slock_(struct sx *sx, const char *file, int line)
352 {
353     return 1;
354 }
355 
356 int
357 sx_try_xlock_(struct sx *sx, const char *file, int line)
358 {
359     return 1;
360 }
361 
362 int
363 sx_try_upgrade_(struct sx *sx, const char *file, int line)
364 {
365     return 1;
366 }
367 
368 void
369 sx_downgrade_(struct sx *sx, const char *file, int line)
370 {
371 
372 }
373 
374 void
375 sx_sysinit(void *arg)
376 {
377     struct sx_args *args = arg;
378     sx_init(args->sa_sx, args->sa_desc);
379 }
380 
381 /*
382  * XXX should never be used;
383  */
384 struct lock_class lock_class_lockmgr;
385 
386 static void
387 lock_spin(struct lock_object *lock, uintptr_t how)
388 {
389     printf("%s: called!\n", __func__);
390 }
391 
392 static uintptr_t
393 unlock_spin(struct lock_object *lock)
394 {
395     printf("%s: called!\n", __func__);
396     return (0);
397 }
398 
399 /*
400  * XXX should never be used;
401  */
402 struct lock_class lock_class_mtx_spin = {
403     .lc_name = "spin mutex",
404     .lc_flags = LC_SPINLOCK | LC_RECURSABLE,
405     .lc_assert = assert_mtx,
406     .lc_lock = lock_spin,
407     .lc_unlock = unlock_spin,
408 };
409 
410 /*
411  * These do not support read locks because it would be hard to make
412  * the tracker work correctly with the current lock_class API as you
413  * would need to have the tracker pointer available when calling
414  * rm_rlock() in lock_rm().
415  */
416 static void
417 lock_rm(struct lock_object *lock, uintptr_t how)
418 {
419 
420 }
421 
422 static uintptr_t
423 unlock_rm(struct lock_object *lock)
424 {
425     return (1);
426 }
427 
428 struct lock_class lock_class_rm_sleepable = {
429     .lc_name = "sleepable rm",
430     .lc_flags = LC_SLEEPLOCK | LC_SLEEPABLE | LC_RECURSABLE,
431     .lc_assert = assert_rm,
432 #ifdef DDB
433     .lc_ddb_show = db_show_rm,
434 #endif
435     .lc_lock = lock_rm,
436     .lc_unlock = unlock_rm,
437 #ifdef KDTRACE_HOOKS
438     .lc_owner = owner_rm,
439 #endif
440 };
441 
442 void
443 mutex_init(void)
444 {
445     mtx_init(&Giant, "Giant", NULL, MTX_DEF | MTX_RECURSE);
446     mtx_init(&proc0.p_mtx, "process lock", NULL, MTX_DEF | MTX_DUPOK);
447 }
448 
449