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

Last change on this file since 7029 was 5564, checked in by sandervl, 24 years ago

removed wrong segment definition

File size: 5.5 KB
Line 
1/* $Id: heapshared.cpp,v 1.8 2001-04-22 09:00:19 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 <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 rc = DosAllocSharedMem(&pSharedMem, NULL, MAX_HEAPSIZE, PAG_READ|PAG_WRITE|OBJ_GETTABLE);
45 if(rc != 0) {
46 dprintf(("InitializeSharedHeap: DosAllocSharedMem failed with %d", rc));
47 return FALSE;
48 }
49 rc = DosSetMem(pSharedMem, INCR_HEAPSIZE, PAG_READ|PAG_WRITE|PAG_COMMIT);
50 if(rc != 0) {
51 DosFreeMem(pSharedMem);
52 dprintf(("InitializeSharedHeap: DosSetMem failed with %d", rc));
53 return FALSE;
54 }
55 sharedHeap = _ucreate(pSharedMem, INCR_HEAPSIZE, _BLOCK_CLEAN,
56 _HEAP_REGULAR|_HEAP_SHARED,
57 getmoreShared, releaseShared);
58
59 if(sharedHeap == NULL) {
60 DosFreeMem(pSharedMem);
61 dprintf(("InitializeSharedHeap: _ucreate failed!"));
62 return FALSE;
63 }
64 dprintf(("KERNEL32: First InitializeSharedHeap %x %x", pSharedMem, sharedHeap));
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 dprintf(("KERNEL32: InitializeSharedHeap %x %x refcount %d", pSharedMem, sharedHeap, refCount));
75 if(_uopen(sharedHeap) != 0) {
76 dprintf(("InitializeSharedHeap: unable to open shared heap!"));
77 return FALSE;
78 }
79 }
80 refCount++;
81 return TRUE;
82}
83//******************************************************************************
84//******************************************************************************
85void DestroySharedHeap()
86{
87 dprintf(("KERNEL32: DestroySharedHeap %d", refCount));
88 if(--refCount == 0) {
89 if(sharedHeap) {
90 _uclose(sharedHeap);
91 _udestroy(sharedHeap, _FORCE);
92 sharedHeap = NULL;
93 }
94 if(pSharedMem) {
95 DosFreeMem(pSharedMem);
96 pSharedMem = NULL;
97 }
98 }
99 else {
100 _uclose(sharedHeap);
101 }
102}
103//******************************************************************************
104//******************************************************************************
105ULONG GetPageRangeFree(ULONG pageoffset)
106{
107 dprintf(("KERNEL32: GetPageRangeFree(%08xh)\n",
108 pageoffset));
109
110 for(int i=pageoffset;i<MAX_HEAPPAGES;i++) {
111 if(pageBitmap[i] == 1) {
112 break;
113 }
114 }
115 return i-pageoffset;
116}
117//******************************************************************************
118//******************************************************************************
119void * _LNK_CONV getmoreShared(Heap_t pHeap, size_t *size, int *clean)
120{
121 APIRET rc;
122 ULONG newsize;
123 PVOID newblock;
124
125 dprintf(("KERNEL32: getmoreShared(%08xh, %08xh, %08xh)\n",
126 pHeap,
127 *size,
128 *clean));
129
130 /* round the size up to a multiple of 4K */
131 // *size = (*size / 4096) * 4096 + 4096;
132 // @@@PH speed improvement
133 *size = (*size + 4096) & 0xFFFFF000;
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.