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

Last change on this file since 404 was 404, checked in by phaller, 26 years ago

Fix: OS2Heap::ReAlloc() fixes for zero allocation and reallocation with same size

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