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