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

Last change on this file since 9667 was 9667, checked in by sandervl, 23 years ago

Don't allocate selectors anymore. Allocate tiled memory and call Dos32FlatToSel; Get default stack size from PE header; Thread handles not closed properly

File size: 6.9 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#include <os2wrap.h>
20#include <string.h>
21#include <dbglog.h>
22#include <heapshared.h>
23#include "initterm.h"
24
25#define DBG_LOCALLOG DBG_heapshared
26#include "dbglocal.h"
27
28#define MAX_HEAPSIZE (2048*1024)
29#define MAX_HEAPPAGES (MAX_HEAPSIZE/PAGE_SIZE)
30#define INCR_HEAPSIZE (16*1024)
31
32//Global DLL Data
33#pragma data_seg(_GLOBALDATA)
34 Heap_t sharedHeap = 0;
35static PVOID pSharedMem = NULL;
36static BYTE pageBitmap[MAX_HEAPPAGES] = {0};
37static ULONG refCount = 0;
38#pragma data_seg()
39
40static int privateRefCount = 0;
41
42void * _LNK_CONV getmoreShared(Heap_t pHeap, size_t *size, int *clean);
43void _LNK_CONV releaseShared(Heap_t pHeap, void *block, size_t size);
44
45//******************************************************************************
46//******************************************************************************
47BOOL SYSTEM InitializeSharedHeap()
48{
49 APIRET rc;
50 ULONG flAllocMem = 0, ulSysinfo;
51
52 //necessary until next WGSS update
53 if(++privateRefCount > 1) {
54 return TRUE;
55 }
56
57 rc = DosQuerySysInfo(QSV_VIRTUALADDRESSLIMIT, QSV_VIRTUALADDRESSLIMIT, &ulSysinfo, sizeof(ulSysinfo));
58 if (rc == 0 && ulSysinfo > 512) //VirtualAddresslimit is in MB
59 {
60 flAllocMem = PAG_ANY;
61 }
62
63 if(pSharedMem == NULL) {
64 rc = DosAllocSharedMem(&pSharedMem, NULL, MAX_HEAPSIZE, PAG_READ|PAG_WRITE|OBJ_GETTABLE|flAllocMem);
65 if(rc != 0) {
66 dprintf(("InitializeSharedHeap: DosAllocSharedMem failed with %d", rc));
67 return FALSE;
68 }
69 rc = DosSetMem(pSharedMem, INCR_HEAPSIZE, PAG_READ|PAG_WRITE|PAG_COMMIT);
70 if(rc != 0) {
71 DosFreeMem(pSharedMem);
72 dprintf(("InitializeSharedHeap: DosSetMem failed with %d", rc));
73 return FALSE;
74 }
75 sharedHeap = _ucreate(pSharedMem, INCR_HEAPSIZE, _BLOCK_CLEAN, _HEAP_REGULAR|_HEAP_SHARED,
76 getmoreShared, releaseShared);
77
78 if(sharedHeap == NULL) {
79 DosFreeMem(pSharedMem);
80 dprintf(("InitializeSharedHeap: _ucreate failed!"));
81 return FALSE;
82 }
83 dprintf(("KERNEL32: First InitializeSharedHeap %x %x", pSharedMem, sharedHeap));
84 for(int i=0;i<INCR_HEAPSIZE/PAGE_SIZE;i++) {
85 pageBitmap[i] = 1; //mark as committed
86 }
87 }
88 else {
89 if(DosGetSharedMem(pSharedMem, PAG_READ|PAG_WRITE) != 0) {
90 dprintf(("InitializeSharedHeap: DosGetSharedMem failed!"));
91 return FALSE;
92 }
93 dprintf(("KERNEL32: InitializeSharedHeap %x %x refcount %d", pSharedMem, sharedHeap, refCount));
94 if(_uopen(sharedHeap) != 0) {
95 dprintf(("InitializeSharedHeap: unable to open shared heap!"));
96 return FALSE;
97 }
98 }
99 refCount++;
100 return TRUE;
101}
102//******************************************************************************
103//******************************************************************************
104void SYSTEM DestroySharedHeap()
105{
106 dprintf(("KERNEL32: DestroySharedHeap %d", refCount));
107 if(--privateRefCount > 0) {
108 return;
109 }
110 if(--refCount == 0) {
111 if(sharedHeap) {
112 _uclose(sharedHeap);
113 _udestroy(sharedHeap, _FORCE);
114 sharedHeap = NULL;
115 }
116 if(pSharedMem) {
117 DosFreeMem(pSharedMem);
118 pSharedMem = NULL;
119 }
120 }
121 else {
122 _uclose(sharedHeap);
123 }
124}
125//******************************************************************************
126//******************************************************************************
127ULONG GetPageRangeFree(ULONG pageoffset)
128{
129 dprintf(("KERNEL32: GetPageRangeFree(%08xh)", pageoffset));
130
131 for(int i=pageoffset;i<MAX_HEAPPAGES;i++) {
132 if(pageBitmap[i] == 1) {
133 break;
134 }
135 }
136 return i-pageoffset;
137}
138//******************************************************************************
139//******************************************************************************
140void * _LNK_CONV getmoreShared(Heap_t pHeap, size_t *size, int *clean)
141{
142 APIRET rc;
143 ULONG newsize;
144 PVOID newblock;
145
146 dprintf(("KERNEL32: getmoreShared(%08xh, %08xh, %08xh)\n", pHeap, *size, *clean));
147
148 /* round the size up to a multiple of 4K */
149 // *size = (*size / 4096) * 4096 + 4096;
150 // @@@PH speed improvement
151 *size = (*size + 4096) & 0xFFFFF000;
152 *size = max(*size, INCR_HEAPSIZE);
153
154 for(int i=0;i<MAX_HEAPPAGES;i++)
155 {
156 int nrpagesfree = GetPageRangeFree(i);
157 if(nrpagesfree >= *size/PAGE_SIZE)
158 {
159 newblock = (PVOID)((ULONG)pSharedMem + i*PAGE_SIZE);
160 rc = DosSetMem(newblock, *size, PAG_READ|PAG_WRITE|PAG_COMMIT);
161 if(rc != 0) {
162 dprintf(("getmoreShared: DosSetMem failed with %d", rc));
163 return NULL;
164 }
165 for(int j=0;j < *size/PAGE_SIZE; j++)
166 {
167 pageBitmap[i+j] = 1; //mark as committed
168 }
169
170 *clean = _BLOCK_CLEAN;
171 dprintf(("KERNEL32: getmoreShared %x %d", newblock, *size));
172 return newblock;
173 }
174 if(nrpagesfree)
175 i += nrpagesfree-1;
176 }
177 dprintf(("KERNEL32: getmoreShared NOTHING LEFT (%d)", *size));
178 return NULL;
179}
180//******************************************************************************
181//******************************************************************************
182void _LNK_CONV releaseShared(Heap_t pHeap, void *block, size_t size)
183{
184 ULONG pagenr;
185
186 dprintf(("KERNEL32: releaseShared %x %d", block, size));
187 DosSetMem(block, size, PAG_READ|PAG_WRITE|PAG_DECOMMIT);
188
189 pagenr = (ULONG)block - (ULONG)pSharedMem;
190 pagenr /= PAGE_SIZE;
191 for(int i=pagenr;i<pagenr+size/PAGE_SIZE;i++) {
192 pageBitmap[i] = 0; //mark as decommitted
193 }
194}
195//******************************************************************************
196//******************************************************************************
197void * SYSTEM _smalloc(int size)
198{
199 void *chunk;
200
201 chunk = _umalloc(sharedHeap, size);
202 dprintf2(("_smalloc %x returned %x", size, chunk));
203 return chunk;
204}
205//******************************************************************************
206//******************************************************************************
207void * SYSTEM _smallocfill(int size, int filler)
208{
209 void *chunk;
210
211 chunk = _umalloc(sharedHeap, size);
212 if(chunk) {
213 memset(chunk, 0, size);
214 }
215 dprintf2(("_smallocfill %x %x returned %x", size, filler, chunk));
216 return chunk;
217}
218//******************************************************************************
219//******************************************************************************
Note: See TracBrowser for help on using the repository browser.