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

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

Fix: fixes and updates for ODINCRT support

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