Zephyr Project API 4.4.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
ref.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
11
12#ifndef ZEPHYR_INCLUDE_SYS_REF_H_
13#define ZEPHYR_INCLUDE_SYS_REF_H_
14
15#include <limits.h>
16#include <stdbool.h>
17
18#include <zephyr/sys/atomic.h>
19#include <zephyr/sys/__assert.h>
20
21#ifdef __cplusplus
22extern "C" {
23#endif
24
31
39#define SYS_REFCOUNT_SATURATED LONG_MAX
41
55
62#define SYS_REFCOUNT_INITIALIZER { .value = ATOMIC_INIT(1) }
63
69static inline void sys_refcount_init(struct sys_refcount *const rc)
70{
71 atomic_set(&rc->value, 1);
72}
73
82static inline void sys_refcount_inc(struct sys_refcount *const rc)
83{
84 atomic_val_t old = atomic_get(&rc->value);
85
86 while (true) {
87 __ASSERT(old != 0, "Increment of zero reference counter");
88
89 if (old == SYS_REFCOUNT_SATURATED) {
90 return;
91 }
92
93 if (atomic_cas(&rc->value, old, old + 1)) {
94 return;
95 }
96
97 old = atomic_get(&rc->value);
98 }
99}
100
112static inline bool sys_refcount_dec(struct sys_refcount *const rc)
113{
114 atomic_val_t old = atomic_get(&rc->value);
115
116 while (true) {
117 if (old == SYS_REFCOUNT_SATURATED) {
118 return false;
119 }
120
121 __ASSERT(old > 0, "Decrement of zero reference counter");
122
123 if (atomic_cas(&rc->value, old, old - 1)) {
124 return old == 1;
125 }
126
127 old = atomic_get(&rc->value);
128 }
129}
130
131struct sys_ref;
132
138typedef void (*sys_ref_release_t)(struct sys_ref *const ref);
139
147struct sys_ref {
150};
151
165#define SYS_REF_INITIALIZER { .refcount = SYS_REFCOUNT_INITIALIZER }
166
176static inline void sys_ref_init(struct sys_ref *const ref)
177{
179}
180
191static inline void sys_ref_get(struct sys_ref *const ref)
192{
194}
195
228static inline bool sys_ref_put(struct sys_ref *const ref,
229 const sys_ref_release_t release)
230{
231 __ASSERT_NO_MSG(release != NULL);
232
233 if (sys_refcount_dec(&ref->refcount)) {
234 release(ref);
235 return true;
236 }
237
238 return false;
239}
240
244
245#ifdef __cplusplus
246}
247#endif
248
249#endif /* ZEPHYR_INCLUDE_SYS_REF_H_ */
long atomic_t
Atomic integer variable.
Definition atomic_types.h:31
atomic_t atomic_val_t
Value type for atomic integer variables.
Definition atomic_types.h:38
atomic_val_t atomic_get(const atomic_t *target)
Atomic get.
atomic_val_t atomic_set(atomic_t *target, atomic_val_t value)
Atomic get-and-set.
bool atomic_cas(atomic_t *target, atomic_val_t old_value, atomic_val_t new_value)
Atomic compare-and-set.
static void sys_refcount_inc(struct sys_refcount *const rc)
Increment a reference counter.
Definition ref.h:82
static bool sys_ref_put(struct sys_ref *const ref, const sys_ref_release_t release)
Decrease reference of an object.
Definition ref.h:228
static void sys_ref_get(struct sys_ref *const ref)
Increase reference of an object.
Definition ref.h:191
static void sys_refcount_init(struct sys_refcount *const rc)
Initialize a reference counter to one.
Definition ref.h:69
static bool sys_refcount_dec(struct sys_refcount *const rc)
Decrement a reference counter.
Definition ref.h:112
static void sys_ref_init(struct sys_ref *const ref)
Initialize a reference to one.
Definition ref.h:176
void(* sys_ref_release_t)(struct sys_ref *const ref)
Release handler called once the last reference is dropped.
Definition ref.h:138
#define NULL
Definition iar_missing_defs.h:20
Reference of an object.
Definition ref.h:147
struct sys_refcount refcount
Reference counter.
Definition ref.h:149
Reference counter.
Definition ref.h:51
atomic_t value
Counter value.
Definition ref.h:53
Header file for the Atomic operations API.