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

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

Rewrote algorithm for 64kb alignment in VirtualAlloc'ed memory; allocation changes for heap (in 64kb chunks) & PE image (align at 64kb)

File size: 5.8 KB
Line 
1/* $Id: heapshared.cpp,v 1.9 2002-07-15 14:28:51 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, _HEAP_REGULAR|_HEAP_SHARED,
56 getmoreShared, releaseShared);
57
58 if(sharedHeap == NULL) {
59 DosFreeMem(pSharedMem);
60 dprintf(("InitializeSharedHeap: _ucreate failed!"));
61 return FALSE;
62 }
63 dprintf(("KERNEL32: First InitializeSharedHeap %x %x", pSharedMem, sharedHeap));
64 for(int i=0;i<INCR_HEAPSIZE/PAGE_SIZE;i++) {
65 pageBitmap[i] = 1; //mark as committed
66 }
67 }
68 else {
69 if(DosGetSharedMem(pSharedMem, PAG_READ|PAG_WRITE) != 0) {
70 dprintf(("InitializeSharedHeap: DosGetSharedMem failed!"));
71 return FALSE;
72 }
73 dprintf(("KERNEL32: InitializeSharedHeap %x %x refcount %d", pSharedMem, sharedHeap, refCount));
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//******************************************************************************
104ULONG GetPageRangeFree(ULONG pageoffset)
105{
106 dprintf(("KERNEL32: GetPageRangeFree(%08xh)", pageoffset));
107
108 for(int i=pageoffset;i<MAX_HEAPPAGES;i++) {
109 if(pageBitmap[i] == 1) {
110 break;
111 }
112 }
113 return i-pageoffset;
114}
115//******************************************************************************
116//******************************************************************************
117void * _LNK_CONV getmoreShared(Heap_t pHeap, size_t *size, int *clean)
118{
119 APIRET rc;
120 ULONG newsize;
121 PVOID newblock;
122
123 dprintf(("KERNEL32: getmoreShared(%08xh, %08xh, %08xh)\n", pHeap, *size, *clean));
124
125 /* round the size up to a multiple of 4K */
126 // *size = (*size / 4096) * 4096 + 4096;
127 // @@@PH speed improvement
128 *size = (*size + 4096) & 0xFFFFF000;
129 *size = max(*size, INCR_HEAPSIZE);
130
131 for(int i=0;i<MAX_HEAPPAGES;i++)
132 {
133 int nrpagesfree = GetPageRangeFree(i);
134 if(nrpagesfree >= *size/PAGE_SIZE) {
135 newblock = (PVOID)((ULONG)pSharedMem + i*PAGE_SIZE);
136 rc = DosSetMem(newblock, *size, PAG_READ|PAG_WRITE|PAG_COMMIT);
137 if(rc != 0) {
138 dprintf(("getmoreShared: DosSetMem failed with %d", rc));
139 return NULL;
140 }
141 for(int j=0;j < *size/PAGE_SIZE; j++)
142 {
143 pageBitmap[i+j] = 1; //mark as committed
144 }
145
146 *clean = _BLOCK_CLEAN;
147 dprintf(("KERNEL32: getmoreShared %x %d", newblock, *size));
148 return newblock;
149 }
150 if(nrpagesfree)
151 i += nrpagesfree-1;
152 }
153 dprintf(("KERNEL32: getmoreShared NOTHING LEFT (%d)", *size));
154 return NULL;
155}
156//******************************************************************************
157//******************************************************************************
158void _LNK_CONV releaseShared(Heap_t pHeap, void *block, size_t size)
159{
160 ULONG pagenr;
161
162 dprintf(("KERNEL32: releaseShared %x %d", block, size));
163 DosSetMem(block, size, PAG_READ|PAG_WRITE|PAG_DECOMMIT);
164
165 pagenr = (ULONG)block - (ULONG)pSharedMem;
166 pagenr /= PAGE_SIZE;
167 for(int i=pagenr;i<pagenr+size/PAGE_SIZE;i++) {
168 pageBitmap[i] = 0; //mark as decommitted
169 }
170}
171//******************************************************************************
172//******************************************************************************
173DWORD HeapGetSharedMemBase()
174{
175 dprintf(("KERNEL32: HeapGetSharedMemBase()\n"));
176 return (DWORD) pSharedMem;
177}
178//******************************************************************************
179//******************************************************************************
Note: See TracBrowser for help on using the repository browser.