2 This file is part of tgl-library
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or(at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 Copyright Vitaly Valtman 2013-2015
31 #include <openssl/err.h>
32 #include <openssl/rand.h>
40 #include <mach/clock.h>
41 #include <mach/mach.h>
45 #define CLOCK_REALTIME 0
46 #define CLOCK_MONOTONIC 1
51 #define MAX_BLOCKS 1000000
52 static void *blocks[MAX_BLOCKS];
53 static void *free_blocks[MAX_BLOCKS];
54 static int used_blocks;
55 static int free_blocks_cnt;
56 static long long total_allocated_bytes;
58 void logprintf(const char *format, ...) __attribute__((format(printf, 1, 2), weak));
60 void logprintf(const char *format, ...)
66 vsnprintf(buffer, sizeof(buffer), format, ap);
72 int tgl_snprintf(char *buf, int len, const char *format, ...)
76 int r = vsnprintf(buf, len, format, ap);
78 assert(r <= len && "tsnprintf buffer overflow");
82 int tgl_asprintf(char **res, const char *format, ...)
86 int r = vasprintf(res, format, ap);
89 void *rs = talloc(strlen(*res) + 1);
90 memcpy(rs, *res, strlen(*res) + 1);
96 void tgl_free_debug(void *ptr, int size __attribute__((unused)))
98 total_allocated_bytes -= size;
100 if (size !=(int)((*(int *)ptr) ^ 0xbedabeda)) {
101 logprintf("size = %d, ptr = %d\n", size,(*(int *)ptr) ^ 0xbedabeda);
103 assert(*(int *)ptr ==(int)((size) ^ 0xbedabeda));
104 assert(*(int *)(ptr + RES_PRE + size) ==(int)((size) ^ 0x7bed7bed));
105 assert(*(int *)(ptr + 4) == size);
106 int block_num = *(int *)(ptr + 4 + RES_PRE + size);
107 if (block_num >= used_blocks) {
108 logprintf("block_num = %d, used = %d\n", block_num, used_blocks);
110 assert(block_num < used_blocks);
111 if (block_num < used_blocks - 1) {
112 void *p = blocks[used_blocks - 1];
113 int s =(*(int *)p) ^ 0xbedabeda;
114 *(int *)(p + 4 + RES_PRE + s) = block_num;
115 blocks[block_num] = p;
117 blocks[--used_blocks] = 0;
118 memset(ptr, 0, size + RES_PRE + RES_AFTER);
119 *(int *)ptr = size + 12;
120 free_blocks[free_blocks_cnt ++] = ptr;
123 void tgl_free_release(void *ptr, int size)
128 void *tgl_realloc_debug(void *ptr, size_t old_size __attribute__((unused)), size_t size)
130 void *p = talloc(size);
131 memcpy(p, ptr, size >= old_size ? old_size : size);
132 tfree(ptr, old_size);
136 void *tgl_realloc_release(void *ptr, size_t old_size __attribute__((unused)), size_t size)
138 void *p = realloc(ptr, size);
143 void *tgl_alloc_debug(size_t size)
145 total_allocated_bytes += size;
146 void *p = malloc(size + RES_PRE + RES_AFTER);
148 *(int *)p = size ^ 0xbedabeda;
149 *(int *)(p + 4) = size;
150 *(int *)(p + RES_PRE + size) = size ^ 0x7bed7bed;
151 *(int *)(p + RES_AFTER + 4 + size) = used_blocks;
152 blocks[used_blocks ++] = p;
154 if (used_blocks - 1 == 24867) {
161 void *tgl_alloc_release(size_t size)
163 void *p = malloc(size);
168 void *tgl_alloc0(size_t size)
170 void *p = talloc(size);
175 char *tgl_strdup(const char *s)
178 char *p = talloc(l + 1);
183 char *tgl_strndup(const char *s, size_t n)
186 for (l = 0; l < n && s[l]; l++) { }
187 char *p = talloc(l + 1);
193 int tgl_inflate(void *input, int ilen, void *output, int olen)
196 memset(&strm, 0, sizeof(strm));
197 assert(inflateInit2(&strm, 16 + MAX_WBITS) == Z_OK);
198 strm.avail_in = ilen;
199 strm.next_in = input;
200 strm.avail_out = olen ;
201 strm.next_out = output;
202 int err = inflate(&strm, Z_FINISH);
203 int total_out = strm.total_out;
205 if (err != Z_OK && err != Z_STREAM_END) {
206 logprintf( "inflate error = %d\n", err);
207 logprintf( "inflated %d bytes\n",(int) strm.total_out);
214 void tgl_check_debug(void)
217 for (i = 0; i < used_blocks; i++) {
218 void *ptr = blocks[i];
219 int size =(*(int *)ptr) ^ 0xbedabeda;
220 if (!(*(int *)(ptr + 4) == size) ||
221 !(*(int *)(ptr + RES_PRE + size) ==(size ^ 0x7bed7bed)) ||
222 !(*(int *)(ptr + RES_PRE + 4 + size) == i)) {
223 logprintf("Bad block at address %p(size %d, num %d)\n", ptr, size, i);
224 assert(0 && "Bad block");
227 for (i = 0; i < free_blocks_cnt; i++) {
228 void *ptr = free_blocks[i];
231 for (j = 0; j < l; j++) {
232 if (*(char *)(ptr + 4 + j)) {
233 hexdump(ptr + 8, ptr + 8 + l +((-l) & 3));
234 logprintf("Used freed memory size = %d. ptr = %p\n", l + 4 - RES_PRE - RES_AFTER, ptr);
241 void tgl_exists_debug(void *ptr, int size)
244 if (size !=(int)((*(int *)ptr) ^ 0xbedabeda)) {
245 logprintf("size = %d, ptr = %d\n", size,(*(int *)ptr) ^ 0xbedabeda);
247 assert(*(int *)ptr ==(int)((size) ^ 0xbedabeda));
248 assert(*(int *)(ptr + RES_PRE + size) ==(int)((size) ^ 0x7bed7bed));
249 assert(*(int *)(ptr + 4) == size);
250 int block_num = *(int *)(ptr + 4 + RES_PRE + size);
251 if (block_num >= used_blocks) {
252 logprintf("block_num = %d, used = %d\n", block_num, used_blocks);
254 assert(block_num < used_blocks);
257 void tgl_exists_release(void *ptr, int size)
262 void tgl_check_release(void)
267 void tgl_my_clock_gettime(int clock_id, struct timespec *T)
270 // We are ignoring MONOTONIC and hope time doesn't go back too often
273 host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
274 clock_get_time(cclock, &mts);
275 mach_port_deallocate(mach_task_self(), cclock);
276 T->tv_sec = mts.tv_sec;
277 T->tv_nsec = mts.tv_nsec;
279 assert(clock_gettime(clock_id, T) >= 0);
283 double tglt_get_double_time(void)
286 tgl_my_clock_gettime(CLOCK_REALTIME, &tv);
287 return tv.tv_sec + 1e-9 * tv.tv_nsec;
290 void tglt_secure_random(void *s, int l)
292 if (RAND_bytes(s, l) <= 0) {
293 /*if (allow_weak_random) {
294 RAND_pseudo_bytes(s, l);
296 assert(0 && "End of random. If you want, you can start with -w");
301 struct tgl_allocator tgl_allocator_debug = {
302 .alloc = tgl_alloc_debug,
303 .realloc = tgl_realloc_debug,
304 .free = tgl_free_debug,
305 .check = tgl_check_debug,
306 .exists = tgl_exists_debug
309 struct tgl_allocator tgl_allocator_release = {
310 .alloc = tgl_alloc_release,
311 .realloc = tgl_realloc_release,
312 .free = tgl_free_release,
313 .check = tgl_check_release,
314 .exists = tgl_exists_release
317 struct tgl_allocator *tgl_allocator = &tgl_allocator_release;