193 lines
5.8 KiB
C
193 lines
5.8 KiB
C
|
/************************************************************/
|
|||
|
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
|
|||
|
/************************************************************/
|
|||
|
|
|||
|
#define NOGDICAPMASKS
|
|||
|
#define NOVIRTUALKEYCODES
|
|||
|
#define NOWINMESSAGES
|
|||
|
#define NOWINSTYLES
|
|||
|
#define NOSYSMETRICS
|
|||
|
#define NOMENUS
|
|||
|
#define NOICON
|
|||
|
#define NOKEYSTATE
|
|||
|
#define NOSYSCOMMANDS
|
|||
|
#define NOSHOWWINDOW
|
|||
|
#define NOCTLMGR
|
|||
|
#define NOCLIPBOARD
|
|||
|
#define NOMSG
|
|||
|
#define NOGDI
|
|||
|
#define NOMB
|
|||
|
#define NOSOUND
|
|||
|
#define NOCOMM
|
|||
|
#define NOPEN
|
|||
|
#define NOBRUSH
|
|||
|
#define NOFONT
|
|||
|
#define NOWNDCLASS
|
|||
|
#include <windows.h>
|
|||
|
#include "mw.h"
|
|||
|
|
|||
|
#ifdef OURHEAP
|
|||
|
/*
|
|||
|
heapInit.c - one routine to calculate the proper information for
|
|||
|
heap management.
|
|||
|
*/
|
|||
|
|
|||
|
#include "code.h"
|
|||
|
#include "heapDefs.h"
|
|||
|
#include "heapData.h"
|
|||
|
#include "str.h"
|
|||
|
#ifdef ENABLE
|
|||
|
#include "memDefs.h"
|
|||
|
#endif
|
|||
|
|
|||
|
/* heap specific data */
|
|||
|
HH *phhMac; /* May change if grow heap */
|
|||
|
int cwHeapMac; /* " " " " " " " " */
|
|||
|
int *pHeapFirst; /* change if the finger table rgfgr expands */
|
|||
|
FGR *rgfgr; /* Declared as a pointer, but also used as an array. */
|
|||
|
FGR *pfgrMac; /* Initially equal to &rgfgr[ifgrInit]; */
|
|||
|
FGR *pfgrFree; /* Singly linked with a trailing NULL pointer. */
|
|||
|
HH *phhFree; /* May be NULL along the way. */
|
|||
|
ENV envMem;
|
|||
|
int fMemFailed;
|
|||
|
int cwInitStorage;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FExpandFgrTbl()
|
|||
|
|
|||
|
/* Will expand the finger table. This routines depends upon the fact
|
|||
|
that the CompactHeap routine moves the allocated blocks to the
|
|||
|
low end of memory. The new space from the finger table comes from
|
|||
|
the tail end of the (only) free block left after a compaction.
|
|||
|
The finger is expanded by at most 'cfgrNewMax' and at least 1.
|
|||
|
If there is no room to expand the finger table, then nothing is
|
|||
|
changed. To expand the table, several pointers and integers are
|
|||
|
decreamented to reflect the reallocation of the storage. Then
|
|||
|
we recalculate the memory totals so the user
|
|||
|
will have an acurate display of the percent free and total bytes
|
|||
|
available. The new fingers are linked so that the finger at the
|
|||
|
low end of the table is at the end of the list.
|
|||
|
(To expand the finger table there must be no fingers available.)
|
|||
|
*/
|
|||
|
|
|||
|
{
|
|||
|
FGR *pfgr;
|
|||
|
int cfgrNew = cfgrBlock;
|
|||
|
register HH *phhNew;
|
|||
|
|
|||
|
#ifdef DEBUG
|
|||
|
if (pfgrFree != NULL)
|
|||
|
panicH(34);
|
|||
|
#endif
|
|||
|
|
|||
|
if (!FCwInMem(cfgrNew + cwReqMin + 1))
|
|||
|
{
|
|||
|
/* couldn't get a block's worth - could we get one? */
|
|||
|
cfgrNew = 1;
|
|||
|
if (!FCwInMem(cfgrNew))
|
|||
|
/* no way to help this guy */
|
|||
|
return(FALSE);
|
|||
|
}
|
|||
|
|
|||
|
phhNew = (HH *)pHeapFirst;
|
|||
|
if (phhNew->cw > 0 || !FHhFound(phhNew, cfgrNew))
|
|||
|
{
|
|||
|
/* we tried but failed to find an adequate free
|
|||
|
block at start of heap */
|
|||
|
CompactHeap();
|
|||
|
MoveFreeBlock(pHeapFirst);
|
|||
|
}
|
|||
|
|
|||
|
if (!FPhhDoAssign(phhNew, cfgrNew))
|
|||
|
return(FALSE);
|
|||
|
|
|||
|
/* we have a block which is FIRST in the heap - let's steal it */
|
|||
|
cfgrNew = phhNew->cw; /* in case it was more than we
|
|||
|
asked for */
|
|||
|
pHeapFirst = pHeapFirst + cfgrNew;
|
|||
|
pfgrMac += cfgrNew;
|
|||
|
cwHeapMac -= cfgrNew;
|
|||
|
|
|||
|
/* do some initialization if pfgrFree is not NULL and you
|
|||
|
want the new fingers at the very end of the free finger list */
|
|||
|
for (pfgr = pfgrMac - cfgrNew; pfgr < pfgrMac; pfgr++)
|
|||
|
{
|
|||
|
*pfgr = (FGR)pfgrFree;
|
|||
|
pfgrFree = pfgr;
|
|||
|
}
|
|||
|
|
|||
|
/* do we need this anymore? (cwInitStorage = cwHeapMac - cwHeapFree)
|
|||
|
cbTot = (cwHeapMac - cwInitStorage) * sizeof(int);
|
|||
|
cbTotQuotient = (cbTot>>1)/100;
|
|||
|
*/
|
|||
|
return(TRUE);
|
|||
|
|
|||
|
} /* End of FExpandFgrTbl () */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
CompactHeap()
|
|||
|
/* moves all allocated hunks */
|
|||
|
/* toward beginning of pHeapFirst. Free hunks */
|
|||
|
{
|
|||
|
HH *phh, *phhSrc, *phhDest; /* are combined into one hunk */
|
|||
|
FGR *pfgr;
|
|||
|
int cwActual;
|
|||
|
|
|||
|
#ifdef DEBUG
|
|||
|
StoreCheck();
|
|||
|
#endif
|
|||
|
|
|||
|
/* set up for compaction by placing cw of hunk in rgfgr and an
|
|||
|
index into rgfgr in the hunk */
|
|||
|
for (pfgr = rgfgr; pfgr < pfgrMac; pfgr++)
|
|||
|
{
|
|||
|
if (FPointsHeap(*pfgr))
|
|||
|
/* if rgfgr[ifgr] points to heap... */
|
|||
|
{
|
|||
|
phh = (HH *)(*pfgr + bhh);
|
|||
|
/* find header */
|
|||
|
*pfgr = (FGR)phh->cw;
|
|||
|
/* coerce so it fits, force the shift */
|
|||
|
phh->cw = (int)(((unsigned)pfgr - (unsigned)rgfgr)/2);
|
|||
|
}
|
|||
|
}
|
|||
|
/* now we have cw in rgfgr and ifgr in phh */
|
|||
|
phhSrc = (HH *) pHeapFirst;
|
|||
|
phhDest = phhSrc;
|
|||
|
while (phhSrc < phhMac)
|
|||
|
{
|
|||
|
if (phhSrc->cw < 0)
|
|||
|
/* free hunk, don't recopy */
|
|||
|
phhSrc = (HH *)((int *) phhSrc - phhSrc->cw);
|
|||
|
else
|
|||
|
{
|
|||
|
pfgr = &rgfgr[phhSrc->cw];
|
|||
|
/* find h */
|
|||
|
cwActual = phhSrc->cw = (int) *pfgr;
|
|||
|
/* restore cw */
|
|||
|
*pfgr = ((FGR) phhDest - bhh);
|
|||
|
/* update ha */
|
|||
|
blt((int *)phhSrc, (int *)phhDest, (unsigned)cwActual);
|
|||
|
/* unless ptrs are = */
|
|||
|
phhDest = (HH *) ((int *) phhDest + cwActual);
|
|||
|
phhSrc = (HH *) ((int *) phhSrc + cwActual);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#ifdef DEBUG
|
|||
|
if ((int *)phhDest + cwHeapFree - cwHunkMin >= (int *)phhMac)
|
|||
|
panicH(35);
|
|||
|
#endif
|
|||
|
phhFree = phhDest;
|
|||
|
phhFree->cw = -cwHeapFree;
|
|||
|
phhFree->phhNext = phhFree->phhPrev = phhFree;
|
|||
|
#ifdef DEBUG
|
|||
|
StoreCheck();
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
#endif /* NOT WINHEAP */
|
|||
|
|