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

Last change on this file since 6184 was 6184, checked in by sandervl, 24 years ago

heap updates/fixes

File size: 8.3 KB
Line 
1/* $Id: os2heap.cpp,v 1.19 2001-07-06 13:47:19 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 <stdlib.h>
21#include <string.h>
22
23#include "win32type.h"
24#include "os2heap.h"
25#include "misc.h"
26#include "vmutex.h"
27#include "initterm.h"
28#include <odin32validate.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->lpMem);
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 HEAPELEM *lpHeapObj;
125 LPVOID lpMem;
126
127// dprintf(("OS2Heap::Alloc\n"));
128 lpMem = malloc(dwBytes + HEAP_OVERHEAD);
129 if(lpMem == NULL) {
130 dprintf(("OS2Heap::Alloc, lpMem == NULL"));
131 return(NULL);
132 }
133 if(dwFlags & HEAP_ZERO_MEMORY) {
134 memset(lpMem, 0, dwBytes+HEAP_OVERHEAD);
135 }
136 totalAlloc += dwBytes;
137
138 //align at 8 byte boundary
139 lpHeapObj = (HEAPELEM *)(((ULONG)lpMem+7) & ~7);
140 lpHeapObj->lpMem = lpMem;
141
142 if(hmutex)
143 hmutex->enter();
144
145 lpHeapObj->next = heapelem;
146 lpHeapObj->prev = NULL;
147 lpHeapObj->magic = MAGIC_NR_HEAP;
148 if(heapelem) {
149 heapelem->prev = lpHeapObj;
150 }
151 heapelem = lpHeapObj;
152
153 if(hmutex) {
154 hmutex->leave();
155 }
156 return(LPVOID)(lpHeapObj+1);
157}
158//******************************************************************************
159//******************************************************************************
160DWORD OS2Heap::Size(DWORD dwFlags, PVOID lpMem)
161{
162 HEAPELEM *helem = GET_HEAPOBJ(lpMem);
163
164 if(lpMem == NULL) {
165 dprintf(("OS2Heap::Size lpMem == NULL\n"));
166 return -1;
167 }
168 /* verify lpMem address */
169 if (lpMem >= (LPVOID)ulMaxAddr || lpMem < (LPVOID)0x10000)
170 {
171 dprintf(("OS2Heap::Size ERROR BAD HEAP POINTER:%X\n", lpMem));
172 return -1;
173 }
174
175 if(helem->magic != MAGIC_NR_HEAP)
176 {
177 dprintf(("OS2Heap::Size ERROR BAD HEAP POINTER:%X\n", lpMem));
178 return -1;
179 }
180
181 return(_msize(helem->lpMem) - HEAP_OVERHEAD);
182}
183//******************************************************************************
184//******************************************************************************
185LPVOID OS2Heap::ReAlloc(DWORD dwFlags, LPVOID lpMem, DWORD dwBytes)
186{
187 HEAPELEM *helem = GET_HEAPOBJ(lpMem);
188 LPVOID lpNewMem;
189 int i, oldSize;
190
191 if (dwBytes == 0) return NULL; // intercept stupid parameters
192
193 //NOTE: Allocate memory using Alloc -> WINE controls depend on this, even
194 // though it apparently doesn't work in Windows.
195 if (lpMem == 0) return Alloc(dwFlags, dwBytes);
196// if (lpMem == 0) return NULL;
197
198 if (helem->magic != MAGIC_NR_HEAP)
199 {
200 dprintf(("OS2Heap::ReAlloc ERROR BAD HEAP POINTER:%X\n", lpMem));
201 return lpMem;
202 }
203
204 oldSize = Size(0,lpMem);
205 if (oldSize >= dwBytes) {
206 dprintf(("ReAlloc with smaller size than original (%d); return old pointer", oldSize));
207 return lpMem; // if reallocation with same size don't do anything
208 }
209 lpNewMem = Alloc(dwFlags, dwBytes);
210 memcpy(lpNewMem, lpMem, dwBytes < oldSize ? dwBytes : oldSize);
211 Free(0, lpMem);
212
213 if(lpNewMem == NULL)
214 {
215 dprintf(("OS2Heap::ReAlloc, no more memory left\n"));
216 }
217
218 return(lpNewMem);
219}
220//******************************************************************************
221//******************************************************************************
222BOOL OS2Heap::Free(DWORD dwFlags, LPVOID lpMem)
223{
224 HEAPELEM *helem = GET_HEAPOBJ(lpMem);
225
226 if(lpMem == NULL) {
227 dprintf(("OS2Heap::Free lpMem == NULL\n"));
228 return(FALSE);
229 }
230 /* verify lpMem address */
231 if (lpMem >= (LPVOID)ulMaxAddr || lpMem < (LPVOID)0x10000)
232 {
233 dprintf(("OS2Heap::Free ERROR BAD HEAP POINTER:%X\n", lpMem));
234 return FALSE;
235 }
236
237 if(helem->magic != MAGIC_NR_HEAP)
238 {
239 dprintf(("OS2Heap::Free ERROR BAD HEAP POINTER:%X\n", lpMem));
240 return FALSE;
241 }
242
243#ifdef DEBUG1
244 int size = Size(0, lpMem);
245 dprintf(("OS2Heap::Free lpMem = %X, size %d\n", lpMem, size));
246 totalAlloc -= size;
247#endif
248 if(hmutex)
249 hmutex->enter();
250
251 if(helem->prev)
252 helem->prev->next = helem->next;
253 if(helem->next)
254 helem->next->prev = helem->prev;
255 if(heapelem == helem)
256 heapelem = heapelem->next;
257
258 if(hmutex) {
259 hmutex->leave();
260 }
261
262 free(helem->lpMem);
263 return(TRUE);
264}
265//******************************************************************************
266//******************************************************************************
267DWORD OS2Heap::Compact(DWORD dwFlags)
268{
269 dprintf(("OS2Heap::Compact, %X- stub\n", dwFlags));
270 return(0);
271}
272//******************************************************************************
273//******************************************************************************
274BOOL OS2Heap::Validate(DWORD dwFlags, LPCVOID lpMem)
275{
276 dprintf(("OS2Heap::Validate, %X %X - stub? (TRUE)\n", dwFlags, lpMem));
277 return(TRUE);
278}
279//******************************************************************************
280//******************************************************************************
281BOOL OS2Heap::Walk(void *lpEntry)
282{
283 dprintf(("OS2Heap::Walk, %X - stub? (TRUE)\n", lpEntry));
284 return(TRUE);
285}
286//******************************************************************************
287//******************************************************************************
288OS2Heap *OS2Heap::find(HANDLE hHeap)
289{
290 OS2Heap *curheap = OS2Heap::heap;
291
292 //@@@PH NT programs seem to assume heap 0 is always valid?!
293 if (hHeap == 0)
294 if (curheap != NULL)
295 return curheap;
296
297 while(curheap != NULL) {
298 if(curheap->hPrimaryHeap == hHeap) {
299 return(curheap);
300 }
301 curheap = curheap->next;
302 }
303 dprintf(("Heap %X not found!\n", hHeap));
304 return(NULL);
305}
306//******************************************************************************
307//******************************************************************************
308OS2Heap *OS2Heap::heap = NULL;
Note: See TracBrowser for help on using the repository browser.