iPXE
refcnt.h
Go to the documentation of this file.
1#ifndef _IPXE_REFCNT_H
2#define _IPXE_REFCNT_H
3
4/** @file
5 *
6 * Reference counting
7 *
8 */
9
10FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11FILE_SECBOOT ( PERMITTED );
12
13#include <stddef.h>
14#include <assert.h>
15
16/**
17 * A reference counter
18 *
19 * This data structure is designed to be embedded within a
20 * reference-counted object.
21 *
22 * Reference-counted objects are freed when their reference count
23 * drops below zero. This means that a freshly allocated-and-zeroed
24 * reference-counted object will be freed on the first call to
25 * ref_put().
26 */
27struct refcnt {
28 /** Current reference count
29 *
30 * When this count is decremented below zero, the free()
31 * method will be called.
32 */
33 int count;
34 /** Free containing object
35 *
36 * This method is called when the reference count is
37 * decremented below zero.
38 *
39 * If this method is left NULL, the standard library free()
40 * function will be called. The upshot of this is that you
41 * may omit the free() method if the @c refcnt object is the
42 * first element of your reference-counted struct.
43 */
44 void ( * free ) ( struct refcnt *refcnt );
45};
46
47/**
48 * Initialise a reference counter
49 *
50 * @v refcnt Reference counter
51 * @v free Freeing function
52 */
53static inline __attribute__ (( always_inline )) void
54ref_init ( struct refcnt *refcnt,
55 void ( * free ) ( struct refcnt *refcnt ) ) {
56 refcnt->free = free;
57}
58
59/**
60 * Initialise a reference counter
61 *
62 * @v refcnt Reference counter
63 * @v free Free containing object
64 */
65#define ref_init( refcnt, free ) do { \
66 if ( __builtin_constant_p ( (free) ) && ( (free) == NULL ) ) { \
67 /* Skip common case of no initialisation required */ \
68 } else { \
69 ref_init ( (refcnt), (free) ); \
70 } \
71 } while ( 0 )
72
73/**
74 * Initialise a static reference counter
75 *
76 * @v free_fn Free containing object
77 */
78#define REF_INIT( free_fn ) { \
79 .free = free_fn, \
80 }
81
82extern void ref_increment ( struct refcnt *refcnt );
83extern void ref_decrement ( struct refcnt *refcnt );
84
85/**
86 * Get additional reference to object
87 *
88 * @v refcnt Reference counter, or NULL
89 * @ret refcnt Reference counter
90 *
91 * If @c refcnt is NULL, no action is taken.
92 */
93#define ref_get( refcnt ) ( { \
94 if ( refcnt ) \
95 assert ( (refcnt)->count >= 0 ); \
96 ref_increment ( refcnt ); \
97 (refcnt); } )
98
99/**
100 * Drop reference to object
101 *
102 * @v refcnt Reference counter, or NULL
103 * @ret refcnt Reference counter
104 *
105 * If @c refcnt is NULL, no action is taken.
106 */
107#define ref_put( refcnt ) do { \
108 if ( refcnt ) \
109 assert ( (refcnt)->count >= 0 ); \
110 ref_decrement ( refcnt ); \
111 } while ( 0 )
112
113extern void ref_no_free ( struct refcnt *refcnt );
114
115#endif /* _IPXE_REFCNT_H */
Assertions.
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define __attribute__(x)
Definition compiler.h:10
void ref_no_free(struct refcnt *refcnt)
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
void ref_increment(struct refcnt *refcnt)
Increment reference count.
Definition refcnt.c:43
void ref_decrement(struct refcnt *refcnt)
Decrement reference count.
Definition refcnt.c:62
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
A reference counter.
Definition refcnt.h:27
int count
Current reference count.
Definition refcnt.h:33
void(* free)(struct refcnt *refcnt)
Free containing object.
Definition refcnt.h:44