2 * Provides a fast serialization facility that will serialize across blocking
3 * conditions. This facility is very similar to a lock but much faster for
4 * the common case. It utilizes the atomic_intr_*() functions to acquire
5 * and release the serializer and token functions to block.
7 * This API is designed to be used whenever low level serialization is
8 * required. Unlike tokens this serialization is not safe from deadlocks
9 * nor is it recursive, and care must be taken when using it.
11 * $DragonFly: src/sys/sys/serialize.h,v 1.9 2008/05/14 11:59:24 sephe Exp $
14 #ifndef _SYS_SERIALIZE_H_
15 #define _SYS_SERIALIZE_H_
18 #error "kernel only header file"
22 #include <sys/param.h>
26 #include <sys/systm.h>
29 #ifndef _MACHINE_STDINT_H_
30 #include <machine/stdint.h>
35 struct lwkt_serialize {
36 __atomic_intr_t interlock;
37 struct thread *last_td;
38 unsigned int sleep_cnt;
39 unsigned int tryfail_cnt;
40 unsigned int enter_cnt;
46 * Note that last_td is only maintained when INVARIANTS is turned on,
47 * so this check is only useful as part of a [K]KASSERT.
49 #define IS_SERIALIZED(ss) ((ss)->last_td == curthread)
52 #define ASSERT_SERIALIZED(ss) KKASSERT(IS_SERIALIZED((ss)))
53 #define ASSERT_NOT_SERIALIZED(ss) KKASSERT(!IS_SERIALIZED((ss)))
55 typedef struct lwkt_serialize *lwkt_serialize_t;
57 void lwkt_serialize_init(lwkt_serialize_t);
58 void lwkt_serialize_enter(lwkt_serialize_t);
60 void lwkt_serialize_adaptive_enter(lwkt_serialize_t);
62 int lwkt_serialize_try(lwkt_serialize_t);
63 void lwkt_serialize_exit(lwkt_serialize_t);
64 void lwkt_serialize_handler_disable(lwkt_serialize_t);
65 void lwkt_serialize_handler_enable(lwkt_serialize_t);
66 void lwkt_serialize_handler_call(lwkt_serialize_t, void (*)(void *, void *), void *, void *);
67 int lwkt_serialize_handler_try(lwkt_serialize_t, void (*)(void *, void *), void *, void *);
70 lwkt_serialize_array_enter(lwkt_serialize_t *_arr, int _arrcnt, int _s)
72 KASSERT(_s < _arrcnt, ("nothing to be serialized\n"));
74 lwkt_serialize_enter(_arr[_s++]);
78 lwkt_serialize_array_try(lwkt_serialize_t *_arr, int _arrcnt, int _s)
82 KASSERT(_s < _arrcnt, ("nothing to be serialized\n"));
83 for (_i = _s; _i < _arrcnt; ++_i) {
84 if (!lwkt_serialize_try(_arr[_i])) {
86 lwkt_serialize_exit(_arr[_i]);
94 lwkt_serialize_array_exit(lwkt_serialize_t *_arr, int _arrcnt, int _s)
96 KASSERT(_arrcnt > _s, ("nothing to be deserialized\n"));
97 while (--_arrcnt >= _s)
98 lwkt_serialize_exit(_arr[_arrcnt]);
101 #endif /* !_SYS_SERIALIZE_H_ */