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