(no commit message)
[geda-pcb/pcjc2.git] / src / free_atexit.c
blob6527a464bf2d769dd9c28dd40598cbc3dda147ad
1 /* COPYRIGHT
3 * Copyright (C) 2010 PCB Contributors (see ChangeLog for details)
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 * Contact addresses for paper mail and Email:
20 * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA
21 * haceaton@aplcomm.jhuapl.edu
25 #include <stdlib.h>
26 #include <string.h>
28 /* we need one ID per context - short int with 64k IDs should be enough */
29 typedef unsigned int leaky_idx_t;
32 /* This structure should be as big as void *, which should be the natural
33 bit-width of the architecture. We allocate extra admin space to be as big
34 as this union, to preserve alignment of pointers returned by malloc().
35 NOTE: in the special corner case when leaky_idx_t is wider than void * but
36 not multiple of it, the alignment will be messed up, potentially causing slower
37 memory access. */
38 typedef union {
39 leaky_idx_t idx;
40 void *ptr;
41 } leaky_admin_t;
43 static void **free_list = NULL;
44 static leaky_idx_t free_size = 0;
47 void *leaky_malloc (size_t size)
49 void *new_memory = malloc(size + sizeof(leaky_admin_t));
51 free_list = (void **)realloc (free_list, (free_size + 1) * sizeof(void *));
52 free_list[free_size] = new_memory;
53 *(leaky_idx_t *)new_memory = free_size;
55 free_size++;
56 return new_memory + sizeof(leaky_admin_t);
59 void *leaky_calloc (size_t nmemb, size_t size)
61 size_t size_ = size * nmemb;
62 void *new_memory = leaky_malloc (size_);
64 memset (new_memory, 0, size_);
65 return new_memory;
68 void *leaky_realloc (void* old_memory, size_t size)
70 void *new_memory;
71 leaky_idx_t i;
73 if (old_memory == NULL)
74 return leaky_malloc (size);
76 old_memory -= sizeof(leaky_admin_t);
78 i = *(leaky_idx_t *)old_memory;
80 new_memory = realloc (old_memory, size + sizeof(leaky_admin_t));
81 free_list[i] = new_memory;
83 return new_memory + sizeof(leaky_admin_t);
86 void leaky_uninit (void)
88 int i;
90 for (i = 0; i < free_size; i++)
91 free (free_list[i]);
93 free (free_list);
94 free_size = 0;
97 void leaky_init (void)
99 atexit(leaky_uninit);