1 /*
2 * Copyright 2022, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5 #ifndef _OBSD_COMPAT_SYS_REFCNT_H_
6 #define _OBSD_COMPAT_SYS_REFCNT_H_
7
8
9 #include <sys/systm.h>
10
11
12 struct refcnt {
13 int32 r_refs;
14 };
15
16
17 #define REFCNT_INITIALIZER() { .r_refs = 1 }
18
19
20 static void
refcnt_init(struct refcnt * r)21 refcnt_init(struct refcnt* r)
22 {
23 atomic_set(&r->r_refs, 1);
24 }
25
26 static void
refcnt_take(struct refcnt * r)27 refcnt_take(struct refcnt* r)
28 {
29 int32 refs;
30
31 refs = atomic_add(&r->r_refs, 1);
32 KASSERT(refs != 0);
33 (void)refs;
34 }
35
36 static int
refcnt_rele(struct refcnt * r)37 refcnt_rele(struct refcnt* r)
38 {
39 int32 refs;
40
41 refs = atomic_add(&r->r_refs, -1) - 1;
42 KASSERT(refs >= 0);
43 if (refs == 0)
44 return 1;
45 return 0;
46 }
47
48 static void
refcnt_rele_wake(struct refcnt * r)49 refcnt_rele_wake(struct refcnt* r)
50 {
51 if (refcnt_rele(r))
52 wakeup_one(r);
53 }
54
55 static void
refcnt_finalize(struct refcnt * r,const char * wmesg)56 refcnt_finalize(struct refcnt* r, const char* wmesg)
57 {
58 refcnt_rele(r);
59 while (r->r_refs > 0)
60 tsleep(r, PWAIT, wmesg, 0);
61 }
62
63
64 #endif /* _OBSD_COMPAT_SYS_REFCNT_H_ */
65