New memory allocators.
[libpwmd.git] / src / mem.c
blobf01e1d00e8f2069a0eb16bb194cb15e6492abc2b
1 /*
2 Copyright (C) 2016
3 Ben Kibbey <bjk@luxsci.net>
5 This file is part of libpwmd.
7 Libpwmd is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
12 Libpwmd is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with libpwmd. If not, see <http://www.gnu.org/licenses/>.
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <stddef.h>
30 #include "mem.h"
32 void *
33 _xrealloc_gpgrt (void *p, size_t n)
35 if (!n)
37 _xfree (p);
38 return NULL;
41 if (!p)
42 return _xmalloc (n);
44 return _xrealloc (p, n);
47 #ifndef MEM_DEBUG
49 /* To avoid that a compiler optimizes certain memset calls away, these
50 macros may be used instead. Thanks g10Code. */
51 #define wipememory(_ptr,_set,_len) do { \
52 volatile char *_vptr=(volatile char *)(_ptr); \
53 size_t _vlen=(_len); \
54 while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
55 } while(0)
57 struct memchunk_s
59 size_t size;
60 char data[1];
63 void
64 _xfree (void *ptr)
66 struct memchunk_s *m;
67 void *p;
69 if (!ptr)
70 return;
72 m = (struct memchunk_s *)((void *)ptr-(offsetof (struct memchunk_s, data)));
73 p = (void *)m+(offsetof (struct memchunk_s, data));
74 wipememory (p, 0, m->size);
75 free (m);
78 void *
79 _xmalloc (size_t size)
81 struct memchunk_s *m;
83 if (!size)
84 return NULL;
86 m = malloc (sizeof (struct memchunk_s)+size);
87 if (!m)
88 return NULL;
90 m->size = size;
91 return (void *)m+(offsetof (struct memchunk_s, data));
94 void *
95 _xcalloc (size_t nmemb, size_t size)
97 void *p;
98 struct memchunk_s *m;
100 m = malloc (sizeof (struct memchunk_s)+(nmemb*size));
101 if (!m)
102 return NULL;
104 m->size = nmemb*size;
105 p = (void *)m+(offsetof (struct memchunk_s, data));
106 memset (p, 0, m->size);
107 return p;
110 void *
111 _xrealloc (void *ptr, size_t size)
113 void *p, *np;
114 struct memchunk_s *m, *mp;
115 size_t n;
117 if (!size && ptr)
119 m = (struct memchunk_s *)((void *)ptr-(offsetof (struct memchunk_s, data)));
120 p = (void *)m+(offsetof (struct memchunk_s, data));
121 wipememory (p, 0, m->size);
122 free (m);
123 return NULL;
125 else if (!ptr)
126 return _xmalloc (size);
128 m = malloc (sizeof (struct memchunk_s)+size);
129 if (!m)
130 return NULL;
132 m->size = size;
133 np = (void *)m+(offsetof (struct memchunk_s, data));
135 mp = (struct memchunk_s *)((void *)ptr-(offsetof (struct memchunk_s, data)));
136 p = (void *)mp+(offsetof (struct memchunk_s, data));
138 n = size > mp->size ? mp->size : size;
139 memcpy (np, p, n);
140 wipememory (p, 0, mp->size);
142 free (mp);
143 return (void *)m+(offsetof (struct memchunk_s, data));
145 #endif