]>
Commit | Line | Data |
---|---|---|
2a6a7a65 DL |
1 | .. highlight:: c |
2 | ||
3 | Memtypes | |
4 | ======== | |
5 | ||
56f0bea7 | 6 | FRR includes wrappers around ``malloc()`` and ``free()`` that count the number |
2a6a7a65 DL |
7 | of objects currently allocated, for each of a defined ``MTYPE``. |
8 | ||
75ca3b11 | 9 | To this extent, there are *memory groups* and *memory types*. Each memory |
2a6a7a65 DL |
10 | type must belong to a memory group, this is used just to provide some basic |
11 | structure. | |
12 | ||
13 | Example: | |
14 | ||
15 | .. code-block:: c | |
75ca3b11 | 16 | :caption: mydaemon.h |
2a6a7a65 | 17 | |
bf8d3d6a DL |
18 | DECLARE_MGROUP(MYDAEMON); |
19 | DECLARE_MTYPE(MYNEIGHBOR); | |
2a6a7a65 DL |
20 | |
21 | .. code-block:: c | |
75ca3b11 QY |
22 | :caption: mydaemon.c |
23 | ||
bf8d3d6a DL |
24 | DEFINE_MGROUP( MYDAEMON, "My daemon's memory"); |
25 | DEFINE_MTYPE( MYDAEMON, MYNEIGHBOR, "Neighbor entry"); | |
26 | DEFINE_MTYPE_STATIC(MYDAEMON, MYNEIGHBORNAME, "Neighbor name"); | |
75ca3b11 QY |
27 | |
28 | struct neigh *neighbor_new(const char *name) | |
29 | { | |
30 | struct neigh *n = XMALLOC(MYNEIGHBOR, sizeof(*n)); | |
31 | n->name = XSTRDUP(MYNEIGHBORNAME, name); | |
32 | return n; | |
33 | } | |
34 | ||
35 | void neighbor_free(struct neigh *n) | |
36 | { | |
37 | XFREE(MYNEIGHBORNAME, n->name); | |
38 | XFREE(MYNEIGHBOR, n); | |
39 | } | |
2a6a7a65 DL |
40 | |
41 | ||
42 | Definition | |
43 | ---------- | |
44 | ||
936c12d7 | 45 | .. c:struct:: memtype |
056830ba DL |
46 | |
47 | This is the (internal) type used for MTYPE definitions. The macros below | |
48 | should be used to create these, but in some cases it is useful to pass a | |
49 | ``struct memtype *`` pointer to some helper function. | |
50 | ||
4d8ebedd | 51 | The ``MTYPE_name`` created by the macros is declared as a pointer, i.e. |
056830ba DL |
52 | a function taking a ``struct memtype *`` argument can be called with an |
53 | ``MTYPE_name`` argument (as opposed to ``&MTYPE_name``.) | |
54 | ||
ee46da26 JW |
55 | .. note:: |
56 | ||
57 | As ``MTYPE_name`` is a variable assigned from ``&_mt_name`` and not a | |
58 | constant expression, it cannot be used as initializer for static | |
59 | variables. In the case please fall back to ``&_mt_name``. | |
60 | ||
2a6a7a65 DL |
61 | .. c:macro:: DECLARE_MGROUP(name) |
62 | ||
63 | This macro forward-declares a memory group and should be placed in a | |
64 | ``.h`` file. It expands to an ``extern struct memgroup`` statement. | |
65 | ||
66 | .. c:macro:: DEFINE_MGROUP(mname, description) | |
67 | ||
68 | Defines/implements a memory group. Must be placed into exactly one ``.c`` | |
69 | file (multiple inclusion will result in a link-time symbol conflict). | |
70 | ||
71 | Contains additional logic (constructor and destructor) to register the | |
72 | memory group in a global list. | |
73 | ||
74 | .. c:macro:: DECLARE_MTYPE(name) | |
75 | ||
76 | Forward-declares a memory type and makes ``MTYPE_name`` available for use. | |
77 | Note that the ``MTYPE_`` prefix must not be included in the name, it is | |
78 | automatically prefixed. | |
79 | ||
80 | ``MTYPE_name`` is created as a `static const` symbol, i.e. a compile-time | |
81 | constant. It refers to an ``extern struct memtype _mt_name``, where `name` | |
82 | is replaced with the actual name. | |
83 | ||
84 | .. c:macro:: DEFINE_MTYPE(group, name, description) | |
85 | ||
86 | Define/implement a memory type, must be placed into exactly one ``.c`` | |
87 | file (multiple inclusion will result in a link-time symbol conflict). | |
88 | ||
89 | Like ``DEFINE_MGROUP``, this contains actual code to register the MTYPE | |
90 | under its group. | |
91 | ||
92 | .. c:macro:: DEFINE_MTYPE_STATIC(group, name, description) | |
93 | ||
94 | Same as ``DEFINE_MTYPE``, but the ``DEFINE_MTYPE_STATIC`` variant places | |
95 | the C ``static`` keyword on the definition, restricting the MTYPE's | |
96 | availability to the current source file. This should be appropriate in | |
97 | >80% of cases. | |
98 | ||
99 | .. todo:: | |
76bd1499 | 100 | |
2a6a7a65 DL |
101 | Daemons currently have ``daemon_memory.[ch]`` files listing all of |
102 | their MTYPEs. This is not how it should be, most of these types | |
103 | should be moved into the appropriate files where they are used. | |
104 | Only a few MTYPEs should remain non-static after that. | |
105 | ||
106 | ||
107 | Usage | |
108 | ----- | |
109 | ||
110 | .. c:function:: void *XMALLOC(struct memtype *mtype, size_t size) | |
111 | ||
112 | .. c:function:: void *XCALLOC(struct memtype *mtype, size_t size) | |
113 | ||
5ba33197 | 114 | .. c:function:: void *XSTRDUP(struct memtype *mtype, const char *name) |
2a6a7a65 DL |
115 | |
116 | Allocation wrappers for malloc/calloc/realloc/strdup, taking an extra | |
117 | mtype parameter. | |
118 | ||
119 | .. c:function:: void *XREALLOC(struct memtype *mtype, void *ptr, size_t size) | |
120 | ||
121 | Wrapper around realloc() with MTYPE tracking. Note that ``ptr`` may | |
122 | be NULL, in which case the function does the same as XMALLOC (regardless | |
123 | of whether the system realloc() supports this.) | |
124 | ||
125 | .. c:function:: void XFREE(struct memtype *mtype, void *ptr) | |
126 | ||
127 | Wrapper around free(), again taking an extra mtype parameter. This is | |
128 | actually a macro, with the following additional properties: | |
129 | ||
130 | - the macro contains ``ptr = NULL`` | |
131 | - if ptr is NULL, no operation is performed (as is guaranteed by system | |
132 | implementations.) Do not surround XFREE with ``if (ptr != NULL)`` | |
133 | checks. | |
fdac05fd IR |
134 | |
135 | .. c:function:: void XCOUNTFREE(struct memtype *mtype, void *ptr) | |
136 | ||
137 | This macro is used to count the ``ptr`` as freed without actually freeing | |
138 | it. This may be needed in some very specific cases, for example, when the | |
139 | ``ptr`` was allocated using any of the above wrappers and will be freed | |
140 | by some external library using simple ``free()``. |