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

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

HeapReAlloc change (for wine controls)

File size: 9.2 KB
Line 
1/* $Id: os2heap.cpp,v 1.10 1999-10-01 16:03:10 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
153 if(hmutex) {
154 hmutex->leave();
155 }
156 return(LPVOID)((char *)lpMem+sizeof(HEAPELEM));
157}
158//******************************************************************************
159//******************************************************************************
160LPVOID OS2Heap::Alloc(DWORD dwFlags, DWORD dwBytes, DWORD LocalAllocFlags)
161{
162 HEAPELEM *helem;
163 LPVOID lpMem = Alloc(dwFlags, dwBytes);
164
165 if(lpMem == NULL)
166 return(NULL);
167
168 helem = (HEAPELEM *)((char *)lpMem - sizeof(HEAPELEM));
169 helem->flags = LocalAllocFlags;
170 return(lpMem);
171}
172//******************************************************************************
173//******************************************************************************
174BOOL OS2Heap::Lock(LPVOID lpMem)
175{
176 HEAPELEM *helem = (HEAPELEM *)((char *)lpMem - sizeof(HEAPELEM));
177
178 if(lpMem == NULL)
179 return(FALSE);
180
181 helem->lockCnt++;
182
183 return(TRUE);
184}
185//******************************************************************************
186//******************************************************************************
187BOOL OS2Heap::Unlock(LPVOID lpMem)
188{
189 HEAPELEM *helem = (HEAPELEM *)((char *)lpMem - sizeof(HEAPELEM));
190
191 if(lpMem == NULL)
192 return(FALSE);
193
194 if(helem->lockCnt == 0)
195 return(FALSE);
196
197 helem->lockCnt--;
198
199 return(TRUE);
200}
201//******************************************************************************
202//******************************************************************************
203DWORD OS2Heap::GetFlags(LPVOID lpMem)
204{
205 HEAPELEM *helem = (HEAPELEM *)((char *)lpMem - sizeof(HEAPELEM));
206
207 if(lpMem == NULL)
208 return(FALSE);
209
210 return(helem->flags);
211}
212//******************************************************************************
213//******************************************************************************
214int OS2Heap::GetLockCnt(LPVOID lpMem)
215{
216 HEAPELEM *helem = (HEAPELEM *)((char *)lpMem - sizeof(HEAPELEM));
217
218 if(lpMem == NULL)
219 return(666);
220
221 return(helem->lockCnt);
222}
223//******************************************************************************
224//******************************************************************************
225DWORD OS2Heap::Size(DWORD dwFlags, PVOID lpMem)
226{
227// dprintf(("OS2Heap::Size, %X\n", lpMem));
228 if(lpMem == NULL)
229 return(0);
230
231 return(_msize((char *)lpMem - sizeof(HEAPELEM)) - HEAP_OVERHEAD);
232}
233//******************************************************************************
234//******************************************************************************
235LPVOID OS2Heap::ReAlloc(DWORD dwFlags, LPVOID lpMem, DWORD dwBytes)
236{
237 LPVOID lpNewMem;
238 int i;
239
240 if (dwBytes == 0) return NULL; // intercept stupid parameters
241
242 //NOTE: Allocate memory using Alloc -> WINE controls depend on this, even
243 // though it apparently doesn't work in Windows.
244 if (lpMem == 0) return Alloc(dwFlags, dwBytes);
245// if (lpMem == 0) return NULL;
246
247 if (Size(0,lpMem) == dwBytes) return lpMem; // if reallocation with same size
248 // don't do anything
249
250// dprintf(("OS2Heap::ReAlloc %X %X %d\n", dwFlags, lpMem, dwBytes));
251 lpNewMem = Alloc(dwFlags, dwBytes);
252 memcpy(lpNewMem, lpMem, Size(0, lpMem));
253 Free(0, lpMem);
254
255 dassert(lpNewMem, ("OS2Heap::ReAlloc, no more memory left\n"));
256
257 return(lpNewMem);
258}
259//******************************************************************************
260//******************************************************************************
261BOOL OS2Heap::Free(DWORD dwFlags, LPVOID lpMem)
262{
263 HEAPELEM *helem = (HEAPELEM *)((char *)lpMem - sizeof(HEAPELEM));
264
265 if(lpMem == NULL) {
266 dprintf(("OS2Heap::Free lpMem == NULL\n"));
267 return(FALSE);
268 }
269#ifdef DEBUG1
270 int size = Size(0, lpMem);
271 dprintf(("OS2Heap::Free lpMem = %X, size %d\n", lpMem, size));
272 totalAlloc -= size;
273#endif
274 if(hmutex)
275 hmutex->enter();
276
277 if(helem->prev)
278 helem->prev->next = helem->next;
279 if(helem->next)
280 helem->next->prev = helem->prev;
281 if(heapelem == helem)
282 heapelem = heapelem->next;
283
284 if(hmutex) {
285 hmutex->leave();
286 }
287
288 free((void *)helem);
289 return(TRUE);
290}
291//******************************************************************************
292//******************************************************************************
293DWORD OS2Heap::Compact(DWORD dwFlags)
294{
295 dprintf(("OS2Heap::Compact, %X- stub\n", dwFlags));
296 return(0);
297}
298//******************************************************************************
299//******************************************************************************
300BOOL OS2Heap::Validate(DWORD dwFlags, LPCVOID lpMem)
301{
302 dprintf(("OS2Heap::Validate, %X %X - stub? (TRUE)\n", dwFlags, lpMem));
303 return(TRUE);
304}
305//******************************************************************************
306//******************************************************************************
307BOOL OS2Heap::Walk(void *lpEntry)
308{
309 dprintf(("OS2Heap::Walk, %X - stub? (TRUE)\n", lpEntry));
310 return(TRUE);
311}
312//******************************************************************************
313//******************************************************************************
314OS2Heap *OS2Heap::find(HANDLE hHeap)
315{
316 OS2Heap *curheap = OS2Heap::heap;
317
318 //@@@PH NT programs seem to assume heap 0 is always valid?!
319 if (hHeap == 0)
320 if (curheap != NULL)
321 return curheap;
322
323 while(curheap != NULL) {
324 if(curheap->hPrimaryHeap == hHeap) {
325 return(curheap);
326 }
327 curheap = curheap->next;
328 }
329 dprintf(("Heap %X not found!\n", hHeap));
330 return(NULL);
331}
332//******************************************************************************
333//******************************************************************************
334OS2Heap *OS2Heap::heap = NULL;
Note: See TracBrowser for help on using the repository browser.