1 /*
2  *	memory.cc
3  *	Memory allocation routines.
4  *	BW & RQ sometime in 1993 or 1994.
5  */
6 
7 
8 /*
9 This file is part of Yadex.
10 
11 Yadex incorporates code from DEU 5.21 that was put in the public domain in
12 1994 by Rapha�l Quinet and Brendon Wyber.
13 
14 The rest of Yadex is Copyright � 1997-2003 Andr� Majorel and others.
15 
16 This program is free software; you can redistribute it and/or modify it under
17 the terms of the GNU General Public License as published by the Free Software
18 Foundation; either version 2 of the License, or (at your option) any later
19 version.
20 
21 This program is distributed in the hope that it will be useful, but WITHOUT
22 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
23 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
24 
25 You should have received a copy of the GNU General Public License along with
26 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
27 Place, Suite 330, Boston, MA 02111-1307, USA.
28 */
29 
30 
31 #include "yadex.h"
32 
33 /*
34    Note from RQ:
35       To prevent memory fragmentation on large blocks (greater than 1K),
36       the size of all blocks is rounded up to 8K.  Thus, "realloc" will
37       move the block if and only if it has grown or shrunk enough to
38       cross a 8K boundary.
39       I don't do that for smaller blocks (smaller than 1K), because this
40       would waste too much space if these blocks were rounded up to 8K.
41       There are lots of "malloc"'s for very small strings (9 characters)
42       or filenames, etc.
43       Thanks to Craig Smith (bcs@cs.tamu.edu) for some of his ideas
44       about memory fragmentation.
45 */
46 
47 #define SIZE_THRESHOLD	1024
48 #define SIZE_OF_BLOCK	4095  /* actually, this is (size - 1) */
49 
50 
51 /*
52    allocate memory with error checking
53 */
54 
GetMemory(unsigned long size)55 void *GetMemory (unsigned long size)
56 {
57 void *ret;
58 
59 /* On 16-bit systems (BC 4.0), size_t is only 16-bit long so
60    you can't malloc() more than 64 kB at a time. Catch it. */
61 if (size != (size_t) size)
62    fatal_error ("GetMemory: %lu B is too much for this poor machine.", size);
63 
64 /* limit fragmentation on large blocks */
65 if (size >= SIZE_THRESHOLD)
66    size = (size + SIZE_OF_BLOCK) & ~SIZE_OF_BLOCK;
67 ret = malloc ((size_t) size);
68 if (!ret)
69    {
70    /* retry after having freed some memory, if possible */
71    FreeSomeMemory ();
72    ret = malloc ((size_t) size);
73    }
74 if (!ret)
75    fatal_error ("out of memory (cannot allocate %u bytes)", size);
76 return ret;
77 }
78 
79 
80 /*
81    reallocate memory with error checking
82 */
83 
ResizeMemory(void * old,unsigned long size)84 void *ResizeMemory (void *old, unsigned long size)
85 {
86 void *ret;
87 
88 /* On 16-bit systems (BC 4.0), size_t is only 16-bit long so
89    you can't malloc() more than 64 kB at a time. Catch it. */
90 if (size != (size_t) size)
91    fatal_error ("ResizeMemory: %lu B is too much for this poor machine.", size);
92 
93 /* limit fragmentation on large blocks */
94 if (size >= SIZE_THRESHOLD)
95    size = (size + SIZE_OF_BLOCK) & ~SIZE_OF_BLOCK;
96 ret = realloc (old, (size_t) size);
97 if (!ret)
98    {
99    FreeSomeMemory ();
100    ret = realloc (old, (size_t) size);
101    }
102 if (!ret)
103    fatal_error ("out of memory (cannot reallocate %lu bytes)", size);
104 return ret;
105 }
106 
107 
108 /*
109    free memory
110 */
111 
FreeMemory(void * ptr)112 void FreeMemory (void *ptr)
113 {
114 /* just a wrapper around free(), but provide an entry point */
115 /* for memory debugging routines... */
116 free (ptr);
117 }
118 
119 
120 /*
121    allocate memory from the far heap with error checking
122 */
123 
GetFarMemory(unsigned long size)124 void huge *GetFarMemory (unsigned long size)
125 {
126 void huge *ret;
127 
128 /* limit fragmentation on large blocks */
129 if (size >= SIZE_THRESHOLD)
130    size = (size +  SIZE_OF_BLOCK) & ~SIZE_OF_BLOCK;
131 ret = farmalloc (size);
132 if (!ret)
133    {
134    /* retry after having freed some memory, if possible */
135    FreeSomeMemory ();
136    ret = farmalloc (size);
137    }
138 if (!ret)
139    fatal_error ("out of memory (cannot allocate %lu far bytes)", size);
140 return ret;
141 }
142 
143 
144 
145 /*
146    reallocate memory from the far heap with error checking
147 */
148 
ResizeFarMemory(void huge * old,unsigned long size)149 void huge *ResizeFarMemory (void huge *old, unsigned long size)
150 {
151 void huge *ret;
152 
153 /* limit fragmentation on large blocks */
154 if (size >= SIZE_THRESHOLD)
155    size = (size + SIZE_OF_BLOCK) & ~SIZE_OF_BLOCK;
156 ret = farrealloc (old, size);
157 if (!ret)
158    {
159    FreeSomeMemory ();
160    ret = farrealloc (old, size);
161    }
162 if (!ret)
163    fatal_error ("out of memory (cannot reallocate %lu far bytes)", size);
164 return ret;
165 }
166 
167 
168 
169 /*
170    free memory from the far heap
171 */
172 
FreeFarMemory(void huge * ptr)173 void FreeFarMemory (void huge *ptr)
174 {
175 /* just a wrapper around farfree(), but provide an entry point */
176 /* for memory debugging routines... */
177 farfree (ptr);
178 }
179 
180 
181 /* end of file */
182