Logo ROOT  
Reference Guide
mfree.c
Go to the documentation of this file.
1/* @(#)root/clib:$Id$ */
2/* Author: */
3
4/* Free a block of memory allocated by `mmalloc'.
5 Copyright 1990, 1991, 1992 Free Software Foundation
6
7 Written May 1989 by Mike Haertel.
8 Heavily modified Mar 1992 by Fred Fish. (fnf@cygnus.com)
9
10The GNU C Library is free software; you can redistribute it and/or
11modify it under the terms of the GNU Library General Public License as
12published by the Free Software Foundation; either version 2 of the
13License, or (at your option) any later version.
14
15The GNU C Library is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18Library General Public License for more details.
19
20You should have received a copy of the GNU Library General Public
21License along with the GNU C Library; see the file COPYING.LIB. If
22not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23Boston, MA 02111-1307, USA.
24
25 The author may be reached (Email) at the address mike@ai.mit.edu,
26 or (US mail) as Mike Haertel c/o Free Software Foundation. */
27
28#include "mmprivate.h"
29
30#include <stddef.h>
31/* Return memory to the heap.
32 Like `mfree' but don't call a mfree_hook if there is one. */
33
34void __mmalloc_free(struct mdesc *mdp, PTR ptr)
35{
36 int type;
37 size_t block, blocks;
38 register size_t i;
39 struct mmlist *prev, *next;
40
41 block = BLOCK (ptr);
42
43 type = mdp -> heapinfo[block].busy.type;
44 switch (type)
45 {
46 case 0:
47 /* Get as many statistics as early as we can. */
48 mdp -> heapstats.chunks_used--;
49 mdp -> heapstats.bytes_used -=
50 mdp -> heapinfo[block].busy.info.size * BLOCKSIZE;
51 mdp -> heapstats.bytes_free +=
52 mdp -> heapinfo[block].busy.info.size * BLOCKSIZE;
53
54 /* Find the free cluster previous to this one in the free list.
55 Start searching at the last block referenced; this may benefit
56 programs with locality of allocation. */
57 i = mdp -> heapindex;
58 if (i > block)
59 {
60 while (i > block)
61 {
62 i = mdp -> heapinfo[i].free.prev;
63 }
64 }
65 else
66 {
67 do
68 {
69 i = mdp -> heapinfo[i].free.next;
70 }
71 while ((i != 0) && (i < block));
72 i = mdp -> heapinfo[i].free.prev;
73 }
74
75 /* Determine how to link this block into the free list. */
76 if (block == i + mdp -> heapinfo[i].free.size)
77 {
78 /* Coalesce this block with its predecessor. */
79 mdp -> heapinfo[i].free.size +=
80 mdp -> heapinfo[block].busy.info.size;
81 block = i;
82 }
83 else
84 {
85 /* Really link this block back into the free list. */
86 mdp -> heapinfo[block].free.size =
87 mdp -> heapinfo[block].busy.info.size;
88 mdp -> heapinfo[block].free.next = mdp -> heapinfo[i].free.next;
89 mdp -> heapinfo[block].free.prev = i;
90 mdp -> heapinfo[i].free.next = block;
91 mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.prev = block;
92 mdp -> heapstats.chunks_free++;
93 }
94
95 /* Now that the block is linked in, see if we can coalesce it
96 with its successor (by deleting its successor from the list
97 and adding in its size). */
98 if (block + mdp -> heapinfo[block].free.size ==
99 mdp -> heapinfo[block].free.next)
100 {
101 mdp -> heapinfo[block].free.size
102 += mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.size;
103 mdp -> heapinfo[block].free.next
104 = mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.next;
105 mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.prev = block;
106 mdp -> heapstats.chunks_free--;
107 }
108
109 /* Now see if we can return stuff to the system. */
110 blocks = mdp -> heapinfo[block].free.size;
111 if (blocks >= FINAL_FREE_BLOCKS && block + blocks == mdp -> heaplimit
112 && mdp -> morecore (mdp, 0) == ADDRESS (block + blocks))
113 {
114 register size_t bytes = blocks * BLOCKSIZE;
115 mdp -> heaplimit -= blocks;
116 mdp -> morecore (mdp, -(ptrdiff_t)bytes);
117 mdp -> heapinfo[mdp -> heapinfo[block].free.prev].free.next
118 = mdp -> heapinfo[block].free.next;
119 mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.prev
120 = mdp -> heapinfo[block].free.prev;
121 block = mdp -> heapinfo[block].free.prev;
122 mdp -> heapstats.chunks_free--;
123 mdp -> heapstats.bytes_free -= bytes;
124 }
125
126 /* Set the next search to begin at this block. */
127 mdp -> heapindex = block;
128 break;
129
130 default:
131 /* Do some of the statistics. */
132 mdp -> heapstats.chunks_used--;
133 mdp -> heapstats.bytes_used -= 1 << type;
134 mdp -> heapstats.chunks_free++;
135 mdp -> heapstats.bytes_free += 1 << type;
136
137 /* Get the address of the first free fragment in this block. */
138 prev = (struct mmlist *)
139 ((char *) ADDRESS(block) +
140 (mdp -> heapinfo[block].busy.info.frag.first << type));
141
142 if (mdp -> heapinfo[block].busy.info.frag.nfree ==
143 (BLOCKSIZE >> type) - 1)
144 {
145 /* If all fragments of this block are free, remove them
146 from the fragment list and free the whole block. */
147 next = prev;
148 for (i = 1; i < (size_t) (BLOCKSIZE >> type); ++i)
149 {
150 next = next -> next;
151 }
152 prev -> prev -> next = next;
153 if (next != NULL)
154 {
155 next -> prev = prev -> prev;
156 }
157 mdp -> heapinfo[block].busy.type = 0;
158 mdp -> heapinfo[block].busy.info.size = 1;
159
160 /* Keep the statistics accurate. */
161 mdp -> heapstats.chunks_used++;
162 mdp -> heapstats.bytes_used += BLOCKSIZE;
163 mdp -> heapstats.chunks_free -= BLOCKSIZE >> type;
164 mdp -> heapstats.bytes_free -= BLOCKSIZE;
165
166 mfree ((PTR) mdp, (PTR) ADDRESS(block));
167 }
168 else if (mdp -> heapinfo[block].busy.info.frag.nfree != 0)
169 {
170 /* If some fragments of this block are free, link this
171 fragment into the fragment list after the first free
172 fragment of this block. */
173 next = (struct mmlist *) ptr;
174 next -> next = prev -> next;
175 next -> prev = prev;
176 prev -> next = next;
177 if (next -> next != NULL)
178 {
179 next -> next -> prev = next;
180 }
181 ++mdp -> heapinfo[block].busy.info.frag.nfree;
182 }
183 else
184 {
185 /* No fragments of this block are free, so link this
186 fragment into the fragment list and announce that
187 it is the first free fragment of this block. */
188 prev = (struct mmlist *) ptr;
189 mdp -> heapinfo[block].busy.info.frag.nfree = 1;
190 mdp -> heapinfo[block].busy.info.frag.first =
191 RESIDUAL (ptr, BLOCKSIZE) >> type;
192 prev -> next = mdp -> fraghead[type].next;
193 prev -> prev = &mdp -> fraghead[type];
194 prev -> prev -> next = prev;
195 if (prev -> next != NULL)
196 {
197 prev -> next -> prev = prev;
198 }
199 }
200 break;
201 }
202}
203
204/* Return memory to the heap. */
205
206void mfree(PTR md, PTR ptr)
207{
208 struct mdesc *mdp;
209 register struct alignlist *l;
210
211 if (ptr != NULL)
212 {
213 mdp = MD_TO_MDP (md);
214 for (l = mdp -> aligned_blocks; l != NULL; l = l -> next)
215 {
216 if (l -> aligned == ptr)
217 {
218 l -> aligned = NULL; /* Mark the slot in the list as free. */
219 ptr = l -> exact;
220 break;
221 }
222 }
223 if (mdp -> mfree_hook != NULL)
224 {
225 (*mdp -> mfree_hook) (md, ptr);
226 }
227 else
228 {
229 __mmalloc_free (mdp, ptr);
230 }
231 }
232}
233
234/* When using this package, provide a version of malloc/realloc/free built
235 on top of it, so that if we use the default sbrk() region we will not
236 collide with another malloc package trying to do the same thing, if
237 the application contains any "hidden" calls to malloc/realloc/free (such
238 as inside a system library). */
239
240#ifndef NO_SBRK_MALLOC
241
242void
243free (ptr)
244 PTR ptr;
245{
246 mfree ((PTR) NULL, ptr);
247}
248
249#endif
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t bytes
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
#define NULL
Definition ZInflate.c:15
#define free
Definition civetweb.c:1578
void mfree(PTR md, PTR ptr)
Definition mfree.c:206
void __mmalloc_free(struct mdesc *mdp, PTR ptr)
Definition mfree.c:34
static PTR morecore(struct mdesc *mdp, size_t size)
Definition mmalloc.c:81
#define PTR
Definition mmalloc.h:29
#define MD_TO_MDP(md)
Definition mmprivate.h:375
#define RESIDUAL(addr, bsize)
Definition mmprivate.h:85
#define ADDRESS(B)
Definition mmprivate.h:108
#define BLOCK(A)
Definition mmprivate.h:106
#define FINAL_FREE_BLOCKS
Definition mmprivate.h:95
#define BLOCKSIZE
Definition mmprivate.h:81
PTR aligned
Definition mmprivate.h:146
struct alignlist * next
Definition mmprivate.h:145
struct mmlist * prev
Definition mmprivate.h:155
struct mmlist * next
Definition mmprivate.h:154