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

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

Lots of changes by several people (see changelog for 4 October

File size: 10.1 KB
Line 
1/* $Id: os2heap.cpp,v 1.11 1999-10-04 09:55:56 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;
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 if (Size(0,lpMem) == dwBytes) return lpMem; // if reallocation with same size
280 // don't do anything
281
282// dprintf(("OS2Heap::ReAlloc %X %X %d\n", dwFlags, lpMem, dwBytes));
283 lpNewMem = Alloc(dwFlags, dwBytes);
284 memcpy(lpNewMem, lpMem, Size(0, lpMem));
285 Free(0, lpMem);
286
287 dassert(lpNewMem, ("OS2Heap::ReAlloc, no more memory left\n"));
288
289 return(lpNewMem);
290}
291//******************************************************************************
292//******************************************************************************
293BOOL OS2Heap::Free(DWORD dwFlags, LPVOID lpMem)
294{
295 HEAPELEM *helem = (HEAPELEM *)((char *)lpMem - sizeof(HEAPELEM));
296
297 if(lpMem == NULL) {
298 dprintf(("OS2Heap::Free lpMem == NULL\n"));
299 return(FALSE);
300 }
301
302 if(helem->magic != MAGIC_NR_HEAP)
303 {
304 dprintf(("OS2Heap::Free ERROR BAD HEAP POINTER:%X\n", lpMem));
305 return FALSE;
306 }
307
308#ifdef DEBUG1
309 int size = Size(0, lpMem);
310 dprintf(("OS2Heap::Free lpMem = %X, size %d\n", lpMem, size));
311 totalAlloc -= size;
312#endif
313 if(hmutex)
314 hmutex->enter();
315
316 if(helem->prev)
317 helem->prev->next = helem->next;
318 if(helem->next)
319 helem->next->prev = helem->prev;
320 if(heapelem == helem)
321 heapelem = heapelem->next;
322
323 if(hmutex) {
324 hmutex->leave();
325 }
326
327 free((void *)helem);
328 return(TRUE);
329}
330//******************************************************************************
331//******************************************************************************
332DWORD OS2Heap::Compact(DWORD dwFlags)
333{
334 dprintf(("OS2Heap::Compact, %X- stub\n", dwFlags));
335 return(0);
336}
337//******************************************************************************
338//******************************************************************************
339BOOL OS2Heap::Validate(DWORD dwFlags, LPCVOID lpMem)
340{
341 dprintf(("OS2Heap::Validate, %X %X - stub? (TRUE)\n", dwFlags, lpMem));
342 return(TRUE);
343}
344//******************************************************************************
345//******************************************************************************
346BOOL OS2Heap::Walk(void *lpEntry)
347{
348 dprintf(("OS2Heap::Walk, %X - stub? (TRUE)\n", lpEntry));
349 return(TRUE);
350}
351//******************************************************************************
352//******************************************************************************
353OS2Heap *OS2Heap::find(HANDLE hHeap)
354{
355 OS2Heap *curheap = OS2Heap::heap;
356
357 //@@@PH NT programs seem to assume heap 0 is always valid?!
358 if (hHeap == 0)
359 if (curheap != NULL)
360 return curheap;
361
362 while(curheap != NULL) {
363 if(curheap->hPrimaryHeap == hHeap) {
364 return(curheap);
365 }
366 curheap = curheap->next;
367 }
368 dprintf(("Heap %X not found!\n", hHeap));
369 return(NULL);
370}
371//******************************************************************************
372//******************************************************************************
373OS2Heap *OS2Heap::heap = NULL;
Note: See TracBrowser for help on using the repository browser.