source: trunk/src/kernel32/heapshared.cpp@ 22010

Last change on this file since 22010 was 21931, checked in by dmik, 14 years ago

kernel32: Increase maximum size of internal shared heap from 2M to 8M.

This heap is used for internal resource representation (internal handle structures
and such) and may be exhausted by a badly written application that has big
resource leaks which will most likely hang or crash the Odin application (since
it generally doesn't check if the allocation returns NULL).

Since the heap space is only committed as needed, this increase should not
affect normal memory usage by Odin applications.

File size: 9.4 KB
Line 
1/* $Id: heapshared.cpp,v 1.11 2003-01-13 16:51:39 sandervl Exp $ */
2/*
3 * Shared heap functions for OS/2
4 *
5 * Initially commit 16 kb, add more when required
6 *
7 * NOTE: Hardcoded limit of 512 KB (increase when required)
8 *
9 * TODO: Not process/thread safe (initializing/destroying heap)
10 *
11 * ASSUMPTION: Rtl library takes care of protection of heap increase/decrease
12 * (from multiple threads/processes)
13 *
14 * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl)
15 *
16 */
17#define INCL_BASE
18#define INCL_DOSMEMMGR
19#define INCL_DOSPROCESS
20#include <os2wrap.h>
21#include <string.h>
22#include <dbglog.h>
23#include <stddef.h>
24#include <stdlib.h>
25#include <umalloc.h>
26#include "initterm.h"
27
28#define DBG_LOCALLOG DBG_heapshared
29#include "dbglocal.h"
30
31//
32// Global constants (keep it in sync with globaldata.asm!)
33//
34#define PAGE_SIZE 4096
35#define MAX_HEAPSIZE (8*1024*1024)
36#define MAX_HEAPPAGES (MAX_HEAPSIZE/PAGE_SIZE)
37#define INCR_HEAPSIZE (16*1024)
38
39//
40// Global DLL Data (keep it in sync with globaldata.asm!)
41//
42extern Heap_t sharedHeap; // = 0
43extern PVOID pSharedMem; // = NULL
44extern BYTE pageBitmap[MAX_HEAPPAGES]; // = {0}
45extern ULONG refCount; // = 0;
46
47static int privateRefCount = 0;
48
49void * _LNK_CONV getmoreShared(Heap_t pHeap, size_t *size, int *clean);
50void _LNK_CONV releaseShared(Heap_t pHeap, void *block, size_t size);
51
52//******************************************************************************
53//******************************************************************************
54BOOL SYSTEM InitializeSharedHeap()
55{
56 APIRET rc;
57 ULONG flAllocMem = 0, ulSysinfo;
58
59 //necessary until next WGSS update
60 if(++privateRefCount > 1) {
61 return TRUE;
62 }
63
64 rc = DosQuerySysInfo(QSV_VIRTUALADDRESSLIMIT, QSV_VIRTUALADDRESSLIMIT, &ulSysinfo, sizeof(ulSysinfo));
65 if (rc == 0 && ulSysinfo > 512) //VirtualAddresslimit is in MB
66 {
67 flAllocMem = PAG_ANY;
68 }
69
70 if(pSharedMem == NULL) {
71 rc = DosAllocSharedMem(&pSharedMem, NULL, MAX_HEAPSIZE, PAG_READ|PAG_WRITE|OBJ_GETTABLE|flAllocMem);
72 if(rc != 0) {
73 dprintf(("InitializeSharedHeap: DosAllocSharedMem failed with %d", rc));
74 return FALSE;
75 }
76 rc = DosSetMem(pSharedMem, INCR_HEAPSIZE, PAG_READ|PAG_WRITE|PAG_COMMIT);
77 if(rc != 0) {
78 DosFreeMem(pSharedMem);
79 dprintf(("InitializeSharedHeap: DosSetMem failed with %d", rc));
80 return FALSE;
81 }
82 sharedHeap = _ucreate(pSharedMem, INCR_HEAPSIZE, _BLOCK_CLEAN, _HEAP_REGULAR|_HEAP_SHARED,
83 getmoreShared, releaseShared);
84
85 if(sharedHeap == NULL) {
86 DosFreeMem(pSharedMem);
87 dprintf(("InitializeSharedHeap: _ucreate failed!"));
88 return FALSE;
89 }
90 dprintf(("KERNEL32: First InitializeSharedHeap %x %x", pSharedMem, sharedHeap));
91 for(int i=0;i<INCR_HEAPSIZE/PAGE_SIZE;i++) {
92 pageBitmap[i] = 1; //mark as committed
93 }
94 }
95 else {
96 if(DosGetSharedMem(pSharedMem, PAG_READ|PAG_WRITE) != 0) {
97 dprintf(("InitializeSharedHeap: DosGetSharedMem failed!"));
98 return FALSE;
99 }
100 dprintf(("KERNEL32: InitializeSharedHeap %x %x refcount %d", pSharedMem, sharedHeap, refCount));
101 if(_uopen(sharedHeap) != 0) {
102 dprintf(("InitializeSharedHeap: unable to open shared heap!"));
103 return FALSE;
104 }
105 }
106 refCount++;
107 return TRUE;
108}
109//******************************************************************************
110//******************************************************************************
111#ifdef DEBUG
112int _LNK_CONV callback_function(const void *pentry, size_t sz, int useflag, int status,
113 const char *filename, size_t line)
114{
115 if (_HEAPOK != status) {
116 dprintf(("status is not _HEAPOK."));
117 return 1;
118 }
119 if (_USEDENTRY == useflag && sz && filename && line) {
120 dprintf(("allocated %08x %u at %s %d\n", pentry, sz, filename, line));
121 }
122 else dprintf(("allocated %08x %u", pentry, sz));
123
124 return 0;
125}
126#endif
127//******************************************************************************
128//******************************************************************************
129void SYSTEM DestroySharedHeap()
130{
131 dprintf(("KERNEL32: DestroySharedHeap %d", refCount));
132 if(--privateRefCount > 0) {
133 return;
134 }
135
136#ifdef DEBUG
137 _uheap_walk(sharedHeap, callback_function);
138 dprintf((NULL));
139#endif
140
141 if(--refCount == 0) {
142 if(sharedHeap) {
143 _uclose(sharedHeap);
144 _udestroy(sharedHeap, _FORCE);
145 sharedHeap = NULL;
146 }
147 if(pSharedMem) {
148 DosFreeMem(pSharedMem);
149 pSharedMem = NULL;
150 }
151 }
152 else {
153 _uclose(sharedHeap);
154 }
155}
156//******************************************************************************
157//******************************************************************************
158ULONG GetPageRangeFree(ULONG pageoffset)
159{
160 dprintf(("KERNEL32: GetPageRangeFree(%08xh)", pageoffset));
161
162 int i;
163 for(i=pageoffset;i<MAX_HEAPPAGES;i++) {
164 if(pageBitmap[i] == 1) {
165 break;
166 }
167 }
168 return i-pageoffset;
169}
170//******************************************************************************
171//******************************************************************************
172void * _LNK_CONV getmoreShared(Heap_t pHeap, size_t *size, int *clean)
173{
174 APIRET rc;
175 ULONG newsize;
176 PVOID newblock;
177
178 dprintf(("KERNEL32: getmoreShared(%08xh, %08xh, %08xh)\n", pHeap, *size, *clean));
179
180 /* round the size up to a multiple of 4K */
181 // *size = (*size / 4096) * 4096 + 4096;
182 // @@@PH speed improvement
183 *size = (*size + 4096) & 0xFFFFF000;
184 *size = max(*size, INCR_HEAPSIZE);
185
186 for(int i=0;i<MAX_HEAPPAGES;i++)
187 {
188 int nrpagesfree = GetPageRangeFree(i);
189 if(nrpagesfree >= *size/PAGE_SIZE)
190 {
191 newblock = (PVOID)((ULONG)pSharedMem + i*PAGE_SIZE);
192 rc = DosSetMem(newblock, *size, PAG_READ|PAG_WRITE|PAG_COMMIT);
193 if(rc != 0) {
194 dprintf(("getmoreShared: DosSetMem failed with %d", rc));
195 return NULL;
196 }
197 for(int j=0;j < *size/PAGE_SIZE; j++)
198 {
199 pageBitmap[i+j] = 1; //mark as committed
200 }
201
202 *clean = _BLOCK_CLEAN;
203 dprintf(("KERNEL32: getmoreShared %x %d", newblock, *size));
204 return newblock;
205 }
206 if(nrpagesfree)
207 i += nrpagesfree-1;
208 }
209 dprintf(("KERNEL32: getmoreShared NOTHING LEFT (%d)", *size));
210 return NULL;
211}
212//******************************************************************************
213//******************************************************************************
214void _LNK_CONV releaseShared(Heap_t pHeap, void *block, size_t size)
215{
216 ULONG pagenr;
217
218 dprintf(("KERNEL32: releaseShared %x %d", block, size));
219 DosSetMem(block, size, PAG_READ|PAG_WRITE|PAG_DECOMMIT);
220
221 pagenr = (ULONG)block - (ULONG)pSharedMem;
222 pagenr /= PAGE_SIZE;
223 for(int i=pagenr;i<pagenr+size/PAGE_SIZE;i++) {
224 pageBitmap[i] = 0; //mark as decommitted
225 }
226}
227//******************************************************************************
228//******************************************************************************
229void * SYSTEM _smalloc(int size)
230{
231 void *chunk;
232
233 chunk = _umalloc(sharedHeap, size);
234 dprintf(("_smalloc %x returned %x", size, chunk));
235 return chunk;
236}
237//******************************************************************************
238//******************************************************************************
239void * SYSTEM _smallocfill(int size, int filler)
240{
241 void *chunk;
242
243 chunk = _umalloc(sharedHeap, size);
244 if(chunk) {
245 memset(chunk, 0, size);
246 }
247 dprintf(("_smallocfill %x %x returned %x", size, filler, chunk));
248 return chunk;
249}
250//******************************************************************************
251//******************************************************************************
252void SYSTEM _sfree(void *block)
253{
254 dprintf(("_sfree %x", block));
255 free(block);
256}
257//******************************************************************************
258//******************************************************************************
259void * _System _debug_smalloc(int size, const char *pszFile, int linenr)
260{
261 void *chunk;
262
263#ifdef __DEBUG_ALLOC__
264 chunk = _debug_umalloc(sharedHeap, size, pszFile, linenr);
265#else
266 chunk = _umalloc(sharedHeap, size);
267#endif
268 dprintf(("_smalloc %x returned %x", size, chunk));
269 return chunk;
270}
271//******************************************************************************
272//******************************************************************************
273void * _System _debug_smallocfill(int size, int filler, const char *pszFile, int linenr)
274{
275 void *chunk;
276
277#ifdef __DEBUG_ALLOC__
278 chunk = _debug_umalloc(sharedHeap, size, pszFile, linenr);
279#else
280 chunk = _umalloc(sharedHeap, size);
281#endif
282 if(chunk) {
283 memset(chunk, 0, size);
284 }
285 dprintf(("_smallocfill %x %x returned %x", size, filler, chunk));
286 return chunk;
287}
288//******************************************************************************
289//******************************************************************************
290void _System _debug_sfree(void *chunk, const char *pszFile, int linenr)
291{
292 dprintf(("_sfree %x", chunk));
293#ifdef __DEBUG_ALLOC__
294 _debug_free(chunk, pszFile, linenr);
295#else
296 free(chunk);
297#endif
298}
299//******************************************************************************
300//******************************************************************************
Note: See TracBrowser for help on using the repository browser.