[refcnt] Fix embedded image building
[gpxe.git] / src / include / gpxe / refcnt.h
1 #ifndef _GPXE_REFCNT_H
2 #define _GPXE_REFCNT_H
3
4 /** @file
5  *
6  * Reference counting
7  *
8  */
9
10 FILE_LICENCE ( GPL2_OR_LATER );
11
12 /**
13  * A reference counter
14  *
15  * This data structure is designed to be embedded within a
16  * reference-counted object.
17  *
18  * Reference-counted objects are freed when their reference count
19  * drops below zero.  This means that a freshly allocated-and-zeroed
20  * reference-counted object will be freed on the first call to
21  * ref_put().
22  */
23 struct refcnt {
24         /** Current reference count
25          *
26          * When this count is decremented below zero, the free()
27          * method will be called.
28          */
29         int refcnt;
30         /** Free containing object
31          *
32          * This method is called when the reference count is
33          * decremented below zero.
34          *
35          * If this method is left NULL, the standard library free()
36          * function will be called.  The upshot of this is that you
37          * may omit the free() method if the @c refcnt object is the
38          * first element of your reference-counted struct.
39          */
40         void ( * free ) ( struct refcnt *refcnt );
41 };
42
43 /**
44  * Initialise a reference counter
45  *
46  * @v refcnt            Reference counter
47  * @v free              Freeing function
48  */
49 static inline __attribute__ (( always_inline )) void
50 ref_init ( struct refcnt *refcnt,
51            void ( * free ) ( struct refcnt *refcnt ) ) {
52         refcnt->free = free;
53 }
54
55 /**
56  * Initialise a reference counter
57  *
58  * @v refcnt            Reference counter
59  * @v free              Free containing object
60  */
61 #define ref_init( refcnt, free ) do {                                   \
62         if ( __builtin_constant_p ( (free) ) && ( (free) == NULL ) ) {  \
63                 /* Skip common case of no initialisation required */    \
64         } else {                                                        \
65                 ref_init ( (refcnt), (free) );                          \
66         }                                                               \
67         } while ( 0 )
68
69 /**
70  * Initialise a static reference counter
71  *
72  * @v free_fn           Free containing object
73  */
74 #define REF_INIT( free_fn ) {                                           \
75                 .free = free_fn,                                        \
76         }
77
78 extern struct refcnt * ref_get ( struct refcnt *refcnt );
79 extern void ref_put ( struct refcnt *refcnt );
80 extern void ref_no_free ( struct refcnt *refcnt );
81
82 #endif /* _GPXE_REFCNT_H */