source: trunk/src/msvcrt/heap.c@ 10005

Last change on this file since 10005 was 10005, checked in by sandervl, 22 years ago

PF: MSVCRT update

File size: 8.1 KB
Line 
1/*
2 * msvcrt.dll heap functions
3 *
4 * Copyright 2000 Jon Griffiths
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * Note: Win32 heap operations are MT safe. We only lock the new
21 * handler and non atomic heap operations
22 */
23
24#include "msvcrt.h"
25
26#include <string.h>
27
28#include "ms_errno.h"
29
30#include "msvcrt/malloc.h"
31#include "msvcrt/stdlib.h"
32#include "mtdll.h"
33
34#include "wine/debug.h"
35
36WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
37
38/* MT */
39#define LOCK_HEAP _mlock( _HEAP_LOCK )
40#define UNLOCK_HEAP _munlock( _HEAP_LOCK )
41
42
43typedef void (*MSVCRT_new_handler_func)(unsigned long size);
44
45static MSVCRT_new_handler_func MSVCRT_new_handler;
46static int MSVCRT_new_mode;
47
48/*********************************************************************
49 * ??2@YAPAXI@Z (MSVCRT.@)
50 */
51void* MSVCRT_operator_new(unsigned long size)
52{
53 void *retval = HeapAlloc(GetProcessHeap(), 0, size);
54 TRACE("MSVCRT: operator_new (%ld) returning %p\n", size, retval);
55 LOCK_HEAP;
56 if(!retval && MSVCRT_new_handler)
57 (*MSVCRT_new_handler)(size);
58 UNLOCK_HEAP;
59 return retval;
60}
61
62/*********************************************************************
63 * ??3@YAXPAX@Z (MSVCRT.@)
64 */
65void MSVCRT_operator_delete(void *mem)
66{
67 TRACE("MSVCRT: operator_delete (%p)\n", mem);
68 HeapFree(GetProcessHeap(), 0, mem);
69}
70
71
72/*********************************************************************
73 * ?_query_new_handler@@YAP6AHI@ZXZ (MSVCRT.@)
74 */
75MSVCRT_new_handler_func MSVCRT__query_new_handler(void)
76{
77 dprintf(("MSVCRT: _query_new_handler"));
78 return MSVCRT_new_handler;
79}
80
81
82/*********************************************************************
83 * ?_query_new_mode@@YAHXZ (MSVCRT.@)
84 */
85int MSVCRT__query_new_mode(void)
86{
87 dprintf(("MSVCRT: _query_new_mode"));
88 return MSVCRT_new_mode;
89}
90
91/*********************************************************************
92 * ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z (MSVCRT.@)
93 */
94MSVCRT_new_handler_func MSVCRT__set_new_handler(MSVCRT_new_handler_func func)
95{
96 MSVCRT_new_handler_func old_handler;
97
98 dprintf(("MSVCRT: _set_new_mode"));
99
100 LOCK_HEAP;
101 old_handler = MSVCRT_new_handler;
102 MSVCRT_new_handler = func;
103 UNLOCK_HEAP;
104 return old_handler;
105}
106
107/*********************************************************************
108 * ?set_new_handler@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
109 */
110MSVCRT_new_handler_func MSVCRT_set_new_handler(void *func)
111{
112 TRACE("MSVCRT: set_new_handler (%p)\n",func);
113 MSVCRT__set_new_handler(NULL);
114 return NULL;
115}
116
117/*********************************************************************
118 * ?_set_new_mode@@YAHH@Z (MSVCRT.@)
119 */
120int MSVCRT__set_new_mode(int mode)
121{
122 int old_mode;
123 TRACE("MSVCRT: set_new_mode (%d)\n",mode);
124 LOCK_HEAP;
125 old_mode = MSVCRT_new_mode;
126 MSVCRT_new_mode = mode;
127 UNLOCK_HEAP;
128 return old_mode;
129}
130
131/*********************************************************************
132 * _callnewh (MSVCRT.@)
133 */
134int _callnewh(unsigned long size)
135{
136 TRACE("MSVCRT: _callnewh (%d)\n",size);
137 if(MSVCRT_new_handler)
138 (*MSVCRT_new_handler)(size);
139 return 0;
140}
141
142/*********************************************************************
143 * _expand (MSVCRT.@)
144 */
145void* _expand(void* mem, MSVCRT_size_t size)
146{
147 TRACE("MSVCRT: _expand (%p)\n",mem);
148 return HeapReAlloc(GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, mem, size);
149}
150
151/*********************************************************************
152 * _heapchk (MSVCRT.@)
153 */
154int MSVCRT__heapchk(void)
155{
156 TRACE("MSVCRT: _heapchk");
157 if (!HeapValidate( GetProcessHeap(), 0, NULL))
158 {
159 MSVCRT__set_errno(GetLastError());
160 return _HEAPBADNODE;
161 }
162 return _HEAPOK;
163}
164
165/*********************************************************************
166 * _heapmin (MSVCRT.@)
167 */
168int MSVCRT__heapmin(void)
169{
170 TRACE("MSVCRT: _heapmin");
171 if (!HeapCompact( GetProcessHeap(), 0 ))
172 {
173 if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
174 MSVCRT__set_errno(GetLastError());
175 return -1;
176 }
177 return 0;
178}
179
180/*********************************************************************
181 * _heapwalk (MSVCRT.@)
182 */
183int MSVCRT__heapwalk(_HEAPINFO* next)
184{
185 PROCESS_HEAP_ENTRY phe;
186
187 TRACE("MSVCRT: _heapwalk");
188
189 LOCK_HEAP;
190 phe.lpData = next->_pentry;
191 phe.cbData = next->_size;
192 phe.wFlags = next->_useflag == _USEDENTRY ? PROCESS_HEAP_ENTRY_BUSY : 0;
193
194 if (phe.lpData && phe.wFlags & PROCESS_HEAP_ENTRY_BUSY &&
195 !HeapValidate( GetProcessHeap(), 0, phe.lpData ))
196 {
197 UNLOCK_HEAP;
198 MSVCRT__set_errno(GetLastError());
199 return _HEAPBADNODE;
200 }
201
202 do
203 {
204 if (!HeapWalk( GetProcessHeap(), &phe ))
205 {
206 UNLOCK_HEAP;
207 if (GetLastError() == ERROR_NO_MORE_ITEMS)
208 return _HEAPEND;
209 MSVCRT__set_errno(GetLastError());
210 if (!phe.lpData)
211 return _HEAPBADBEGIN;
212 return _HEAPBADNODE;
213 }
214 } while (phe.wFlags & (PROCESS_HEAP_REGION|PROCESS_HEAP_UNCOMMITTED_RANGE));
215
216 UNLOCK_HEAP;
217 next->_pentry = phe.lpData;
218 next->_size = phe.cbData;
219 next->_useflag = phe.wFlags & PROCESS_HEAP_ENTRY_BUSY ? _USEDENTRY : _FREEENTRY;
220 return _HEAPOK;
221}
222
223/*********************************************************************
224 * _heapset (MSVCRT.@)
225 */
226int MSVCRT__heapset(unsigned int value)
227{
228 int retval;
229 _HEAPINFO heap;
230
231 TRACE("MSVCRT: _heapset");
232
233 memset( &heap, 0, sizeof(_HEAPINFO) );
234 LOCK_HEAP;
235 while ((retval = MSVCRT__heapwalk(&heap)) == _HEAPOK)
236 {
237 if (heap._useflag == _FREEENTRY)
238 memset(heap._pentry, value, heap._size);
239 }
240 UNLOCK_HEAP;
241 return retval == _HEAPEND? _HEAPOK : retval;
242}
243
244/*********************************************************************
245 * _heapadd (MSVCRT.@)
246 */
247int MSVCRT__heapadd(void* mem, MSVCRT_size_t size)
248{
249 TRACE("MSVCRT: _heapadd (%p,%d) unsupported in Win32\n", mem,size);
250 *MSVCRT__errno() = MSVCRT_ENOSYS;
251 return -1;
252}
253
254/*********************************************************************
255 * _msize (MSVCRT.@)
256 */
257MSVCRT_size_t MSVCRT__msize(void* mem)
258{
259 long size = HeapSize(GetProcessHeap(),0,mem);
260
261 TRACE("MSVCRT: _msize (%p)",mem);
262
263 if (size == -1)
264 {
265 WARN(":Probably called with non wine-allocated memory, ret = -1\n");
266 /* At least the Win32 crtdll/msvcrt also return -1 in this case */
267 }
268 return size;
269}
270
271/*********************************************************************
272 * calloc (MSVCRT.@)
273 */
274void* MSVCRT_calloc(MSVCRT_size_t size, MSVCRT_size_t count)
275{
276 void *ret;
277 ret = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size * count );
278 TRACE("MSVCRT: calloc (%d,%d) returned %p",size, count, ret);
279 return ret;
280}
281
282/*********************************************************************
283 * free (MSVCRT.@)
284 */
285void MSVCRT_free(void* ptr)
286{
287 dprintf(("MSVCRT: free %x ptr",ptr));
288 HeapFree(GetProcessHeap(),0,ptr);
289}
290
291void* MSVCRT(memset)(void* ptr,int fill,MSVCRT(size_t) size)
292{
293 dprintf(("MSVCRT: memset %x(%d bytes) with %d",ptr,size,fill));
294 return memset(ptr,fill,size);
295}
296
297
298void* MSVCRT(memcpy)(void* ptr,const void* ptr2,MSVCRT(size_t) size)
299{
300 dprintf(("MSVCRT: memcpy %x->%x (%d bytes)",ptr2,ptr,size));
301 return memcpy(ptr,ptr2,size);
302}
303
304
305/*********************************************************************
306 * malloc (MSVCRT.@)
307 */
308void* MSVCRT_malloc(MSVCRT_size_t size)
309{
310 void *ret = HeapAlloc(GetProcessHeap(),0,size);
311 dprintf(("MSVCRT: malloc of %d size returned %x",size,ret));
312 if (!ret)
313 MSVCRT__set_errno(GetLastError());
314 return ret;
315}
316
317/*********************************************************************
318 * realloc (MSVCRT.@)
319 */
320void* MSVCRT_realloc(void* ptr, MSVCRT_size_t size)
321{
322 dprintf(("MSVCRT: realloc %x",ptr));
323 return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
324}
Note: See TracBrowser for help on using the repository browser.