140 lines
4.7 KiB
ReStructuredText
140 lines
4.7 KiB
ReStructuredText
.. highlight:: c
|
|
|
|
Memtypes
|
|
========
|
|
|
|
FRR includes wrappers around ``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:struct:: memtype
|
|
|
|
This is the (internal) type used for MTYPE definitions. The macros below
|
|
should be used to create these, but in some cases it is useful to pass a
|
|
``struct memtype *`` pointer to some helper function.
|
|
|
|
The ``MTYPE_name`` created by the macros is declared as a pointer, i.e.
|
|
a function taking a ``struct memtype *`` argument can be called with an
|
|
``MTYPE_name`` argument (as opposed to ``&MTYPE_name``.)
|
|
|
|
.. note::
|
|
|
|
As ``MTYPE_name`` is a variable assigned from ``&_mt_name`` and not a
|
|
constant expression, it cannot be used as initializer for static
|
|
variables. In the case please fall back to ``&_mt_name``.
|
|
|
|
.. 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, const char *name)
|
|
|
|
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.
|
|
|
|
.. c:function:: void XCOUNTFREE(struct memtype *mtype, void *ptr)
|
|
|
|
This macro is used to count the ``ptr`` as freed without actually freeing
|
|
it. This may be needed in some very specific cases, for example, when the
|
|
``ptr`` was allocated using any of the above wrappers and will be freed
|
|
by some external library using simple ``free()``.
|