xref: /haiku/src/libs/compat/openbsd_network/compat/sys/refcnt.h (revision 97f11716bfaa0f385eb0e28a52bf56a5023b9e99)
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