PatchworkOS
Loading...
Searching...
No Matches
ref.h
Go to the documentation of this file.
1#pragma once
2
3#include <kernel/defs.h>
4
5#include <assert.h>
6#include <stdatomic.h>
7#include <stdint.h>
8
19#define REF_MAGIC 0x26CB6E4C
20
29typedef struct ref
30{
31#ifndef NDEBUG
36#endif
40 atomic_uint32_t count;
44 void (*free)(void* self);
45} ref_t;
46
54#define DEREF_DEFER(ptr) __attribute__((cleanup(ref_defer_cleanup))) void* CONCAT(p, __COUNTER__) = (ptr)
55
65#define REF(ptr) \
66 ({ \
67 ref_t* ref = (ref_t*)ptr; \
68 ref_inc(ref); \
69 ptr; \
70 })
71
80#define DEREF(ptr) \
81 ({ \
82 ref_t* ref = (ref_t*)ptr; \
83 ref_dec(ref); \
84 })
85
92static inline void ref_init(ref_t* ref, void* free)
93{
94#ifndef NDEBUG
95 ref->magic = REF_MAGIC;
96#endif
97 atomic_init(&ref->count, 1);
98 ref->free = free;
99}
100
107static inline void* ref_inc(void* ptr)
108{
109 ref_t* ref = (ref_t*)ptr;
110 if (ref == NULL)
111 {
112 return NULL;
113 }
114
115 assert(ref->magic == REF_MAGIC);
117 return ptr;
118}
119
127static inline void ref_dec(void* ptr)
128{
129 ref_t* ref = (ref_t*)ptr;
130 if (ref == NULL)
131 {
132 return;
133 }
134
135 assert(ref->magic == REF_MAGIC);
137 if (count > 1)
138 {
139 return;
140 }
141
143 assert(count == 1); // Count is now zero, if it was zero before then we have a double free.
144 if (ref->free == NULL)
145 {
146 return;
147 }
148
149#ifndef NDEBUG
150 ref->magic = 0;
151#endif
152 ref->free(ptr);
153}
154
155static inline void ref_defer_cleanup(void** ptr)
156{
157 ref_dec(*ptr);
158}
159
#define assert(expression)
Definition assert.h:29
static void ref_defer_cleanup(void **ptr)
Definition ref.h:155
static void ref_dec(void *ptr)
Decrement reference count.
Definition ref.h:127
static void ref_init(ref_t *ref, void *free)
Initialize a reference counter.
Definition ref.h:92
#define REF_MAGIC
Magic value used in debug builds to check for corruption or invalid use of the ref_t structure.
Definition ref.h:19
static void * ref_inc(void *ptr)
Increment reference count.
Definition ref.h:107
#define NULL
Pointer error value.
Definition NULL.h:23
static atomic_long count
Definition main.c:9
@ memory_order_relaxed
Definition stdatomic.h:116
@ memory_order_acquire
Definition stdatomic.h:118
#define atomic_fetch_add_explicit(object, operand, order)
Definition stdatomic.h:259
#define atomic_thread_fence(order)
Definition stdatomic.h:135
#define atomic_init(obj, value)
Definition stdatomic.h:75
#define atomic_fetch_sub_explicit(object, operand, order)
Definition stdatomic.h:262
__UINT32_TYPE__ uint32_t
Definition stdint.h:15
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
_PUBLIC void free(void *ptr)
Definition free.c:11
Reference counting structure.
Definition ref.h:30
atomic_uint32_t count
Atomic reference counter.
Definition ref.h:40
void(* free)(void *self)
Cleanup function called when count reaches zero.
Definition ref.h:44
uint32_t magic
Debug magic value to detect corruption.
Definition ref.h:35