00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "mmprivate.h"
00029
00030
00031
00032
00033 void
00034 __mmalloc_free (mdp, ptr)
00035 struct mdesc *mdp;
00036 PTR ptr;
00037 {
00038 int type;
00039 size_t block, blocks;
00040 register size_t i;
00041 struct mmlist *prev, *next;
00042
00043 block = BLOCK (ptr);
00044
00045 type = mdp -> heapinfo[block].busy.type;
00046 switch (type)
00047 {
00048 case 0:
00049
00050 mdp -> heapstats.chunks_used--;
00051 mdp -> heapstats.bytes_used -=
00052 mdp -> heapinfo[block].busy.info.size * BLOCKSIZE;
00053 mdp -> heapstats.bytes_free +=
00054 mdp -> heapinfo[block].busy.info.size * BLOCKSIZE;
00055
00056
00057
00058
00059 i = mdp -> heapindex;
00060 if (i > block)
00061 {
00062 while (i > block)
00063 {
00064 i = mdp -> heapinfo[i].free.prev;
00065 }
00066 }
00067 else
00068 {
00069 do
00070 {
00071 i = mdp -> heapinfo[i].free.next;
00072 }
00073 while ((i != 0) && (i < block));
00074 i = mdp -> heapinfo[i].free.prev;
00075 }
00076
00077
00078 if (block == i + mdp -> heapinfo[i].free.size)
00079 {
00080
00081 mdp -> heapinfo[i].free.size +=
00082 mdp -> heapinfo[block].busy.info.size;
00083 block = i;
00084 }
00085 else
00086 {
00087
00088 mdp -> heapinfo[block].free.size =
00089 mdp -> heapinfo[block].busy.info.size;
00090 mdp -> heapinfo[block].free.next = mdp -> heapinfo[i].free.next;
00091 mdp -> heapinfo[block].free.prev = i;
00092 mdp -> heapinfo[i].free.next = block;
00093 mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.prev = block;
00094 mdp -> heapstats.chunks_free++;
00095 }
00096
00097
00098
00099
00100 if (block + mdp -> heapinfo[block].free.size ==
00101 mdp -> heapinfo[block].free.next)
00102 {
00103 mdp -> heapinfo[block].free.size
00104 += mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.size;
00105 mdp -> heapinfo[block].free.next
00106 = mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.next;
00107 mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.prev = block;
00108 mdp -> heapstats.chunks_free--;
00109 }
00110
00111
00112 blocks = mdp -> heapinfo[block].free.size;
00113 if (blocks >= FINAL_FREE_BLOCKS && block + blocks == mdp -> heaplimit
00114 && mdp -> morecore (mdp, 0) == ADDRESS (block + blocks))
00115 {
00116 register size_t bytes = blocks * BLOCKSIZE;
00117 mdp -> heaplimit -= blocks;
00118 mdp -> morecore (mdp, -(ptrdiff_t)bytes);
00119 mdp -> heapinfo[mdp -> heapinfo[block].free.prev].free.next
00120 = mdp -> heapinfo[block].free.next;
00121 mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.prev
00122 = mdp -> heapinfo[block].free.prev;
00123 block = mdp -> heapinfo[block].free.prev;
00124 mdp -> heapstats.chunks_free--;
00125 mdp -> heapstats.bytes_free -= bytes;
00126 }
00127
00128
00129 mdp -> heapindex = block;
00130 break;
00131
00132 default:
00133
00134 mdp -> heapstats.chunks_used--;
00135 mdp -> heapstats.bytes_used -= 1 << type;
00136 mdp -> heapstats.chunks_free++;
00137 mdp -> heapstats.bytes_free += 1 << type;
00138
00139
00140 prev = (struct mmlist *)
00141 ((char *) ADDRESS(block) +
00142 (mdp -> heapinfo[block].busy.info.frag.first << type));
00143
00144 if (mdp -> heapinfo[block].busy.info.frag.nfree ==
00145 (BLOCKSIZE >> type) - 1)
00146 {
00147
00148
00149 next = prev;
00150 for (i = 1; i < (size_t) (BLOCKSIZE >> type); ++i)
00151 {
00152 next = next -> next;
00153 }
00154 prev -> prev -> next = next;
00155 if (next != NULL)
00156 {
00157 next -> prev = prev -> prev;
00158 }
00159 mdp -> heapinfo[block].busy.type = 0;
00160 mdp -> heapinfo[block].busy.info.size = 1;
00161
00162
00163 mdp -> heapstats.chunks_used++;
00164 mdp -> heapstats.bytes_used += BLOCKSIZE;
00165 mdp -> heapstats.chunks_free -= BLOCKSIZE >> type;
00166 mdp -> heapstats.bytes_free -= BLOCKSIZE;
00167
00168 mfree ((PTR) mdp, (PTR) ADDRESS(block));
00169 }
00170 else if (mdp -> heapinfo[block].busy.info.frag.nfree != 0)
00171 {
00172
00173
00174
00175 next = (struct mmlist *) ptr;
00176 next -> next = prev -> next;
00177 next -> prev = prev;
00178 prev -> next = next;
00179 if (next -> next != NULL)
00180 {
00181 next -> next -> prev = next;
00182 }
00183 ++mdp -> heapinfo[block].busy.info.frag.nfree;
00184 }
00185 else
00186 {
00187
00188
00189
00190 prev = (struct mmlist *) ptr;
00191 mdp -> heapinfo[block].busy.info.frag.nfree = 1;
00192 mdp -> heapinfo[block].busy.info.frag.first =
00193 RESIDUAL (ptr, BLOCKSIZE) >> type;
00194 prev -> next = mdp -> fraghead[type].next;
00195 prev -> prev = &mdp -> fraghead[type];
00196 prev -> prev -> next = prev;
00197 if (prev -> next != NULL)
00198 {
00199 prev -> next -> prev = prev;
00200 }
00201 }
00202 break;
00203 }
00204 }
00205
00206
00207
00208 void
00209 mfree (md, ptr)
00210 PTR md;
00211 PTR ptr;
00212 {
00213 struct mdesc *mdp;
00214 register struct alignlist *l;
00215
00216 if (ptr != NULL)
00217 {
00218 mdp = MD_TO_MDP (md);
00219 for (l = mdp -> aligned_blocks; l != NULL; l = l -> next)
00220 {
00221 if (l -> aligned == ptr)
00222 {
00223 l -> aligned = NULL;
00224 ptr = l -> exact;
00225 break;
00226 }
00227 }
00228 if (mdp -> mfree_hook != NULL)
00229 {
00230 (*mdp -> mfree_hook) (md, ptr);
00231 }
00232 else
00233 {
00234 __mmalloc_free (mdp, ptr);
00235 }
00236 }
00237 }
00238
00239
00240
00241
00242
00243
00244
00245 #ifndef NO_SBRK_MALLOC
00246
00247 void
00248 free (ptr)
00249 PTR ptr;
00250 {
00251 mfree ((PTR) NULL, ptr);
00252 }
00253
00254 #endif