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
12struct refcnt {
13	int32	r_refs;
14};
15
16
17#define REFCNT_INITIALIZER()		{ .r_refs = 1 }
18
19
20static void
21refcnt_init(struct refcnt* r)
22{
23	atomic_set(&r->r_refs, 1);
24}
25
26static void
27refcnt_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
36static int
37refcnt_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
48static void
49refcnt_rele_wake(struct refcnt* r)
50{
51	if (refcnt_rele(r))
52		wakeup_one(r);
53}
54
55static void
56refcnt_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