source: trunk/src/kernel32/os2heap.cpp@ 2803

Last change on this file since 2803 was 2803, checked in by sandervl, 26 years ago

Added new logging feature

File size: 10.3 KB
Line 
1/* $Id: os2heap.cpp,v 1.14 2000-02-16 14:25:43 sandervl Exp $ */
2
3/*
4 * Heap class for OS/2
5 *
6 * Copyright 1998 Sander van Leeuwen
7 *
8 *
9 * NOTE: ReAlloc allocates memory using Alloc if memory pointer == NULL
10 * WINE controls depend on this, even though it apparently
11 * doesn't work like this in Windows.
12 *
13 * Project Odin Software License can be found in LICENSE.TXT
14 *
15 */
16#define INCL_DOSMEMMGR
17#define INCL_DOSSEMAPHORES
18#define INCL_DOSERRORS
19#include <os2wrap.h> //Odin32 OS/2 api wrappers
20#include <builtin.h>
21#include <stdlib.h>
22#include <string.h>
23
24#include "win32type.h"
25#include "os2heap.h"
26#include "misc.h"
27#include "vmutex.h"
28#include "initterm.h"
29
30#define DBG_LOCALLOG DBG_os2heap
31#include "dbglocal.h"
32
33#ifndef HEAP_NO_SERIALIZE
34 #define HEAP_NO_SERIALIZE 1
35#endif
36
37#ifndef HEAP_ZERO_MEMORY
38 #define HEAP_ZERO_MEMORY 8
39#endif
40
41VMutex heaplistmutex; //protects linked lists of heaps
42
43//******************************************************************************
44//******************************************************************************
45OS2Heap::OS2Heap(HANDLE hHeap, DWORD flOptions, DWORD dwInitialSize, DWORD dwMaximumSize)
46{
47 OS2Heap *curheap = OS2Heap::heap;
48
49 hPrimaryHeap = hHeap;
50 totalAlloc = 0;
51 fInitialized = 0;
52 nrHeaps = 0;
53 heapelem = NULL;
54
55 this->dwMaximumSize = dwMaximumSize;
56 this->dwInitialSize = dwInitialSize;
57 this->flOptions = flOptions;
58
59 dprintf(("KERNEL32: HeapCreate: initial size %d, max size %d (flags %X) returned %X\n", dwInitialSize, dwMaximumSize, flOptions, hPrimaryHeap));
60
61 if(!(flOptions & HEAP_NO_SERIALIZE))
62 {
63 hmutex = new VMutex();
64 dassert(hmutex, ("ERROR: new VMutex\n"));
65 }
66 else hmutex = NULL;
67
68 heaplistmutex.enter();
69 if(curheap != NULL) {
70 while(curheap->next != NULL) {
71 curheap = curheap->next;
72 }
73 curheap->next = this;
74 }
75 else heap = this;
76 next = NULL;
77
78 heaplistmutex.leave();
79}
80//******************************************************************************
81//******************************************************************************
82OS2Heap::~OS2Heap()
83{
84 OS2Heap *curheap = OS2Heap::heap;
85 HEAPELEM *hnext;
86 int i;
87
88 dprintf(("dtr OS2Heap, hPrimaryHeap = %X\n", hPrimaryHeap));
89
90 if(hmutex)
91 hmutex->enter();
92
93 while(heapelem) {
94 hnext = heapelem->next;
95 free(heapelem);
96 heapelem = hnext;
97 }
98 if(hmutex)
99 {
100 hmutex->leave();
101 delete(hmutex);
102 }
103
104 heaplistmutex.enter();
105 if(heap == this) {
106 heap = next;
107 }
108 else {
109 while(curheap->next != NULL) {
110 if(curheap->next == this) {
111 curheap->next = next;
112 break;
113 }
114 curheap = curheap->next;
115 }
116 }
117 heaplistmutex.leave();
118 dprintf(("dtr OS2Heap, hPrimaryHeap = %X done\n", hPrimaryHeap));
119}
120//******************************************************************************
121//******************************************************************************
122LPVOID OS2Heap::Alloc(DWORD dwFlags, DWORD dwBytes)
123{
124 LPVOID lpMem;
125
126// dprintf(("OS2Heap::Alloc\n"));
127 lpMem = malloc(dwBytes + HEAP_OVERHEAD);
128 if(lpMem == NULL) {
129 dprintf(("OS2Heap::Alloc, lpMem == NULL"));
130 return(NULL);
131 }
132 if(dwFlags & HEAP_ZERO_MEMORY) {
133 memset((char *)lpMem, 0, dwBytes+HEAP_OVERHEAD);
134 }
135 totalAlloc += dwBytes;
136
137 if(hmutex)
138 hmutex->enter();
139
140 if(heapelem) {
141 HEAPELEM *hnext;
142
143 hnext = heapelem;
144
145 heapelem = (HEAPELEM *)lpMem;
146 hnext->prev = heapelem;
147 heapelem->next = hnext;
148 }
149 else {
150 heapelem = (HEAPELEM *)lpMem;
151 heapelem->next = NULL;
152 }
153 heapelem->prev = NULL;
154 heapelem->flags = 0; //only used when allocated with LocalAlloc
155 heapelem->lockCnt = 0; //.. ..
156 heapelem->magic = MAGIC_NR_HEAP;
157
158 if(hmutex) {
159 hmutex->leave();
160 }
161 return(LPVOID)((char *)lpMem+sizeof(HEAPELEM));
162}
163//******************************************************************************
164//******************************************************************************
165LPVOID OS2Heap::Alloc(DWORD dwFlags, DWORD dwBytes, DWORD LocalAllocFlags)
166{
167 HEAPELEM *helem;
168 LPVOID lpMem = Alloc(dwFlags, dwBytes);
169
170 if(lpMem == NULL)
171 return(NULL);
172
173 helem = (HEAPELEM *)((char *)lpMem - sizeof(HEAPELEM));
174 helem->flags = LocalAllocFlags;
175 return(lpMem);
176}
177//******************************************************************************
178//******************************************************************************
179BOOL OS2Heap::Lock(LPVOID lpMem)
180{
181 HEAPELEM *helem = (HEAPELEM *)((char *)lpMem - sizeof(HEAPELEM));
182
183 if(lpMem == NULL)
184 return(FALSE);
185
186 if(helem->magic != MAGIC_NR_HEAP)
187 {
188 dprintf(("OS2Heap::Lock ERROR BAD HEAP POINTER:%X\n", lpMem));
189 return FALSE;
190 }
191
192 helem->lockCnt++;
193
194 return(TRUE);
195}
196//******************************************************************************
197//******************************************************************************
198BOOL OS2Heap::Unlock(LPVOID lpMem)
199{
200 HEAPELEM *helem = (HEAPELEM *)((char *)lpMem - sizeof(HEAPELEM));
201
202 if(lpMem == NULL)
203 return(FALSE);
204
205 if(helem->lockCnt == 0)
206 return(FALSE);
207
208 if(helem->magic != MAGIC_NR_HEAP)
209 {
210 dprintf(("OS2Heap::UnLock ERROR BAD HEAP POINTER:%X\n", lpMem));
211 return FALSE;
212 }
213
214 helem->lockCnt--;
215
216 return(TRUE);
217}
218//******************************************************************************
219//******************************************************************************
220DWORD OS2Heap::GetFlags(LPVOID lpMem)
221{
222 HEAPELEM *helem = (HEAPELEM *)((char *)lpMem - sizeof(HEAPELEM));
223
224 if(lpMem == NULL)
225 return(FALSE);
226
227 if(helem->magic != MAGIC_NR_HEAP)
228 {
229 dprintf(("OS2Heap::GetFlags ERROR BAD HEAP POINTER:%X\n", lpMem));
230 return FALSE;
231 }
232
233 return(helem->flags);
234}
235//******************************************************************************
236//******************************************************************************
237int OS2Heap::GetLockCnt(LPVOID lpMem)
238{
239 HEAPELEM *helem = (HEAPELEM *)((char *)lpMem - sizeof(HEAPELEM));
240
241 if(lpMem == NULL)
242 return(666);
243
244 if(helem->magic != MAGIC_NR_HEAP)
245 {
246 dprintf(("OS2Heap::GetLockCnt ERROR BAD HEAP POINTER:%X\n", lpMem));
247 return FALSE;
248 }
249
250 return(helem->lockCnt);
251}
252//******************************************************************************
253//******************************************************************************
254DWORD OS2Heap::Size(DWORD dwFlags, PVOID lpMem)
255{
256// dprintf(("OS2Heap::Size, %X\n", lpMem));
257 if(lpMem == NULL)
258 return(0);
259
260 return(_msize((char *)lpMem - sizeof(HEAPELEM)) - HEAP_OVERHEAD);
261}
262//******************************************************************************
263//******************************************************************************
264LPVOID OS2Heap::ReAlloc(DWORD dwFlags, LPVOID lpMem, DWORD dwBytes)
265{
266 HEAPELEM *helem = (HEAPELEM *)((char *)lpMem - sizeof(HEAPELEM));
267 LPVOID lpNewMem;
268 int i, oldSize;
269
270 if (dwBytes == 0) return NULL; // intercept stupid parameters
271
272 //NOTE: Allocate memory using Alloc -> WINE controls depend on this, even
273 // though it apparently doesn't work in Windows.
274 if (lpMem == 0) return Alloc(dwFlags, dwBytes);
275// if (lpMem == 0) return NULL;
276
277 if (helem->magic != MAGIC_NR_HEAP)
278 {
279 dprintf(("OS2Heap::ReAlloc ERROR BAD HEAP POINTER:%X\n", lpMem));
280 return lpMem;
281 }
282
283 oldSize = Size(0,lpMem);
284 if (oldSize == dwBytes) return lpMem; // if reallocation with same size
285 // don't do anything
286 lpNewMem = Alloc(dwFlags, dwBytes);
287 memcpy(lpNewMem, lpMem, dwBytes < oldSize ? dwBytes : oldSize);
288 Free(0, lpMem);
289
290 if(lpNewMem == NULL)
291 {
292 dprintf(("OS2Heap::ReAlloc, no more memory left\n"));
293 }
294
295 return(lpNewMem);
296}
297//******************************************************************************
298//******************************************************************************
299BOOL OS2Heap::Free(DWORD dwFlags, LPVOID lpMem)
300{
301 HEAPELEM *helem = (HEAPELEM *)((char *)lpMem - sizeof(HEAPELEM));
302
303 if(lpMem == NULL) {
304 dprintf(("OS2Heap::Free lpMem == NULL\n"));
305 return(FALSE);
306 }
307 /* verify lpMem address */
308 if (lpMem >= (LPVOID)ulMaxAddr || lpMem < (LPVOID)0x10000)
309 {
310 dprintf(("OS2Heap::Free ERROR BAD HEAP POINTER:%X\n", lpMem));
311 return FALSE;
312 }
313
314 if(helem->magic != MAGIC_NR_HEAP)
315 {
316 dprintf(("OS2Heap::Free ERROR BAD HEAP POINTER:%X\n", lpMem));
317 return FALSE;
318 }
319
320#ifdef DEBUG1
321 int size = Size(0, lpMem);
322 dprintf(("OS2Heap::Free lpMem = %X, size %d\n", lpMem, size));
323 totalAlloc -= size;
324#endif
325 if(hmutex)
326 hmutex->enter();
327
328 if(helem->prev)
329 helem->prev->next = helem->next;
330 if(helem->next)
331 helem->next->prev = helem->prev;
332 if(heapelem == helem)
333 heapelem = heapelem->next;
334
335 if(hmutex) {
336 hmutex->leave();
337 }
338
339 free((void *)helem);
340 return(TRUE);
341}
342//******************************************************************************
343//******************************************************************************
344DWORD OS2Heap::Compact(DWORD dwFlags)
345{
346 dprintf(("OS2Heap::Compact, %X- stub\n", dwFlags));
347 return(0);
348}
349//******************************************************************************
350//******************************************************************************
351BOOL OS2Heap::Validate(DWORD dwFlags, LPCVOID lpMem)
352{
353 dprintf(("OS2Heap::Validate, %X %X - stub? (TRUE)\n", dwFlags, lpMem));
354 return(TRUE);
355}
356//******************************************************************************
357//******************************************************************************
358BOOL OS2Heap::Walk(void *lpEntry)
359{
360 dprintf(("OS2Heap::Walk, %X - stub? (TRUE)\n", lpEntry));
361 return(TRUE);
362}
363//******************************************************************************
364//******************************************************************************
365OS2Heap *OS2Heap::find(HANDLE hHeap)
366{
367 OS2Heap *curheap = OS2Heap::heap;
368
369 //@@@PH NT programs seem to assume heap 0 is always valid?!
370 if (hHeap == 0)
371 if (curheap != NULL)
372 return curheap;
373
374 while(curheap != NULL) {
375 if(curheap->hPrimaryHeap == hHeap) {
376 return(curheap);
377 }
378 curheap = curheap->next;
379 }
380 dprintf(("Heap %X not found!\n", hHeap));
381 return(NULL);
382}
383//******************************************************************************
384//******************************************************************************
385OS2Heap *OS2Heap::heap = NULL;
Note: See TracBrowser for help on using the repository browser.