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

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

exception handler changes + EB's HeapReAlloc fix

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