2 * \file src/free_atexit.c
8 * <h1><b>Copyright.</b></h1>\n
10 * Copyright (C) 2010 PCB Contributors (see ChangeLog for details)
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 * Contact addresses for paper mail and Email:
27 * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA
28 * haceaton@aplcomm.jhuapl.edu
35 * \brief We need one ID per context - short int with 64k IDs should be
38 typedef unsigned int leaky_idx_t
;
44 * This structure should be as big as void *, which should be the
45 * natural bit-width of the architecture.\n
46 * We allocate extra admin space to be as big as this union, to preserve
47 * alignment of pointers returned by malloc().\n
49 * \note In the special corner case when leaky_idx_t is wider than
50 * void * but not multiple of it, the alignment will be messed up,
51 * potentially causing slower memory access.
58 static void **free_list
= NULL
;
59 static leaky_idx_t free_size
= 0;
63 * \brief Allocate memory, remember the pointer and free it after exit
64 * from the application.
66 void *leaky_malloc (size_t size
)
68 void *new_memory
= malloc(size
+ sizeof(leaky_admin_t
));
70 free_list
= (void **)realloc (free_list
, (free_size
+ 1) * sizeof(void *));
71 free_list
[free_size
] = new_memory
;
72 *(leaky_idx_t
*)new_memory
= free_size
;
75 return new_memory
+ sizeof(leaky_admin_t
);
79 * \brief Same as leaky_malloc but this one wraps calloc().
81 void *leaky_calloc (size_t nmemb
, size_t size
)
83 size_t size_
= size
* nmemb
;
84 void *new_memory
= leaky_malloc (size_
);
86 memset (new_memory
, 0, size_
);
91 * \brief Reallocate memory, remember the new pointer and free it after
92 * exit from the application.
94 void *leaky_realloc (void* old_memory
, size_t size
)
99 if (old_memory
== NULL
)
100 return leaky_malloc (size
);
102 old_memory
-= sizeof(leaky_admin_t
);
104 i
= *(leaky_idx_t
*)old_memory
;
106 new_memory
= realloc (old_memory
, size
+ sizeof(leaky_admin_t
));
107 free_list
[i
] = new_memory
;
109 return new_memory
+ sizeof(leaky_admin_t
);
113 * \brief Free all allocations.
115 void leaky_uninit (void)
119 for (i
= 0; i
< free_size
; i
++)
127 * \brief Set up atexit() hook.
129 * Can be avoided if leaky_uninit() is called by hand.
131 void leaky_init (void)
133 atexit(leaky_uninit
);