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

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

Shared memory mapping changes

File size: 5.4 KB
Line 
1/* $Id: heapshared.cpp,v 1.1 1999-10-24 22:53:24 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 per process (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 }
72 refCount++;
73 return TRUE;
74}
75//******************************************************************************
76//******************************************************************************
77void DestroySharedHeap()
78{
79 dprintf(("KERNEL32: DestroySharedHeap %d", refCount));
80 if(--refCount == 0) {
81 if(sharedHeap) {
82 _uclose(sharedHeap);
83 _udestroy(sharedHeap, _FORCE);
84 sharedHeap = NULL;
85 }
86 if(pSharedMem) {
87 DosFreeMem(pSharedMem);
88 pSharedMem = NULL;
89 }
90 }
91}
92//******************************************************************************
93//******************************************************************************
94void *_smalloc(size_t size)
95{
96 return _umalloc(sharedHeap, size);
97}
98//******************************************************************************
99//******************************************************************************
100ULONG GetPageRangeFree(ULONG pageoffset)
101{
102 dprintf(("KERNEL32: GetPageRangeFree(%08xh)\n",
103 pageoffset));
104
105 for(int i=pageoffset;i<MAX_HEAPPAGES;i++) {
106 if(pageBitmap[i] == 1) {
107 break;
108 }
109 }
110 return i-pageoffset;
111}
112//******************************************************************************
113//******************************************************************************
114void * _LNK_CONV getmoreShared(Heap_t pHeap, size_t *size, int *clean)
115{
116 APIRET rc;
117 ULONG newsize;
118 PVOID newblock;
119
120 dprintf(("KERNEL32: getmoreShared(%08xh, %08xh, %08xh)\n",
121 pHeap,
122 *size,
123 *clean));
124
125 /* round the size up to a multiple of 4K */
126 *size = (*size / 4096) * 4096 + 4096;
127 *size = max(*size, INCR_HEAPSIZE);
128
129 for(int i=0;i<MAX_HEAPPAGES;i++)
130 {
131 int nrpagesfree = GetPageRangeFree(i);
132 if(nrpagesfree >= *size/PAGE_SIZE) {
133 newblock = (PVOID)((ULONG)pSharedMem + i*PAGE_SIZE);
134 rc = DosSetMem(newblock, *size, PAG_READ|PAG_WRITE|PAG_COMMIT);
135 if(rc != 0) {
136 dprintf(("getmoreShared: DosSetMem failed with %d", rc));
137 return NULL;
138 }
139 for(int j=0;j < *size/PAGE_SIZE; j++)
140 {
141 pageBitmap[i+j] = 1; //mark as committed
142 }
143
144 *clean = _BLOCK_CLEAN;
145 dprintf(("KERNEL32: getmoreShared %x %d", newblock, *size));
146 return newblock;
147 }
148 if(nrpagesfree)
149 i += nrpagesfree-1;
150 }
151 dprintf(("KERNEL32: getmoreShared NOTHING LEFT (%d)", *size));
152 return NULL;
153}
154//******************************************************************************
155//******************************************************************************
156void _LNK_CONV releaseShared(Heap_t pHeap, void *block, size_t size)
157{
158 ULONG pagenr;
159
160 dprintf(("KERNEL32: releaseShared %x %d", block, size));
161 DosSetMem(block, size, PAG_READ|PAG_WRITE|PAG_DECOMMIT);
162
163 pagenr = (ULONG)block - (ULONG)pSharedMem;
164 pagenr /= PAGE_SIZE;
165 for(int i=pagenr;i<pagenr+size/PAGE_SIZE;i++) {
166 pageBitmap[i] = 0; //mark as decommitted
167 }
168}
169//******************************************************************************
170//******************************************************************************
171DWORD HeapGetSharedMemBase()
172{
173 dprintf(("KERNEL32: HeapGetSharedMemBase()\n"));
174 return (DWORD) pSharedMem;
175}
176//******************************************************************************
177//******************************************************************************
Note: See TracBrowser for help on using the repository browser.