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

Last change on this file since 3704 was 3704, checked in by phaller, 25 years ago

Fix: StarCraft STORM.DLL requires reserved DllEntryPoint parameter

File size: 5.6 KB
Line 
1/* $Id: heapshared.cpp,v 1.6 2000-06-14 02:27:33 phaller 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 <misc.h>
21#include <heapshared.h>
22
23#define DBG_LOCALLOG DBG_heapshared
24#include "dbglocal.h"
25
26//Global DLL Data
27#pragma data_seg(_GLOBALDATA)
28 Heap_t sharedHeap = 0;
29static PVOID pSharedMem = NULL;
30static BYTE pageBitmap[MAX_HEAPPAGES] = {0};
31static ULONG refCount = 0;
32#pragma data_seg()
33
34void * _LNK_CONV getmoreShared(Heap_t pHeap, size_t *size, int *clean);
35void _LNK_CONV releaseShared(Heap_t pHeap, void *block, size_t size);
36
37//******************************************************************************
38//******************************************************************************
39BOOL InitializeSharedHeap()
40{
41 APIRET rc;
42
43 if(pSharedMem == NULL) {
44 dprintf(("KERNEL32: InitializeSharedHeap %x", &sharedHeap));
45 rc = DosAllocSharedMem(&pSharedMem, NULL, MAX_HEAPSIZE, PAG_READ|PAG_WRITE|OBJ_GETTABLE);
46 if(rc != 0) {
47 dprintf(("InitializeSharedHeap: DosAllocSharedMem failed with %d", rc));
48 return FALSE;
49 }
50 rc = DosSetMem(pSharedMem, INCR_HEAPSIZE, PAG_READ|PAG_WRITE|PAG_COMMIT);
51 if(rc != 0) {
52 DosFreeMem(pSharedMem);
53 dprintf(("InitializeSharedHeap: DosSetMem failed with %d", rc));
54 return FALSE;
55 }
56 sharedHeap = _ucreate(pSharedMem, INCR_HEAPSIZE, _BLOCK_CLEAN,
57 _HEAP_REGULAR|_HEAP_SHARED,
58 getmoreShared, releaseShared);
59
60 if(sharedHeap == NULL) {
61 DosFreeMem(pSharedMem);
62 dprintf(("InitializeSharedHeap: _ucreate failed!"));
63 return FALSE;
64 }
65 for(int i=0;i<INCR_HEAPSIZE/PAGE_SIZE;i++) {
66 pageBitmap[i] = 1; //mark as committed
67 }
68 }
69 else {
70 if(DosGetSharedMem(pSharedMem, PAG_READ|PAG_WRITE) != 0) {
71 dprintf(("InitializeSharedHeap: DosGetSharedMem failed!"));
72 return FALSE;
73 }
74 if(_uopen(sharedHeap) != 0) {
75 dprintf(("InitializeSharedHeap: unable to open shared heap!"));
76 return FALSE;
77 }
78 }
79 refCount++;
80 return TRUE;
81}
82//******************************************************************************
83//******************************************************************************
84void DestroySharedHeap()
85{
86 dprintf(("KERNEL32: DestroySharedHeap %d", refCount));
87 if(--refCount == 0) {
88 if(sharedHeap) {
89 _uclose(sharedHeap);
90 _udestroy(sharedHeap, _FORCE);
91 sharedHeap = NULL;
92 }
93 if(pSharedMem) {
94 DosFreeMem(pSharedMem);
95 pSharedMem = NULL;
96 }
97 }
98 else {
99 _uclose(sharedHeap);
100 }
101}
102//******************************************************************************
103//******************************************************************************
104void *_smalloc(size_t size)
105{
106 return _umalloc(sharedHeap, size);
107}
108//******************************************************************************
109//******************************************************************************
110ULONG GetPageRangeFree(ULONG pageoffset)
111{
112 dprintf(("KERNEL32: GetPageRangeFree(%08xh)\n",
113 pageoffset));
114
115 for(int i=pageoffset;i<MAX_HEAPPAGES;i++) {
116 if(pageBitmap[i] == 1) {
117 break;
118 }
119 }
120 return i-pageoffset;
121}
122//******************************************************************************
123//******************************************************************************
124void * _LNK_CONV getmoreShared(Heap_t pHeap, size_t *size, int *clean)
125{
126 APIRET rc;
127 ULONG newsize;
128 PVOID newblock;
129
130 dprintf(("KERNEL32: getmoreShared(%08xh, %08xh, %08xh)\n",
131 pHeap,
132 *size,
133 *clean));
134
135 /* round the size up to a multiple of 4K */
136 // *size = (*size / 4096) * 4096 + 4096;
137 // @@@PH speed improvement
138 *size = (*size + 4096) & 0xFFFFF000;
139 *size = max(*size, INCR_HEAPSIZE);
140
141 for(int i=0;i<MAX_HEAPPAGES;i++)
142 {
143 int nrpagesfree = GetPageRangeFree(i);
144 if(nrpagesfree >= *size/PAGE_SIZE) {
145 newblock = (PVOID)((ULONG)pSharedMem + i*PAGE_SIZE);
146 rc = DosSetMem(newblock, *size, PAG_READ|PAG_WRITE|PAG_COMMIT);
147 if(rc != 0) {
148 dprintf(("getmoreShared: DosSetMem failed with %d", rc));
149 return NULL;
150 }
151 for(int j=0;j < *size/PAGE_SIZE; j++)
152 {
153 pageBitmap[i+j] = 1; //mark as committed
154 }
155
156 *clean = _BLOCK_CLEAN;
157 dprintf(("KERNEL32: getmoreShared %x %d", newblock, *size));
158 return newblock;
159 }
160 if(nrpagesfree)
161 i += nrpagesfree-1;
162 }
163 dprintf(("KERNEL32: getmoreShared NOTHING LEFT (%d)", *size));
164 return NULL;
165}
166//******************************************************************************
167//******************************************************************************
168void _LNK_CONV releaseShared(Heap_t pHeap, void *block, size_t size)
169{
170 ULONG pagenr;
171
172 dprintf(("KERNEL32: releaseShared %x %d", block, size));
173 DosSetMem(block, size, PAG_READ|PAG_WRITE|PAG_DECOMMIT);
174
175 pagenr = (ULONG)block - (ULONG)pSharedMem;
176 pagenr /= PAGE_SIZE;
177 for(int i=pagenr;i<pagenr+size/PAGE_SIZE;i++) {
178 pageBitmap[i] = 0; //mark as decommitted
179 }
180}
181//******************************************************************************
182//******************************************************************************
183DWORD HeapGetSharedMemBase()
184{
185 dprintf(("KERNEL32: HeapGetSharedMemBase()\n"));
186 return (DWORD) pSharedMem;
187}
188//******************************************************************************
189//******************************************************************************
Note: See TracBrowser for help on using the repository browser.