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 #include <string.h>
00027
00028 #include "mmprivate.h"
00029
00030
00031
00032
00033
00034
00035
00036
00037 PTR
00038 mrealloc (md, ptr, size)
00039 PTR md;
00040 PTR ptr;
00041 size_t size;
00042 {
00043 struct mdesc *mdp;
00044 PTR result;
00045 int type;
00046 size_t block, blocks, oldlimit;
00047
00048 if (size == 0)
00049 {
00050 mfree (md, ptr);
00051 return (mmalloc (md, 0));
00052 }
00053 else if (ptr == NULL)
00054 {
00055 return (mmalloc (md, size));
00056 }
00057
00058 mdp = MD_TO_MDP (md);
00059
00060 if (mdp -> mrealloc_hook != NULL)
00061 {
00062 return ((*mdp -> mrealloc_hook) (md, ptr, size));
00063 }
00064
00065 block = BLOCK (ptr);
00066
00067 type = mdp -> heapinfo[block].busy.type;
00068 switch (type)
00069 {
00070 case 0:
00071
00072 if (size <= BLOCKSIZE / 2)
00073 {
00074 result = mmalloc (md, size);
00075 if (result != NULL)
00076 {
00077 memcpy (result, ptr, size);
00078 mfree (md, ptr);
00079 return (result);
00080 }
00081 }
00082
00083
00084
00085 blocks = BLOCKIFY (size);
00086 if (blocks < mdp -> heapinfo[block].busy.info.size)
00087 {
00088
00089 mdp -> heapinfo[block + blocks].busy.type = 0;
00090 mdp -> heapinfo[block + blocks].busy.info.size
00091 = mdp -> heapinfo[block].busy.info.size - blocks;
00092 mdp -> heapinfo[block].busy.info.size = blocks;
00093 mfree (md, ADDRESS (block + blocks));
00094 result = ptr;
00095 }
00096 else if (blocks == mdp -> heapinfo[block].busy.info.size)
00097 {
00098
00099 result = ptr;
00100 }
00101 else
00102 {
00103
00104
00105
00106 blocks = mdp -> heapinfo[block].busy.info.size;
00107
00108 oldlimit = mdp -> heaplimit;
00109 mdp -> heaplimit = 0;
00110 mfree (md, ptr);
00111 mdp -> heaplimit = oldlimit;
00112 result = mmalloc (md, size);
00113 if (result == NULL)
00114 {
00115 mmalloc (md, blocks * BLOCKSIZE);
00116 return (NULL);
00117 }
00118 if (ptr != result)
00119 {
00120 memmove (result, ptr, blocks * BLOCKSIZE);
00121 }
00122 }
00123 break;
00124
00125 default:
00126
00127
00128 if (size > (size_t) (1 << (type - 1)) && size <= (size_t) (1 << type))
00129 {
00130
00131 result = ptr;
00132 }
00133 else
00134 {
00135
00136
00137 result = mmalloc (md, size);
00138 if (result == NULL)
00139 {
00140 return (NULL);
00141 }
00142 memcpy (result, ptr, MIN (size, (size_t) 1 << type));
00143 mfree (md, ptr);
00144 }
00145 break;
00146 }
00147
00148 return (result);
00149 }
00150
00151
00152
00153
00154
00155
00156
00157 #ifndef NO_SBRK_MALLOC
00158
00159 PTR
00160 realloc (ptr, size)
00161 PTR ptr;
00162 size_t size;
00163 {
00164 return (mrealloc ((PTR) NULL, ptr, size));
00165 }
00166
00167 #endif
00168