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

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

misc changes

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