Category : C++ Source Code
Archive   : VMVCPP.ZIP
Filename : VMEMS.C

 
Output of file : VMEMS.C contained in archive : VMVCPP.ZIP
/***
* vmems.c -
*
* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved.
*
*Purpose:
*
* PRIVATE Functions:
*
* VmInitializeEms:
*
* VmTerminateEms:
*
* FVmAllocateEmsPage:
*
* VmMapInEmsPage:
*
*******************************************************************************/

#pragma title("Virtual Memory Manager")
#pragma subtitle("DOS Expanded memory support")


#include
#include
#include
#include
#include
#include
#include

#if VMFREE
#define cVmPageQueuedEmsMost 8
#else /* !VMFREE */
#define cVmPageQueuedEmsMost 1
#endif /* !VMFREE */

extern char _near _fVmDisableEms = FALSE;
static char _near _fVmUseEms;
static HEMS _near hemsVm;
static unsigned _near _cVmPageHems;
static unsigned _near _cVmPageQueuedEms;
static unsigned _near rgiVmPageQueuedEms[cVmPageQueuedEmsMost];

#if VMFREE

static unsigned _near iVmPageEmsNextFree;

#endif /* VMFREE */


#if VMPROFILE

unsigned long _near _cVmSwapInEms;
unsigned long _near _cVmSwapOutEms;

#endif /* VMPROFILE */


#pragma page()

void PRIVATE __VmInitializeEms(void)
{
VmTracePrintf(("VmInitializeEms\n"));

#if VMPROFILE
_cVmSwapInEms = _cVmSwapOutEms = 0;
#endif

if (_fVmDisableEms ||
!__FEmsCheckInstalled() ||
(__ErrEmsAllocatePages(&hemsVm, 1) != errNoError)
)
{
_fVmUseEms = FALSE;
return;
}

_fVmUseEms = TRUE;
_cVmPageHems = 1;
_cVmPageQueuedEms = 1;
rgiVmPageQueuedEms[0] = 0;

#if VMFREE
iVmPageEmsNextFree = 0xffff;
#endif /* VMFREE */
}


#pragma page()

void PRIVATE __VmTerminateEms(void)
{
VmTracePrintf(("VmTerminateEms\n"));

VmProfilePrintf(("VmProfile:\t_cVmSwapInEms = %lu, _cVmSwapOutEms = %lu\n",
_cVmSwapInEms, _cVmSwapOutEms));

if (_fVmUseEms)
{
__ErrEmsDeallocatePages(hemsVm);

_fVmUseEms = FALSE;
}
}


#pragma page()

void LOCAL __VmFillEmsQueue(void)
{
VmTracePrintf(("VmFillEmsQueue\n"));

Assert(_fVmUseEms && (_cVmPageQueuedEms == 0));

#if VMFREE
if (iVmPageEmsNextFree != 0xffff)
{
ERR err;
move_source_dest emsmove;

/* Insert first free page in queue. */

/* CONSIDER: Should more than one page be added to queue. */
/* CONSIDER: I chose not to because a subsequent set of */
/* CONSIDER: calls to VmFreeEmsPage could result in more */
/* CONSIDER: EMS calls than occur by not doing so. */

rgiVmPageQueuedEms[_cVmPageQueuedEms++] = iVmPageEmsNextFree;

emsmove.cb = sizeof(iVmPageEmsNextFree);
emsmove.fEmsSource = 1;
emsmove.hemsSource = hemsVm;
emsmove.ibSource = 0;
emsmove.iPageSource = iVmPageEmsNextFree;
emsmove.fEmsDest = 0;
emsmove.hemsDest = 0;
emsmove.ibDest = (unsigned) (void _near *) &iVmPageEmsNextFree;
emsmove.segDest = (_segment) &iVmPageEmsNextFree;
err = __ErrEmsMoveMemoryRegion(&emsmove);
Assert(err == errNoError);
}

else
#endif /* VMFREE */
{
if (__ErrEmsReallocatePages(hemsVm, _cVmPageHems + 1) != errNoError)
return;

rgiVmPageQueuedEms[_cVmPageQueuedEms++] = _cVmPageHems++;

VmTracePrintf(("Reallocated EMS Handle. cPage = %04X.\n", _cVmPageHems));
}
}


#pragma page()

int PRIVATE __FVmAllocateEmsPage(PPTE ppte, VPVOID vp)
{
PPTE ppteBase;
unsigned iPage;
PTE pte;

if (!_fVmUseEms)
return(FALSE);

Assert(*ppte == 0);

/* Find the base of this 16K range */

ppteBase = ppte - ((vp & 16383UL) / cbVmPage);

/* EMS is only allocated in 16K blocks. For this allocation to */
/* succeed, the 16K block containing this page must not contain */
/* any pages assigned swap storage in XMS or disk. */

for (iPage = 0; iPage < 16384U / cbVmPage; iPage++)
{
Assert(!(ppteBase[iPage] & fEmsPte));

if (ppteBase[iPage] & (fXmsPte | fDiskPte))
return(FALSE);
}

if (_cVmPageQueuedEms == 0) /* No Queued pages available. */
__VmFillEmsQueue();

if (_cVmPageQueuedEms == 0) /* Queue remains empty. No EMS left. */
return(FALSE);

pte = (rgiVmPageQueuedEms[--_cVmPageQueuedEms] * 16384UL) | fEmsPte;

vp &= ~(VPVOID) (cbVmPage - 1UL); /* Virtual address of base of range */

for (iPage = 0; iPage < 16384U / cbVmPage; iPage++)
{
HPGD hpgd;

/* Remember the assigned swap location in the page tables. */

ppteBase[iPage] |= pte;

/* If this page is resident, the swap location must be updated in */
/* the page descriptor as well or else the page won't be swapped */
/* out to the correct location. */

if ((ppteBase[iPage] & fAllocatedPte) &&
((hpgd = __HpgdSearchCache(vp)) != hpgdNil))
PpgdOfHpgd(hpgd)->pte |= pte;

pte += cbVmPage;
vp += cbVmPage;
}

*ppte |= fAllocatedPte | fUnreferencedPte;

VmTracePrintf(("FVmAllocateEmsPage: SwapLocation = %08lX.\n", *ppte & bitSwapPte));

return(TRUE);
}


