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