xref: /xnu-12377.41.6/libkern/os/refcnt_internal.h (revision bbb1b6f9e71b8cdde6e5cd6f4841f207dee3d828) !
1*bbb1b6f9SApple OSS Distributions #ifndef _OS_REFCNT_INTERNAL_H
2*bbb1b6f9SApple OSS Distributions #define _OS_REFCNT_INTERNAL_H
3*bbb1b6f9SApple OSS Distributions 
4*bbb1b6f9SApple OSS Distributions struct os_refcnt {
5*bbb1b6f9SApple OSS Distributions 	os_ref_atomic_t ref_count;
6*bbb1b6f9SApple OSS Distributions #if OS_REFCNT_DEBUG
7*bbb1b6f9SApple OSS Distributions 	struct os_refgrp *ref_group;
8*bbb1b6f9SApple OSS Distributions #endif
9*bbb1b6f9SApple OSS Distributions };
10*bbb1b6f9SApple OSS Distributions 
11*bbb1b6f9SApple OSS Distributions #if OS_REFCNT_DEBUG
12*bbb1b6f9SApple OSS Distributions 
13*bbb1b6f9SApple OSS Distributions __options_closed_decl(os_refgrp_flags_t, uint64_t, {
14*bbb1b6f9SApple OSS Distributions 	OS_REFGRP_F_NONE           = 0x0,
15*bbb1b6f9SApple OSS Distributions 	OS_REFGRP_F_ALWAYS_ENABLED = 0x1,
16*bbb1b6f9SApple OSS Distributions });
17*bbb1b6f9SApple OSS Distributions 
18*bbb1b6f9SApple OSS Distributions struct os_refgrp {
19*bbb1b6f9SApple OSS Distributions 	const char *grp_name;
20*bbb1b6f9SApple OSS Distributions 	os_ref_atomic_t grp_children;  /* number of refcount objects in group */
21*bbb1b6f9SApple OSS Distributions 	os_ref_atomic_t grp_count;     /* current reference count of group */
22*bbb1b6f9SApple OSS Distributions 	_Atomic uint64_t grp_retain_total;
23*bbb1b6f9SApple OSS Distributions 	_Atomic uint64_t grp_release_total;
24*bbb1b6f9SApple OSS Distributions 	struct os_refgrp *grp_parent;
25*bbb1b6f9SApple OSS Distributions 	void *grp_log;                 /* refcount logging context */
26*bbb1b6f9SApple OSS Distributions 	uint64_t grp_flags;            /* Unused for now. */
27*bbb1b6f9SApple OSS Distributions };
28*bbb1b6f9SApple OSS Distributions 
29*bbb1b6f9SApple OSS Distributions #endif
30*bbb1b6f9SApple OSS Distributions 
31*bbb1b6f9SApple OSS Distributions # define OS_REF_ATOMIC_INITIALIZER 0
32*bbb1b6f9SApple OSS Distributions #if OS_REFCNT_DEBUG
33*bbb1b6f9SApple OSS Distributions # define OS_REF_INITIALIZER { .ref_count = OS_REF_ATOMIC_INITIALIZER, .ref_group = NULL }
34*bbb1b6f9SApple OSS Distributions #else
35*bbb1b6f9SApple OSS Distributions # define OS_REF_INITIALIZER { .ref_count = OS_REF_ATOMIC_INITIALIZER }
36*bbb1b6f9SApple OSS Distributions #endif
37*bbb1b6f9SApple OSS Distributions 
38*bbb1b6f9SApple OSS Distributions __BEGIN_DECLS
39*bbb1b6f9SApple OSS Distributions 
40*bbb1b6f9SApple OSS Distributions #if OS_REFCNT_DEBUG
41*bbb1b6f9SApple OSS Distributions # define os_ref_if_debug(x, y) x
42*bbb1b6f9SApple OSS Distributions #else
43*bbb1b6f9SApple OSS Distributions # define os_ref_if_debug(x, y) y
44*bbb1b6f9SApple OSS Distributions #endif
45*bbb1b6f9SApple OSS Distributions 
46*bbb1b6f9SApple OSS Distributions void os_ref_init_count_external(os_ref_atomic_t *, struct os_refgrp *, os_ref_count_t);
47*bbb1b6f9SApple OSS Distributions void os_ref_retain_external(os_ref_atomic_t *, struct os_refgrp *);
48*bbb1b6f9SApple OSS Distributions void os_ref_retain_locked_external(os_ref_atomic_t *, struct os_refgrp *);
49*bbb1b6f9SApple OSS Distributions os_ref_count_t os_ref_release_external(os_ref_atomic_t *, struct os_refgrp *,
50*bbb1b6f9SApple OSS Distributions     memory_order release_order, memory_order dealloc_order);
51*bbb1b6f9SApple OSS Distributions os_ref_count_t os_ref_release_relaxed_external(os_ref_atomic_t *, struct os_refgrp *);
52*bbb1b6f9SApple OSS Distributions os_ref_count_t os_ref_release_barrier_external(os_ref_atomic_t *, struct os_refgrp *);
53*bbb1b6f9SApple OSS Distributions os_ref_count_t os_ref_release_locked_external(os_ref_atomic_t *, struct os_refgrp *);
54*bbb1b6f9SApple OSS Distributions bool os_ref_retain_try_external(os_ref_atomic_t *, struct os_refgrp *);
55*bbb1b6f9SApple OSS Distributions 
56*bbb1b6f9SApple OSS Distributions #if XNU_KERNEL_PRIVATE
57*bbb1b6f9SApple OSS Distributions void os_ref_init_count_internal(os_ref_atomic_t *, struct os_refgrp *, os_ref_count_t);
58*bbb1b6f9SApple OSS Distributions void os_ref_retain_internal(os_ref_atomic_t *, struct os_refgrp *);
59*bbb1b6f9SApple OSS Distributions void os_ref_retain_floor_internal(os_ref_atomic_t *, os_ref_count_t, struct os_refgrp *);
60*bbb1b6f9SApple OSS Distributions os_ref_count_t os_ref_release_relaxed_internal(os_ref_atomic_t *, struct os_refgrp *);
61*bbb1b6f9SApple OSS Distributions os_ref_count_t os_ref_release_barrier_internal(os_ref_atomic_t *, struct os_refgrp *);
62*bbb1b6f9SApple OSS Distributions os_ref_count_t os_ref_release_internal(os_ref_atomic_t *, struct os_refgrp *,
63*bbb1b6f9SApple OSS Distributions     memory_order release_order, memory_order dealloc_order);
64*bbb1b6f9SApple OSS Distributions bool os_ref_retain_try_internal(os_ref_atomic_t *, struct os_refgrp *);
65*bbb1b6f9SApple OSS Distributions bool os_ref_retain_floor_try_internal(os_ref_atomic_t *, os_ref_count_t, struct os_refgrp *);
66*bbb1b6f9SApple OSS Distributions void os_ref_retain_locked_internal(os_ref_atomic_t *, struct os_refgrp *);
67*bbb1b6f9SApple OSS Distributions void os_ref_retain_floor_locked_internal(os_ref_atomic_t *, os_ref_count_t, struct os_refgrp *);
68*bbb1b6f9SApple OSS Distributions os_ref_count_t os_ref_release_locked_internal(os_ref_atomic_t *, struct os_refgrp *);
69*bbb1b6f9SApple OSS Distributions #else
70*bbb1b6f9SApple OSS Distributions /* For now, the internal and external variants are identical */
71*bbb1b6f9SApple OSS Distributions #define os_ref_init_count_internal      os_ref_init_count_external
72*bbb1b6f9SApple OSS Distributions #define os_ref_retain_internal          os_ref_retain_external
73*bbb1b6f9SApple OSS Distributions #define os_ref_retain_locked_internal   os_ref_retain_locked_external
74*bbb1b6f9SApple OSS Distributions #define os_ref_release_internal         os_ref_release_external
75*bbb1b6f9SApple OSS Distributions #define os_ref_release_barrier_internal os_ref_release_barrier_external
76*bbb1b6f9SApple OSS Distributions #define os_ref_release_relaxed_internal os_ref_release_relaxed_external
77*bbb1b6f9SApple OSS Distributions #define os_ref_release_locked_internal  os_ref_release_locked_external
78*bbb1b6f9SApple OSS Distributions #define os_ref_retain_try_internal      os_ref_retain_try_external
79*bbb1b6f9SApple OSS Distributions #endif
80*bbb1b6f9SApple OSS Distributions 
81*bbb1b6f9SApple OSS Distributions static inline void
os_ref_init_count(struct os_refcnt * rc,struct os_refgrp * __unused grp,os_ref_count_t count)82*bbb1b6f9SApple OSS Distributions os_ref_init_count(struct os_refcnt *rc, struct os_refgrp * __unused grp, os_ref_count_t count)
83*bbb1b6f9SApple OSS Distributions {
84*bbb1b6f9SApple OSS Distributions #if OS_REFCNT_DEBUG
85*bbb1b6f9SApple OSS Distributions 	rc->ref_group = grp;
86*bbb1b6f9SApple OSS Distributions #endif
87*bbb1b6f9SApple OSS Distributions 	os_ref_init_count_internal(&rc->ref_count, os_ref_if_debug(rc->ref_group, NULL), count);
88*bbb1b6f9SApple OSS Distributions }
89*bbb1b6f9SApple OSS Distributions 
90*bbb1b6f9SApple OSS Distributions static inline void
os_ref_retain(struct os_refcnt * rc)91*bbb1b6f9SApple OSS Distributions os_ref_retain(struct os_refcnt *rc)
92*bbb1b6f9SApple OSS Distributions {
93*bbb1b6f9SApple OSS Distributions 	os_ref_retain_internal(&rc->ref_count, os_ref_if_debug(rc->ref_group, NULL));
94*bbb1b6f9SApple OSS Distributions }
95*bbb1b6f9SApple OSS Distributions 
96*bbb1b6f9SApple OSS Distributions static inline os_ref_count_t
os_ref_release_locked(struct os_refcnt * rc)97*bbb1b6f9SApple OSS Distributions os_ref_release_locked(struct os_refcnt *rc)
98*bbb1b6f9SApple OSS Distributions {
99*bbb1b6f9SApple OSS Distributions 	return os_ref_release_locked_internal(&rc->ref_count, os_ref_if_debug(rc->ref_group, NULL));
100*bbb1b6f9SApple OSS Distributions }
101*bbb1b6f9SApple OSS Distributions 
102*bbb1b6f9SApple OSS Distributions static inline void
os_ref_retain_locked(struct os_refcnt * rc)103*bbb1b6f9SApple OSS Distributions os_ref_retain_locked(struct os_refcnt *rc)
104*bbb1b6f9SApple OSS Distributions {
105*bbb1b6f9SApple OSS Distributions 	os_ref_retain_internal(&rc->ref_count, os_ref_if_debug(rc->ref_group, NULL));
106*bbb1b6f9SApple OSS Distributions }
107*bbb1b6f9SApple OSS Distributions 
108*bbb1b6f9SApple OSS Distributions static inline bool
os_ref_retain_try(struct os_refcnt * rc)109*bbb1b6f9SApple OSS Distributions os_ref_retain_try(struct os_refcnt *rc)
110*bbb1b6f9SApple OSS Distributions {
111*bbb1b6f9SApple OSS Distributions 	return os_ref_retain_try_internal(&rc->ref_count, os_ref_if_debug(rc->ref_group, NULL));
112*bbb1b6f9SApple OSS Distributions }
113*bbb1b6f9SApple OSS Distributions 
114*bbb1b6f9SApple OSS Distributions __deprecated_msg("inefficient codegen, prefer os_ref_release / os_ref_release_relaxed")
115*bbb1b6f9SApple OSS Distributions static inline os_ref_count_t OS_WARN_RESULT
os_ref_release_explicit(struct os_refcnt * rc,memory_order release_order,memory_order dealloc_order)116*bbb1b6f9SApple OSS Distributions os_ref_release_explicit(struct os_refcnt *rc, memory_order release_order, memory_order dealloc_order)
117*bbb1b6f9SApple OSS Distributions {
118*bbb1b6f9SApple OSS Distributions 	return os_ref_release_internal(&rc->ref_count, os_ref_if_debug(rc->ref_group, NULL),
119*bbb1b6f9SApple OSS Distributions 	           release_order, dealloc_order);
120*bbb1b6f9SApple OSS Distributions }
121*bbb1b6f9SApple OSS Distributions 
122*bbb1b6f9SApple OSS Distributions #if OS_REFCNT_DEBUG
123*bbb1b6f9SApple OSS Distributions # define os_refgrp_initializer(name, parent, flags) \
124*bbb1b6f9SApple OSS Distributions 	 { \
125*bbb1b6f9SApple OSS Distributions 	        .grp_name =          (name), \
126*bbb1b6f9SApple OSS Distributions 	        .grp_children =      (0u), \
127*bbb1b6f9SApple OSS Distributions 	        .grp_count =         (0u), \
128*bbb1b6f9SApple OSS Distributions 	        .grp_retain_total =  (0u), \
129*bbb1b6f9SApple OSS Distributions 	        .grp_release_total = (0u), \
130*bbb1b6f9SApple OSS Distributions 	        .grp_parent =        (parent), \
131*bbb1b6f9SApple OSS Distributions 	        .grp_log =           NULL, \
132*bbb1b6f9SApple OSS Distributions 	        .grp_flags =         flags, \
133*bbb1b6f9SApple OSS Distributions 	}
134*bbb1b6f9SApple OSS Distributions 
135*bbb1b6f9SApple OSS Distributions # define os_refgrp_decl_flags(qual, var, name, parent, flags) \
136*bbb1b6f9SApple OSS Distributions 	qual struct os_refgrp __attribute__((section("__DATA,__refgrps"))) var =  \
137*bbb1b6f9SApple OSS Distributions 	    os_refgrp_initializer(name, parent, flags)
138*bbb1b6f9SApple OSS Distributions 
139*bbb1b6f9SApple OSS Distributions # define os_refgrp_decl(qual, var, name, parent) \
140*bbb1b6f9SApple OSS Distributions 	os_refgrp_decl_flags(qual, var, name, parent, OS_REFGRP_F_NONE)
141*bbb1b6f9SApple OSS Distributions 
142*bbb1b6f9SApple OSS Distributions # define os_refgrp_decl_extern(var) \
143*bbb1b6f9SApple OSS Distributions 	extern struct os_refgrp var
144*bbb1b6f9SApple OSS Distributions 
145*bbb1b6f9SApple OSS Distributions /* Create a default group based on the init() callsite if no explicit group
146*bbb1b6f9SApple OSS Distributions  * is provided. */
147*bbb1b6f9SApple OSS Distributions # define os_ref_init_count(rc, grp, count) ({ \
148*bbb1b6f9SApple OSS Distributions 	        os_refgrp_decl(static, __grp, __func__, NULL); \
149*bbb1b6f9SApple OSS Distributions 	        (os_ref_init_count)((rc), (grp) ? (grp) : &__grp, (count)); \
150*bbb1b6f9SApple OSS Distributions 	})
151*bbb1b6f9SApple OSS Distributions 
152*bbb1b6f9SApple OSS Distributions #else /* OS_REFCNT_DEBUG */
153*bbb1b6f9SApple OSS Distributions 
154*bbb1b6f9SApple OSS Distributions # define os_refgrp_decl(qual, var, name, parent) extern struct os_refgrp var __attribute__((unused))
155*bbb1b6f9SApple OSS Distributions # define os_refgrp_decl_extern(var) os_refgrp_decl(, var, ,)
156*bbb1b6f9SApple OSS Distributions # define os_ref_init_count(rc, grp, count) (os_ref_init_count)((rc), NULL, (count))
157*bbb1b6f9SApple OSS Distributions 
158*bbb1b6f9SApple OSS Distributions #endif /* OS_REFCNT_DEBUG */
159*bbb1b6f9SApple OSS Distributions 
160*bbb1b6f9SApple OSS Distributions #if XNU_KERNEL_PRIVATE
161*bbb1b6f9SApple OSS Distributions void os_ref_panic_live(void *rc) __abortlike;
162*bbb1b6f9SApple OSS Distributions #else
163*bbb1b6f9SApple OSS Distributions __abortlike
164*bbb1b6f9SApple OSS Distributions static inline void
os_ref_panic_live(void * rc)165*bbb1b6f9SApple OSS Distributions os_ref_panic_live(void *rc)
166*bbb1b6f9SApple OSS Distributions {
167*bbb1b6f9SApple OSS Distributions 	panic("os_refcnt: unexpected release of final reference (rc=%p)\n", rc);
168*bbb1b6f9SApple OSS Distributions 	__builtin_unreachable();
169*bbb1b6f9SApple OSS Distributions }
170*bbb1b6f9SApple OSS Distributions #endif
171*bbb1b6f9SApple OSS Distributions 
172*bbb1b6f9SApple OSS Distributions #if XNU_KERNEL_PRIVATE
173*bbb1b6f9SApple OSS Distributions void os_ref_panic_last(void *rc) __abortlike;
174*bbb1b6f9SApple OSS Distributions #else
175*bbb1b6f9SApple OSS Distributions __abortlike
176*bbb1b6f9SApple OSS Distributions static inline void
os_ref_panic_last(void * rc)177*bbb1b6f9SApple OSS Distributions os_ref_panic_last(void *rc)
178*bbb1b6f9SApple OSS Distributions {
179*bbb1b6f9SApple OSS Distributions 	panic("os_refcnt: expected release of final reference but rc %p!=0\n", rc);
180*bbb1b6f9SApple OSS Distributions 	__builtin_unreachable();
181*bbb1b6f9SApple OSS Distributions }
182*bbb1b6f9SApple OSS Distributions #endif
183*bbb1b6f9SApple OSS Distributions 
184*bbb1b6f9SApple OSS Distributions static inline os_ref_count_t OS_WARN_RESULT
os_ref_release(struct os_refcnt * rc)185*bbb1b6f9SApple OSS Distributions os_ref_release(struct os_refcnt *rc)
186*bbb1b6f9SApple OSS Distributions {
187*bbb1b6f9SApple OSS Distributions 	return os_ref_release_barrier_internal(&rc->ref_count,
188*bbb1b6f9SApple OSS Distributions 	           os_ref_if_debug(rc->ref_group, NULL));
189*bbb1b6f9SApple OSS Distributions }
190*bbb1b6f9SApple OSS Distributions 
191*bbb1b6f9SApple OSS Distributions static inline void
os_ref_release_last(struct os_refcnt * rc)192*bbb1b6f9SApple OSS Distributions os_ref_release_last(struct os_refcnt *rc)
193*bbb1b6f9SApple OSS Distributions {
194*bbb1b6f9SApple OSS Distributions 	if (__improbable(os_ref_release(rc) != 0)) {
195*bbb1b6f9SApple OSS Distributions 		os_ref_panic_last(rc);
196*bbb1b6f9SApple OSS Distributions 	}
197*bbb1b6f9SApple OSS Distributions }
198*bbb1b6f9SApple OSS Distributions 
199*bbb1b6f9SApple OSS Distributions static inline os_ref_count_t OS_WARN_RESULT
os_ref_release_relaxed(struct os_refcnt * rc)200*bbb1b6f9SApple OSS Distributions os_ref_release_relaxed(struct os_refcnt *rc)
201*bbb1b6f9SApple OSS Distributions {
202*bbb1b6f9SApple OSS Distributions 	return os_ref_release_relaxed_internal(&rc->ref_count,
203*bbb1b6f9SApple OSS Distributions 	           os_ref_if_debug(rc->ref_group, NULL));
204*bbb1b6f9SApple OSS Distributions }
205*bbb1b6f9SApple OSS Distributions 
206*bbb1b6f9SApple OSS Distributions static inline void
os_ref_release_live(struct os_refcnt * rc)207*bbb1b6f9SApple OSS Distributions os_ref_release_live(struct os_refcnt *rc)
208*bbb1b6f9SApple OSS Distributions {
209*bbb1b6f9SApple OSS Distributions 	if (__improbable(os_ref_release(rc) == 0)) {
210*bbb1b6f9SApple OSS Distributions 		os_ref_panic_live(rc);
211*bbb1b6f9SApple OSS Distributions 	}
212*bbb1b6f9SApple OSS Distributions }
213*bbb1b6f9SApple OSS Distributions 
214*bbb1b6f9SApple OSS Distributions static inline os_ref_count_t
os_ref_get_count_internal(os_ref_atomic_t * rc)215*bbb1b6f9SApple OSS Distributions os_ref_get_count_internal(os_ref_atomic_t *rc)
216*bbb1b6f9SApple OSS Distributions {
217*bbb1b6f9SApple OSS Distributions 	return atomic_load_explicit(rc, memory_order_relaxed);
218*bbb1b6f9SApple OSS Distributions }
219*bbb1b6f9SApple OSS Distributions 
220*bbb1b6f9SApple OSS Distributions static inline os_ref_count_t
os_ref_get_count(struct os_refcnt * rc)221*bbb1b6f9SApple OSS Distributions os_ref_get_count(struct os_refcnt *rc)
222*bbb1b6f9SApple OSS Distributions {
223*bbb1b6f9SApple OSS Distributions 	return os_ref_get_count_internal(&rc->ref_count);
224*bbb1b6f9SApple OSS Distributions }
225*bbb1b6f9SApple OSS Distributions 
226*bbb1b6f9SApple OSS Distributions #if !OS_REFCNT_DEBUG
227*bbb1b6f9SApple OSS Distributions #define os_pcpu_ref_init(ref, grp)              (os_pcpu_ref_init)(ref, NULL)
228*bbb1b6f9SApple OSS Distributions #define os_pcpu_ref_destroy(ref, grp)           (os_pcpu_ref_destroy)(ref, NULL)
229*bbb1b6f9SApple OSS Distributions #define os_pcpu_ref_kill(ref, grp)              (os_pcpu_ref_kill)(ref, NULL)
230*bbb1b6f9SApple OSS Distributions #define os_pcpu_ref_retain(ref, grp)            (os_pcpu_ref_retain)(ref, NULL)
231*bbb1b6f9SApple OSS Distributions #define os_pcpu_ref_retain_try(ref, grp)        (os_pcpu_ref_retain_try)(ref, NULL)
232*bbb1b6f9SApple OSS Distributions #define os_pcpu_ref_release(ref, grp)           (os_pcpu_ref_release)(ref, NULL)
233*bbb1b6f9SApple OSS Distributions #define os_pcpu_ref_release_live(ref, grp)      (os_pcpu_ref_release_live)(ref, NULL)
234*bbb1b6f9SApple OSS Distributions #endif
235*bbb1b6f9SApple OSS Distributions 
236*bbb1b6f9SApple OSS Distributions #if XNU_KERNEL_PRIVATE
237*bbb1b6f9SApple OSS Distributions #pragma GCC visibility push(hidden)
238*bbb1b6f9SApple OSS Distributions 
239*bbb1b6f9SApple OSS Distributions /*
240*bbb1b6f9SApple OSS Distributions  * Raw API
241*bbb1b6f9SApple OSS Distributions  */
242*bbb1b6f9SApple OSS Distributions 
243*bbb1b6f9SApple OSS Distributions static inline void
os_ref_init_count_raw(os_ref_atomic_t * rc,struct os_refgrp * grp,os_ref_count_t count)244*bbb1b6f9SApple OSS Distributions os_ref_init_count_raw(os_ref_atomic_t *rc, struct os_refgrp *grp, os_ref_count_t count)
245*bbb1b6f9SApple OSS Distributions {
246*bbb1b6f9SApple OSS Distributions 	os_ref_init_count_internal(rc, grp, count);
247*bbb1b6f9SApple OSS Distributions }
248*bbb1b6f9SApple OSS Distributions 
249*bbb1b6f9SApple OSS Distributions static inline void
os_ref_retain_floor(struct os_refcnt * rc,os_ref_count_t f)250*bbb1b6f9SApple OSS Distributions os_ref_retain_floor(struct os_refcnt *rc, os_ref_count_t f)
251*bbb1b6f9SApple OSS Distributions {
252*bbb1b6f9SApple OSS Distributions 	os_ref_retain_floor_internal(&rc->ref_count, f, os_ref_if_debug(rc->ref_group, NULL));
253*bbb1b6f9SApple OSS Distributions }
254*bbb1b6f9SApple OSS Distributions 
255*bbb1b6f9SApple OSS Distributions static inline void
os_ref_retain_raw(os_ref_atomic_t * rc,struct os_refgrp * grp)256*bbb1b6f9SApple OSS Distributions os_ref_retain_raw(os_ref_atomic_t *rc, struct os_refgrp *grp)
257*bbb1b6f9SApple OSS Distributions {
258*bbb1b6f9SApple OSS Distributions 	os_ref_retain_internal(rc, grp);
259*bbb1b6f9SApple OSS Distributions }
260*bbb1b6f9SApple OSS Distributions 
261*bbb1b6f9SApple OSS Distributions static inline void
os_ref_retain_floor_raw(os_ref_atomic_t * rc,os_ref_count_t f,struct os_refgrp * grp)262*bbb1b6f9SApple OSS Distributions os_ref_retain_floor_raw(os_ref_atomic_t *rc, os_ref_count_t f, struct os_refgrp *grp)
263*bbb1b6f9SApple OSS Distributions {
264*bbb1b6f9SApple OSS Distributions 	os_ref_retain_floor_internal(rc, f, grp);
265*bbb1b6f9SApple OSS Distributions }
266*bbb1b6f9SApple OSS Distributions 
267*bbb1b6f9SApple OSS Distributions static inline os_ref_count_t
os_ref_release_raw(os_ref_atomic_t * rc,struct os_refgrp * grp)268*bbb1b6f9SApple OSS Distributions os_ref_release_raw(os_ref_atomic_t *rc, struct os_refgrp *grp)
269*bbb1b6f9SApple OSS Distributions {
270*bbb1b6f9SApple OSS Distributions 	return os_ref_release_barrier_internal(rc, grp);
271*bbb1b6f9SApple OSS Distributions }
272*bbb1b6f9SApple OSS Distributions 
273*bbb1b6f9SApple OSS Distributions static inline os_ref_count_t
os_ref_release_raw_relaxed(os_ref_atomic_t * rc,struct os_refgrp * grp)274*bbb1b6f9SApple OSS Distributions os_ref_release_raw_relaxed(os_ref_atomic_t *rc, struct os_refgrp *grp)
275*bbb1b6f9SApple OSS Distributions {
276*bbb1b6f9SApple OSS Distributions 	return os_ref_release_relaxed_internal(rc, grp);
277*bbb1b6f9SApple OSS Distributions }
278*bbb1b6f9SApple OSS Distributions 
279*bbb1b6f9SApple OSS Distributions static inline void
os_ref_release_live_raw(os_ref_atomic_t * rc,struct os_refgrp * grp)280*bbb1b6f9SApple OSS Distributions os_ref_release_live_raw(os_ref_atomic_t *rc, struct os_refgrp *grp)
281*bbb1b6f9SApple OSS Distributions {
282*bbb1b6f9SApple OSS Distributions 	if (__improbable(os_ref_release_barrier_internal(rc, grp) == 0)) {
283*bbb1b6f9SApple OSS Distributions 		os_ref_panic_live(rc);
284*bbb1b6f9SApple OSS Distributions 	}
285*bbb1b6f9SApple OSS Distributions }
286*bbb1b6f9SApple OSS Distributions 
287*bbb1b6f9SApple OSS Distributions static inline bool
os_ref_retain_try_raw(os_ref_atomic_t * rc,struct os_refgrp * grp)288*bbb1b6f9SApple OSS Distributions os_ref_retain_try_raw(os_ref_atomic_t *rc, struct os_refgrp *grp)
289*bbb1b6f9SApple OSS Distributions {
290*bbb1b6f9SApple OSS Distributions 	return os_ref_retain_try_internal(rc, grp);
291*bbb1b6f9SApple OSS Distributions }
292*bbb1b6f9SApple OSS Distributions 
293*bbb1b6f9SApple OSS Distributions static inline bool
os_ref_retain_floor_try_raw(os_ref_atomic_t * rc,os_ref_count_t f,struct os_refgrp * grp)294*bbb1b6f9SApple OSS Distributions os_ref_retain_floor_try_raw(os_ref_atomic_t *rc, os_ref_count_t f,
295*bbb1b6f9SApple OSS Distributions     struct os_refgrp *grp)
296*bbb1b6f9SApple OSS Distributions {
297*bbb1b6f9SApple OSS Distributions 	return os_ref_retain_floor_try_internal(rc, f, grp);
298*bbb1b6f9SApple OSS Distributions }
299*bbb1b6f9SApple OSS Distributions 
300*bbb1b6f9SApple OSS Distributions static inline void
os_ref_retain_locked_raw(os_ref_atomic_t * rc,struct os_refgrp * grp)301*bbb1b6f9SApple OSS Distributions os_ref_retain_locked_raw(os_ref_atomic_t *rc, struct os_refgrp *grp)
302*bbb1b6f9SApple OSS Distributions {
303*bbb1b6f9SApple OSS Distributions 	os_ref_retain_locked_internal(rc, grp);
304*bbb1b6f9SApple OSS Distributions }
305*bbb1b6f9SApple OSS Distributions 
306*bbb1b6f9SApple OSS Distributions static inline void
os_ref_retain_floor_locked_raw(os_ref_atomic_t * rc,os_ref_count_t f,struct os_refgrp * grp)307*bbb1b6f9SApple OSS Distributions os_ref_retain_floor_locked_raw(os_ref_atomic_t *rc, os_ref_count_t f,
308*bbb1b6f9SApple OSS Distributions     struct os_refgrp *grp)
309*bbb1b6f9SApple OSS Distributions {
310*bbb1b6f9SApple OSS Distributions 	os_ref_retain_floor_locked_internal(rc, f, grp);
311*bbb1b6f9SApple OSS Distributions }
312*bbb1b6f9SApple OSS Distributions 
313*bbb1b6f9SApple OSS Distributions static inline os_ref_count_t
os_ref_release_locked_raw(os_ref_atomic_t * rc,struct os_refgrp * grp)314*bbb1b6f9SApple OSS Distributions os_ref_release_locked_raw(os_ref_atomic_t *rc, struct os_refgrp *grp)
315*bbb1b6f9SApple OSS Distributions {
316*bbb1b6f9SApple OSS Distributions 	return os_ref_release_locked_internal(rc, grp);
317*bbb1b6f9SApple OSS Distributions }
318*bbb1b6f9SApple OSS Distributions 
319*bbb1b6f9SApple OSS Distributions static inline void
os_ref_release_live_locked_raw(os_ref_atomic_t * rc,struct os_refgrp * grp)320*bbb1b6f9SApple OSS Distributions os_ref_release_live_locked_raw(os_ref_atomic_t *rc, struct os_refgrp *grp)
321*bbb1b6f9SApple OSS Distributions {
322*bbb1b6f9SApple OSS Distributions 	if (__improbable(os_ref_release_locked_internal(rc, grp) == 0)) {
323*bbb1b6f9SApple OSS Distributions 		os_ref_panic_live(rc);
324*bbb1b6f9SApple OSS Distributions 	}
325*bbb1b6f9SApple OSS Distributions }
326*bbb1b6f9SApple OSS Distributions 
327*bbb1b6f9SApple OSS Distributions static inline os_ref_count_t
os_ref_get_count_raw(os_ref_atomic_t * rc)328*bbb1b6f9SApple OSS Distributions os_ref_get_count_raw(os_ref_atomic_t *rc)
329*bbb1b6f9SApple OSS Distributions {
330*bbb1b6f9SApple OSS Distributions 	return os_ref_get_count_internal(rc);
331*bbb1b6f9SApple OSS Distributions }
332*bbb1b6f9SApple OSS Distributions 
333*bbb1b6f9SApple OSS Distributions #if !OS_REFCNT_DEBUG
334*bbb1b6f9SApple OSS Distributions /* remove the group argument for non-debug */
335*bbb1b6f9SApple OSS Distributions #define os_ref_init_count_raw(rc, grp, count) (os_ref_init_count_raw)((rc), NULL, (count))
336*bbb1b6f9SApple OSS Distributions #define os_ref_retain_raw(rc, grp) (os_ref_retain_raw)((rc), NULL)
337*bbb1b6f9SApple OSS Distributions #define os_ref_retain_floor_raw(rc, f, grp) (os_ref_retain_floor_raw)((rc), f, NULL)
338*bbb1b6f9SApple OSS Distributions #define os_ref_release_raw(rc, grp) (os_ref_release_raw)((rc), NULL)
339*bbb1b6f9SApple OSS Distributions #define os_ref_release_raw_relaxed(rc, grp) (os_ref_release_raw_relaxed)((rc), NULL)
340*bbb1b6f9SApple OSS Distributions #define os_ref_release_live_raw(rc, grp) (os_ref_release_live_raw)((rc), NULL)
341*bbb1b6f9SApple OSS Distributions #define os_ref_retain_try_raw(rc, grp) (os_ref_retain_try_raw)((rc), NULL)
342*bbb1b6f9SApple OSS Distributions #define os_ref_retain_floor_try_raw(rc, f, grp) (os_ref_retain_floor_try_raw)((rc), f, NULL)
343*bbb1b6f9SApple OSS Distributions #define os_ref_retain_locked_raw(rc, grp) (os_ref_retain_locked_raw)((rc), NULL)
344*bbb1b6f9SApple OSS Distributions #define os_ref_retain_floor_locked_raw(rc, f, grp) (os_ref_retain_floor_locked_raw)((rc), f, NULL)
345*bbb1b6f9SApple OSS Distributions #define os_ref_release_locked_raw(rc, grp) (os_ref_release_locked_raw)((rc), NULL)
346*bbb1b6f9SApple OSS Distributions #define os_ref_release_live_locked_raw(rc, grp) (os_ref_release_live_locked_raw)((rc), NULL)
347*bbb1b6f9SApple OSS Distributions #endif
348*bbb1b6f9SApple OSS Distributions 
349*bbb1b6f9SApple OSS Distributions extern void
350*bbb1b6f9SApple OSS Distributions os_ref_log_fini(struct os_refgrp *grp);
351*bbb1b6f9SApple OSS Distributions 
352*bbb1b6f9SApple OSS Distributions extern void
353*bbb1b6f9SApple OSS Distributions os_ref_log_init(struct os_refgrp *grp);
354*bbb1b6f9SApple OSS Distributions 
355*bbb1b6f9SApple OSS Distributions extern void
356*bbb1b6f9SApple OSS Distributions os_ref_retain_mask_internal(os_ref_atomic_t *rc, uint32_t n, struct os_refgrp *grp);
357*bbb1b6f9SApple OSS Distributions extern void
358*bbb1b6f9SApple OSS Distributions os_ref_retain_acquire_mask_internal(os_ref_atomic_t *rc, uint32_t n, struct os_refgrp *grp);
359*bbb1b6f9SApple OSS Distributions extern uint32_t
360*bbb1b6f9SApple OSS Distributions os_ref_retain_try_mask_internal(os_ref_atomic_t *, uint32_t n,
361*bbb1b6f9SApple OSS Distributions     uint32_t reject_mask, struct os_refgrp *grp) OS_WARN_RESULT;
362*bbb1b6f9SApple OSS Distributions extern bool
363*bbb1b6f9SApple OSS Distributions os_ref_retain_try_acquire_mask_internal(os_ref_atomic_t *, uint32_t n,
364*bbb1b6f9SApple OSS Distributions     uint32_t reject_mask, struct os_refgrp *grp) OS_WARN_RESULT;
365*bbb1b6f9SApple OSS Distributions 
366*bbb1b6f9SApple OSS Distributions extern uint32_t
367*bbb1b6f9SApple OSS Distributions os_ref_release_barrier_mask_internal(os_ref_atomic_t *rc, uint32_t n, struct os_refgrp *grp);
368*bbb1b6f9SApple OSS Distributions extern uint32_t
369*bbb1b6f9SApple OSS Distributions os_ref_release_relaxed_mask_internal(os_ref_atomic_t *rc, uint32_t n, struct os_refgrp *grp);
370*bbb1b6f9SApple OSS Distributions 
371*bbb1b6f9SApple OSS Distributions static inline uint32_t
os_ref_get_raw_mask(os_ref_atomic_t * rc)372*bbb1b6f9SApple OSS Distributions os_ref_get_raw_mask(os_ref_atomic_t *rc)
373*bbb1b6f9SApple OSS Distributions {
374*bbb1b6f9SApple OSS Distributions 	return os_ref_get_count_internal(rc);
375*bbb1b6f9SApple OSS Distributions }
376*bbb1b6f9SApple OSS Distributions 
377*bbb1b6f9SApple OSS Distributions static inline uint32_t
os_ref_get_bits_mask(os_ref_atomic_t * rc,uint32_t b)378*bbb1b6f9SApple OSS Distributions os_ref_get_bits_mask(os_ref_atomic_t *rc, uint32_t b)
379*bbb1b6f9SApple OSS Distributions {
380*bbb1b6f9SApple OSS Distributions 	return os_ref_get_raw_mask(rc) & ((1u << b) - 1);
381*bbb1b6f9SApple OSS Distributions }
382*bbb1b6f9SApple OSS Distributions 
383*bbb1b6f9SApple OSS Distributions static inline os_ref_count_t
os_ref_get_count_mask(os_ref_atomic_t * rc,uint32_t b)384*bbb1b6f9SApple OSS Distributions os_ref_get_count_mask(os_ref_atomic_t *rc, uint32_t b)
385*bbb1b6f9SApple OSS Distributions {
386*bbb1b6f9SApple OSS Distributions 	return os_ref_get_raw_mask(rc) >> b;
387*bbb1b6f9SApple OSS Distributions }
388*bbb1b6f9SApple OSS Distributions 
389*bbb1b6f9SApple OSS Distributions static inline void
os_ref_retain_mask(os_ref_atomic_t * rc,uint32_t b,struct os_refgrp * grp)390*bbb1b6f9SApple OSS Distributions os_ref_retain_mask(os_ref_atomic_t *rc, uint32_t b, struct os_refgrp *grp)
391*bbb1b6f9SApple OSS Distributions {
392*bbb1b6f9SApple OSS Distributions 	os_ref_retain_mask_internal(rc, 1u << b, grp);
393*bbb1b6f9SApple OSS Distributions }
394*bbb1b6f9SApple OSS Distributions 
395*bbb1b6f9SApple OSS Distributions static inline void
os_ref_retain_acquire_mask(os_ref_atomic_t * rc,uint32_t b,struct os_refgrp * grp)396*bbb1b6f9SApple OSS Distributions os_ref_retain_acquire_mask(os_ref_atomic_t *rc, uint32_t b, struct os_refgrp *grp)
397*bbb1b6f9SApple OSS Distributions {
398*bbb1b6f9SApple OSS Distributions 	os_ref_retain_acquire_mask_internal(rc, 1u << b, grp);
399*bbb1b6f9SApple OSS Distributions }
400*bbb1b6f9SApple OSS Distributions 
401*bbb1b6f9SApple OSS Distributions static inline uint32_t
os_ref_retain_try_mask(os_ref_atomic_t * rc,uint32_t b,uint32_t reject_mask,struct os_refgrp * grp)402*bbb1b6f9SApple OSS Distributions os_ref_retain_try_mask(os_ref_atomic_t *rc, uint32_t b,
403*bbb1b6f9SApple OSS Distributions     uint32_t reject_mask, struct os_refgrp *grp)
404*bbb1b6f9SApple OSS Distributions {
405*bbb1b6f9SApple OSS Distributions 	return os_ref_retain_try_mask_internal(rc, 1u << b, reject_mask, grp);
406*bbb1b6f9SApple OSS Distributions }
407*bbb1b6f9SApple OSS Distributions 
408*bbb1b6f9SApple OSS Distributions static inline bool
os_ref_retain_try_acquire_mask(os_ref_atomic_t * rc,uint32_t b,uint32_t reject_mask,struct os_refgrp * grp)409*bbb1b6f9SApple OSS Distributions os_ref_retain_try_acquire_mask(os_ref_atomic_t *rc, uint32_t b,
410*bbb1b6f9SApple OSS Distributions     uint32_t reject_mask, struct os_refgrp *grp)
411*bbb1b6f9SApple OSS Distributions {
412*bbb1b6f9SApple OSS Distributions 	return os_ref_retain_try_acquire_mask_internal(rc, 1u << b, reject_mask, grp);
413*bbb1b6f9SApple OSS Distributions }
414*bbb1b6f9SApple OSS Distributions 
415*bbb1b6f9SApple OSS Distributions static inline uint32_t
os_ref_release_raw_mask(os_ref_atomic_t * rc,uint32_t b,struct os_refgrp * grp)416*bbb1b6f9SApple OSS Distributions os_ref_release_raw_mask(os_ref_atomic_t *rc, uint32_t b, struct os_refgrp *grp)
417*bbb1b6f9SApple OSS Distributions {
418*bbb1b6f9SApple OSS Distributions 	return os_ref_release_barrier_mask_internal(rc, 1u << b, grp);
419*bbb1b6f9SApple OSS Distributions }
420*bbb1b6f9SApple OSS Distributions 
421*bbb1b6f9SApple OSS Distributions static inline uint32_t
os_ref_release_raw_relaxed_mask(os_ref_atomic_t * rc,uint32_t b,struct os_refgrp * grp)422*bbb1b6f9SApple OSS Distributions os_ref_release_raw_relaxed_mask(os_ref_atomic_t *rc, uint32_t b, struct os_refgrp *grp)
423*bbb1b6f9SApple OSS Distributions {
424*bbb1b6f9SApple OSS Distributions 	return os_ref_release_relaxed_mask_internal(rc, 1u << b, grp);
425*bbb1b6f9SApple OSS Distributions }
426*bbb1b6f9SApple OSS Distributions 
427*bbb1b6f9SApple OSS Distributions static inline os_ref_count_t
os_ref_release_mask(os_ref_atomic_t * rc,uint32_t b,struct os_refgrp * grp)428*bbb1b6f9SApple OSS Distributions os_ref_release_mask(os_ref_atomic_t *rc, uint32_t b, struct os_refgrp *grp)
429*bbb1b6f9SApple OSS Distributions {
430*bbb1b6f9SApple OSS Distributions 	return os_ref_release_barrier_mask_internal(rc, 1u << b, grp) >> b;
431*bbb1b6f9SApple OSS Distributions }
432*bbb1b6f9SApple OSS Distributions 
433*bbb1b6f9SApple OSS Distributions static inline os_ref_count_t
os_ref_release_relaxed_mask(os_ref_atomic_t * rc,uint32_t b,struct os_refgrp * grp)434*bbb1b6f9SApple OSS Distributions os_ref_release_relaxed_mask(os_ref_atomic_t *rc, uint32_t b, struct os_refgrp *grp)
435*bbb1b6f9SApple OSS Distributions {
436*bbb1b6f9SApple OSS Distributions 	return os_ref_release_relaxed_mask_internal(rc, 1u << b, grp) >> b;
437*bbb1b6f9SApple OSS Distributions }
438*bbb1b6f9SApple OSS Distributions 
439*bbb1b6f9SApple OSS Distributions static inline uint32_t
os_ref_release_live_raw_mask(os_ref_atomic_t * rc,uint32_t b,struct os_refgrp * grp)440*bbb1b6f9SApple OSS Distributions os_ref_release_live_raw_mask(os_ref_atomic_t *rc, uint32_t b, struct os_refgrp *grp)
441*bbb1b6f9SApple OSS Distributions {
442*bbb1b6f9SApple OSS Distributions 	uint32_t val = os_ref_release_barrier_mask_internal(rc, 1u << b, grp);
443*bbb1b6f9SApple OSS Distributions 	if (__improbable(val < 1u << b)) {
444*bbb1b6f9SApple OSS Distributions 		os_ref_panic_live(rc);
445*bbb1b6f9SApple OSS Distributions 	}
446*bbb1b6f9SApple OSS Distributions 	return val;
447*bbb1b6f9SApple OSS Distributions }
448*bbb1b6f9SApple OSS Distributions 
449*bbb1b6f9SApple OSS Distributions static inline void
os_ref_release_live_mask(os_ref_atomic_t * rc,uint32_t b,struct os_refgrp * grp)450*bbb1b6f9SApple OSS Distributions os_ref_release_live_mask(os_ref_atomic_t *rc, uint32_t b, struct os_refgrp *grp)
451*bbb1b6f9SApple OSS Distributions {
452*bbb1b6f9SApple OSS Distributions 	os_ref_release_live_raw_mask(rc, b, grp);
453*bbb1b6f9SApple OSS Distributions }
454*bbb1b6f9SApple OSS Distributions 
455*bbb1b6f9SApple OSS Distributions static inline uint32_t
os_ref_release_last_raw_mask(os_ref_atomic_t * rc,uint32_t b,struct os_refgrp * grp)456*bbb1b6f9SApple OSS Distributions os_ref_release_last_raw_mask(os_ref_atomic_t *rc, uint32_t b, struct os_refgrp *grp)
457*bbb1b6f9SApple OSS Distributions {
458*bbb1b6f9SApple OSS Distributions 	uint32_t val = os_ref_release_barrier_mask_internal(rc, 1u << b, grp);
459*bbb1b6f9SApple OSS Distributions 	if (__improbable(val >> b != 0)) {
460*bbb1b6f9SApple OSS Distributions 		os_ref_panic_last(rc);
461*bbb1b6f9SApple OSS Distributions 	}
462*bbb1b6f9SApple OSS Distributions 	return val;
463*bbb1b6f9SApple OSS Distributions }
464*bbb1b6f9SApple OSS Distributions 
465*bbb1b6f9SApple OSS Distributions static inline void
os_ref_release_last_mask(os_ref_atomic_t * rc,uint32_t b,struct os_refgrp * grp)466*bbb1b6f9SApple OSS Distributions os_ref_release_last_mask(os_ref_atomic_t *rc, uint32_t b, struct os_refgrp *grp)
467*bbb1b6f9SApple OSS Distributions {
468*bbb1b6f9SApple OSS Distributions 	os_ref_release_last_raw_mask(rc, b, grp);
469*bbb1b6f9SApple OSS Distributions }
470*bbb1b6f9SApple OSS Distributions 
471*bbb1b6f9SApple OSS Distributions #if !OS_REFCNT_DEBUG
472*bbb1b6f9SApple OSS Distributions /* remove the group argument for non-debug */
473*bbb1b6f9SApple OSS Distributions #define os_ref_init_count_mask(rc, b, grp, init_c, init_b) (os_ref_init_count_mask)(rc, b, NULL, init_c, init_b)
474*bbb1b6f9SApple OSS Distributions #define os_ref_retain_mask(rc, b, grp) (os_ref_retain_mask)((rc), (b), NULL)
475*bbb1b6f9SApple OSS Distributions #define os_ref_retain_acquire_mask(rc, b, grp) (os_ref_retain_acquire_mask)((rc), (b), NULL)
476*bbb1b6f9SApple OSS Distributions #define os_ref_retain_try_mask(rc, b, m, grp) (os_ref_retain_try_mask)((rc), (b), (m), NULL)
477*bbb1b6f9SApple OSS Distributions #define os_ref_retain_try_acquire_mask(rc, b, grp) (os_ref_retain_try_acquire_mask)((rc), (b), NULL)
478*bbb1b6f9SApple OSS Distributions #define os_ref_release_mask(rc, b, grp) (os_ref_release_mask)((rc), (b), NULL)
479*bbb1b6f9SApple OSS Distributions #define os_ref_release_relaxed_mask(rc, b, grp) (os_ref_release_relaxed_mask)((rc), (b), NULL)
480*bbb1b6f9SApple OSS Distributions #define os_ref_release_raw_mask(rc, b, grp) (os_ref_release_raw_mask)((rc), (b), NULL)
481*bbb1b6f9SApple OSS Distributions #define os_ref_release_raw_relaxed_mask(rc, b, grp) (os_ref_release_raw_relaxed_mask)((rc), (b), NULL)
482*bbb1b6f9SApple OSS Distributions #define os_ref_release_live_raw_mask(rc, b, grp) (os_ref_release_live_raw_mask)((rc), (b), NULL)
483*bbb1b6f9SApple OSS Distributions #define os_ref_release_live_mask(rc, b, grp) (os_ref_release_live_mask)((rc), (b), NULL)
484*bbb1b6f9SApple OSS Distributions #define os_ref_release_last_raw_mask(rc, b, grp) (os_ref_release_last_raw_mask)((rc), (b), NULL)
485*bbb1b6f9SApple OSS Distributions #define os_ref_release_last_mask(rc, b, grp) (os_ref_release_last_mask)((rc), (b), NULL)
486*bbb1b6f9SApple OSS Distributions #endif
487*bbb1b6f9SApple OSS Distributions 
488*bbb1b6f9SApple OSS Distributions #pragma GCC visibility pop
489*bbb1b6f9SApple OSS Distributions #endif
490*bbb1b6f9SApple OSS Distributions 
491*bbb1b6f9SApple OSS Distributions __END_DECLS
492*bbb1b6f9SApple OSS Distributions 
493*bbb1b6f9SApple OSS Distributions #endif /* _OS_REFCNT_INTERNAL_H */
494