#pragma page()

#if VMFREE

void PRIVATE __VmFreeEmsPage(PPTE ppte)
{
PPTE ppteBase;
unsigned iPage;

VmTracePrintf(("VmFreeEmsPage: SwapLocation = %08lX.\n", *ppte & bitSwapPte));

Assert(_fVmUseEms && (*ppte & fEmsPte) && !(*ppte & fAllocatedPte));

/* Find the base of this 16K range */

ppteBase = ppte - ((*ppte & bitSwapPte & 16383UL) / cbVmPage);

/* If any page in this page is allocated, don't free the EMS page. */

for (iPage = 0; iPage < 16384U / cbVmPage; iPage++)
{
Assert(ppteBase[iPage] & fEmsPte);

if (ppteBase[iPage] & fAllocatedPte)
return;
}

iPage = (unsigned) ((*ppte & bitSwapPte) / 16384UL);

if (_cVmPageQueuedEms < cVmPageQueuedEmsMost)
rgiVmPageQueuedEms[_cVmPageQueuedEms++] = iPage;

else
{
ERR err;
move_source_dest emsmove;

emsmove.cb = sizeof(iVmPageEmsNextFree);
emsmove.fEmsDest = 1;
emsmove.hemsDest = hemsVm;
emsmove.ibDest = 0;
emsmove.iPageDest = iPage;
emsmove.fEmsSource = 0;
emsmove.hemsSource = 0;
emsmove.ibSource = (unsigned) (void _near *) &iVmPageEmsNextFree;
emsmove.segSource = (_segment) &iVmPageEmsNextFree;
err = __ErrEmsMoveMemoryRegion(&emsmove);
Assert(err == errNoError);

iVmPageEmsNextFree = iPage;
}

for (iPage = 0; iPage < 16384U / cbVmPage; iPage++)
ppteBase[iPage] = 0;
}

#endif /* VMFREE */


#pragma page()

int PRIVATE __FVmSwapInEmsPage(PTE pte, HPGD hpgd)
{
ERR err;
move_source_dest emsmove;

VmTracePrintf(("VmSwapInEmsPage: pPage = %Fp, SwapLocation = %08lX.\n",
PPageOfHpgd(hpgd), pte & bitSwapPte));

#if VMPROFILE
_cVmSwapInEms++;
#endif

Assert(_fVmUseEms && (pte & fEmsPte));

emsmove.cb = cbVmPage;
emsmove.fEmsSource = 1;
emsmove.hemsSource = hemsVm;
emsmove.ibSource = (unsigned) ((pte & bitSwapPte) & 16383UL);
emsmove.iPageSource = (unsigned) ((pte & bitSwapPte) / 16384UL);
emsmove.fEmsDest = 0;
emsmove.hemsDest = 0;
emsmove.ibDest = 0;
emsmove.segDest = PpgdOfHpgd(hpgd)->segPage;
err = __ErrEmsMoveMemoryRegion(&emsmove);

Assert(err == errNoError);
return(err == errNoError);
}


#pragma page()

int PRIVATE __FVmSwapOutEmsPage(PTE pte, HPGD hpgd)
{
ERR err;
move_source_dest emsmove;

VmTracePrintf(("VmSwapOutEmsPage: vp = %08lX, pPage = %Fp, SwapLocation = %08lX.\n",
PpgdOfHpgd(hpgd)->vp, PPageOfHpgd(hpgd), pte & bitSwapPte));

#if VMPROFILE
_cVmSwapOutEms++;
#endif

Assert(_fVmUseEms && (pte & fEmsPte));

emsmove.cb = cbVmPage;
emsmove.fEmsSource = 0;
emsmove.hemsSource = 0;
emsmove.ibSource = 0;
emsmove.segSource = PpgdOfHpgd(hpgd)->segPage;
emsmove.fEmsDest = 1;
emsmove.hemsDest = hemsVm;
emsmove.ibDest = (unsigned) ((pte & bitSwapPte) & 16383U);
emsmove.iPageDest = (unsigned) ((pte & bitSwapPte) / 16384UL);
err = __ErrEmsMoveMemoryRegion(&emsmove);

Assert(err == errNoError);
return(err == errNoError);
}


  3 Responses to “Category : C++ Source Code
Archive   : VMVCPP.ZIP
Filename : VMEMS.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/