]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/memory.h
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[mirror_frr.git] / lib / memory.h
index 9e8803a8b2a6dbc1881df66e050cfe83c2072c4a..2d6c1447786a467d39fc147acb981947380ad996 100644 (file)
 #define _QUAGGA_MEMORY_H
 
 #include <stdlib.h>
+#include <stdio.h>
 #include <frratomic.h>
+#include "compiler.h"
 
 #define array_size(ar) (sizeof(ar) / sizeof(ar[0]))
 
+#if defined(HAVE_MALLOC_SIZE) && !defined(HAVE_MALLOC_USABLE_SIZE)
+#define malloc_usable_size(x) malloc_size(x)
+#define HAVE_MALLOC_USABLE_SIZE
+#endif
+
 #define SIZE_VAR ~0UL
 struct memtype {
        struct memtype *next, **ref;
        const char *name;
        _Atomic size_t n_alloc;
+       _Atomic size_t n_max;
        _Atomic size_t size;
+#ifdef HAVE_MALLOC_USABLE_SIZE
+       _Atomic size_t total;
+       _Atomic size_t max_size;
+#endif
 };
 
 struct memgroup {
@@ -36,41 +48,6 @@ struct memgroup {
        const char *name;
 };
 
-#if defined(__clang__)
-# if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 5)
-#  define _RET_NONNULL  , returns_nonnull
-# endif
-# define _CONSTRUCTOR(x) constructor(x)
-#elif defined(__GNUC__)
-# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
-#  define _RET_NONNULL  , returns_nonnull
-# endif
-# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
-#  define _CONSTRUCTOR(x) constructor(x)
-#  define _DESTRUCTOR(x)  destructor(x)
-#  define _ALLOC_SIZE(x)  alloc_size(x)
-# endif
-#endif
-
-#ifdef __sun
-/* Solaris doesn't do constructor priorities due to linker restrictions */
-# undef _CONSTRUCTOR
-# undef _DESTRUCTOR
-#endif
-
-#ifndef _RET_NONNULL
-# define _RET_NONNULL
-#endif
-#ifndef _CONSTRUCTOR
-# define _CONSTRUCTOR(x) constructor
-#endif
-#ifndef _DESTRUCTOR
-# define _DESTRUCTOR(x) destructor
-#endif
-#ifndef _ALLOC_SIZE
-# define _ALLOC_SIZE(x)
-#endif
-
 /* macro usage:
  *
  *  mydaemon.h
@@ -96,81 +73,92 @@ struct memgroup {
  *         but MGROUP_* aren't.
  */
 
-#define DECLARE_MGROUP(name) \
-       extern struct memgroup _mg_##name;
-#define DEFINE_MGROUP(mname, desc) \
-       struct memgroup _mg_##mname \
-       __attribute__ ((section (".data.mgroups"))) = { \
-               .name = desc, \
-               .types = NULL, .next = NULL, .insert = NULL, .ref = NULL, \
-       }; \
-       static void _mginit_##mname (void) \
-         __attribute__ ((_CONSTRUCTOR (1000))); \
-       static void _mginit_##mname (void) \
-       {       extern struct memgroup **mg_insert; \
-               _mg_##mname.ref = mg_insert; \
-               *mg_insert = &_mg_##mname; \
-               mg_insert =  &_mg_##mname.next; } \
-       static void _mgfini_##mname (void) \
-         __attribute__ ((_DESTRUCTOR (1000))); \
-       static void _mgfini_##mname (void) \
-       {       if (_mg_##mname.next) \
-                       _mg_##mname.next->ref = _mg_##mname.ref; \
-               *_mg_##mname.ref = _mg_##mname.next; }
-
-
-#define DECLARE_MTYPE(name) \
-       extern struct memtype _mt_##name; \
-       static struct memtype * const MTYPE_ ## name = &_mt_##name;
-
-#define DEFINE_MTYPE_ATTR(group, mname, attr, desc) \
-       attr struct memtype _mt_##mname \
-       __attribute__ ((section (".data.mtypes"))) = { \
-               .name = desc, \
-               .next = NULL, .n_alloc = 0, .size = 0, .ref = NULL, \
-       }; \
-       static void _mtinit_##mname (void) \
-         __attribute__ ((_CONSTRUCTOR (1001))); \
-       static void _mtinit_##mname (void) \
-       {       if (_mg_##group.insert == NULL) \
-                       _mg_##group.insert = &_mg_##group.types; \
-               _mt_##mname.ref = _mg_##group.insert; \
-               *_mg_##group.insert = &_mt_##mname; \
-               _mg_##group.insert =  &_mt_##mname.next; } \
-       static void _mtfini_##mname (void) \
-         __attribute__ ((_DESTRUCTOR (1001))); \
-       static void _mtfini_##mname (void) \
-       {       if (_mt_##mname.next) \
-                       _mt_##mname.next->ref = _mt_##mname.ref; \
-               *_mt_##mname.ref = _mt_##mname.next; }
-
-#define DEFINE_MTYPE(group, name, desc) \
-       DEFINE_MTYPE_ATTR(group, name, , desc)
-#define DEFINE_MTYPE_STATIC(group, name, desc) \
-       DEFINE_MTYPE_ATTR(group, name, static, desc) \
-       static struct memtype * const MTYPE_ ## name = &_mt_##name;
+#define DECLARE_MGROUP(name) extern struct memgroup _mg_##name;
+#define DEFINE_MGROUP(mname, desc)                                             \
+       struct memgroup _mg_##mname                                            \
+               __attribute__((section(".data.mgroups"))) = {                  \
+                       .name = desc,                                          \
+                       .types = NULL,                                         \
+                       .next = NULL,                                          \
+                       .insert = NULL,                                        \
+                       .ref = NULL,                                           \
+       };                                                                     \
+       static void _mginit_##mname(void) __attribute__((_CONSTRUCTOR(1000))); \
+       static void _mginit_##mname(void)                                      \
+       {                                                                      \
+               extern struct memgroup **mg_insert;                            \
+               _mg_##mname.ref = mg_insert;                                   \
+               *mg_insert = &_mg_##mname;                                     \
+               mg_insert = &_mg_##mname.next;                                 \
+       }                                                                      \
+       static void _mgfini_##mname(void) __attribute__((_DESTRUCTOR(1000)));  \
+       static void _mgfini_##mname(void)                                      \
+       {                                                                      \
+               if (_mg_##mname.next)                                          \
+                       _mg_##mname.next->ref = _mg_##mname.ref;               \
+               *_mg_##mname.ref = _mg_##mname.next;                           \
+       }
+
+
+#define DECLARE_MTYPE(name)                                                    \
+       extern struct memtype _mt_##name;                                      \
+       static struct memtype *const MTYPE_##name = &_mt_##name;
+
+#define DEFINE_MTYPE_ATTR(group, mname, attr, desc)                            \
+       attr struct memtype _mt_##mname                                        \
+               __attribute__((section(".data.mtypes"))) = {                   \
+                       .name = desc,                                          \
+                       .next = NULL,                                          \
+                       .n_alloc = 0,                                          \
+                       .size = 0,                                             \
+                       .ref = NULL,                                           \
+       };                                                                     \
+       static void _mtinit_##mname(void) __attribute__((_CONSTRUCTOR(1001))); \
+       static void _mtinit_##mname(void)                                      \
+       {                                                                      \
+               if (_mg_##group.insert == NULL)                                \
+                       _mg_##group.insert = &_mg_##group.types;               \
+               _mt_##mname.ref = _mg_##group.insert;                          \
+               *_mg_##group.insert = &_mt_##mname;                            \
+               _mg_##group.insert = &_mt_##mname.next;                        \
+       }                                                                      \
+       static void _mtfini_##mname(void) __attribute__((_DESTRUCTOR(1001)));  \
+       static void _mtfini_##mname(void)                                      \
+       {                                                                      \
+               if (_mt_##mname.next)                                          \
+                       _mt_##mname.next->ref = _mt_##mname.ref;               \
+               *_mt_##mname.ref = _mt_##mname.next;                           \
+       }
+
+#define DEFINE_MTYPE(group, name, desc) DEFINE_MTYPE_ATTR(group, name, , desc)
+#define DEFINE_MTYPE_STATIC(group, name, desc)                                 \
+       DEFINE_MTYPE_ATTR(group, name, static, desc)                           \
+       static struct memtype *const MTYPE_##name = &_mt_##name;
 
 DECLARE_MGROUP(LIB)
 DECLARE_MTYPE(TMP)
+DECLARE_MTYPE(PREFIX_FLOWSPEC)
 
 
 extern void *qmalloc(struct memtype *mt, size_t size)
-       __attribute__ ((malloc, _ALLOC_SIZE(2), nonnull (1) _RET_NONNULL));
+       __attribute__((malloc, _ALLOC_SIZE(2), nonnull(1) _RET_NONNULL));
 extern void *qcalloc(struct memtype *mt, size_t size)
-       __attribute__ ((malloc, _ALLOC_SIZE(2), nonnull (1) _RET_NONNULL));
+       __attribute__((malloc, _ALLOC_SIZE(2), nonnull(1) _RET_NONNULL));
 extern void *qrealloc(struct memtype *mt, void *ptr, size_t size)
-       __attribute__ ((_ALLOC_SIZE(3), nonnull (1) _RET_NONNULL));
-extern void *qstrdup (struct memtype *mt, const char *str)
-       __attribute__ ((malloc, nonnull (1) _RET_NONNULL));
-extern void qfree(struct memtype *mt, void *ptr)
-       __attribute__ ((nonnull (1)));
+       __attribute__((_ALLOC_SIZE(3), nonnull(1) _RET_NONNULL));
+extern void *qstrdup(struct memtype *mt, const char *str)
+       __attribute__((malloc, nonnull(1) _RET_NONNULL));
+extern void qfree(struct memtype *mt, void *ptr) __attribute__((nonnull(1)));
 
 #define XMALLOC(mtype, size)           qmalloc(mtype, size)
 #define XCALLOC(mtype, size)           qcalloc(mtype, size)
 #define XREALLOC(mtype, ptr, size)     qrealloc(mtype, ptr, size)
 #define XSTRDUP(mtype, str)            qstrdup(mtype, str)
-#define XFREE(mtype, ptr)              do { qfree(mtype, ptr); ptr = NULL; } \
-                                       while (0)
+#define XFREE(mtype, ptr)                                                      \
+       do {                                                                   \
+               qfree(mtype, ptr);                                             \
+               ptr = NULL;                                                    \
+       } while (0)
 
 static inline size_t mtype_stats_alloc(struct memtype *mt)
 {
@@ -184,7 +172,8 @@ static inline size_t mtype_stats_alloc(struct memtype *mt)
  * last value from qmem_walk_fn. */
 typedef int qmem_walk_fn(void *arg, struct memgroup *mg, struct memtype *mt);
 extern int qmem_walk(qmem_walk_fn *func, void *arg);
-extern void log_memstats_stderr(const char *);
+extern int log_memstats(FILE *fp, const char *);
+#define log_memstats_stderr(prefix) log_memstats(stderr, prefix)
 
 extern void memory_oom(size_t size, const char *name);