Category : C++ Source Code
Archive   : VMEMPP.ZIP
Filename : MEMORY.H

 
Output of file : MEMORY.H contained in archive : VMEMPP.ZIP
#if !defined( __MEMORY_H )
#define __MEMORY_H

#if !defined( __MEM_H )
#include
#endif

#define EMSPAGESPERFRAME 4
#define EMSMAXBLKSIZE 0xFFFF
#define EMSPAGESIZE 16384

// Memory types: conventional, EMS, disk

enum { MemConventional, MemEMS, MemDisk };

// Allocation schemes, in the form of AaaBbbCcc, where Aaa is the
// first type to try and use, Bbb is the second type, Ccc is the last.

enum { ConvEmsDisk, ConvDiskEms, EmsConvDisk, EmsDiskConv, DiskConvEms,
DiskEmsConv };

// Class MemoryObject
// Base class
// All memory types are derived from MemoryObject.

class MemoryObject
{
public:

MemoryObject();

// The following methods are pure abstract and must be
// overridden in the derived classes.

virtual int type() = 0;
// Post conditions: returns the enumerated memory type.

virtual int allocate( size_t sz ) = 0;
// Post conditions: returns 0 on failure, <>0 on pass.
// Note: should fail if object has already allocated memory.

virtual void free() = 0;
// Post conditions: if allocate(sz<>0) has been called and the
// block is not locked, should deallocate.

virtual void far *lock() = 0;
// Post conditions: should return 0 if no memory allocated. If
// already locked, should return the same pointer. If it can
// lock (or already is), should increment lockflag. On fail should
// return 0, on pass should return a far pointer into conventional
// memory space.

virtual void unlock() = 0;
// Post conditions: Should do nothing if lockflag = 0; otherwise
// should decrement lockflag. If the result of decrementing lockflag
// is 0, should unlock the memory block.

virtual long memAvail() = 0;
// Post conditions: should return the total amount of type() memory
// available for allocation: value should take into account
// fragmentation.

virtual long maxAvail() = 0;
// Post conditions: should return the largest contiguous block of type()
// available for allocation.

size_t memSize()
// Post conditions: returns the size of the allocated block in bytes.
{ return memsize; }

protected:

size_t memsize; // bytes currently allocated.
unsigned lockflag; // incremented flag for locking.
};

inline MemoryObject::MemoryObject()
{
memsize = 0;
lockflag = 0;
}

// Class ConvMemory
// Derived from: MemoryObject
// Desc:
// ConvMemory uses conventional memory as the source for allocation.
// Uses the global operator new to allocate, and delete to free. Use
// extern long ConvMemPoolSize = xxxx; to ensure that a call to allocate
// that would result in less than xxxx bytes being the max available
// conventional block available will fail. This is particularly handy if
// DiskMemory is to be used, since DiskMemory requires a block of
// ConvMemory or EmsMemory in order to lock() its block into accessible
// memory.

class ConvMemory : public MemoryObject
{
public:

ConvMemory();
ConvMemory( size_t sz );
~ConvMemory();

virtual int type() { return MemConventional; }
virtual int allocate( size_t sz );
virtual void free();
virtual void far *lock();
virtual void unlock();
virtual long memAvail();
virtual long maxAvail();

protected:

void far *vp;
};

// Class EmsMemory
// Derived from: MemoryObject
// Desc:
// EmsMemory uses EMS (LIM 3.2+) memory as the source for allocation.
// All calls to allocate() will fail if an EMS driver is not installed.
// Note: upon the first ctor for an EmsMemory object (with EMS installed),
// EmsMemory allocates ALL of EMS memory available by default. If you
// want only xxx pages (16K per page) used, use
// extern unsigned MaxEmsPages = xxx;
// If xxx = 0 (default) then all available pages are used.
// EmsMemory uses a linked-list of EmsMemory instances to
// implement a first-available allocation scheme.

class EmsMemory : public MemoryObject
{
public:

EmsMemory();
EmsMemory( size_t sz );
~EmsMemory();

virtual int type() { return MemEMS; }
virtual int allocate( size_t sz );
virtual void free();
virtual void far *lock();
virtual void unlock();

virtual long memAvail();
virtual long maxAvail();

friend void ClearEms();
// Note: ClearEms() is called when your program exits to return all
// used pages back to the EMS pool.

protected:

static unsigned handle; // EMS handle.
static int isInitialized; // flag
static EmsMemory *head; // head of linked list.
static long lastAddr; // last byte+1 in buffer.
static char framePageInUse[EMSPAGESPERFRAME];
// Note: framePageInUse constitutes 4 flags that indicate if any object
// has been locked into one of the 4 frame pages. This is to ensure
// that subsequent lock() calls won't toss a locked item by using
// its EMS page in the frame buffer.

static unsigned frameSeg; // segment of the frame buffer.

EmsMemory *next; // next item in the linked list.
long addr; // linear offset of this block of memory.
char framePage; // the first frame page (0..3) that holds
// this objects memory in the frame.

void init(); // initialize EMS.
static int fitsInto( long addr, long next, size_t sz );
// ensures sz bytes can fit between addr and next and that the
// required pages will fit in the frame buffer.
static long nextPageAddr( long addr );
// linear offset of the next page from addr.
static unsigned pageOf( long addr );
// the page number of the linear offset addr.
static long pageAddr( unsigned page );
// the linear addres that maps to the start of page.
static char availableFramePage( char count );
// returns the first available frame page that will fit count
// pages contiguously in the frame buffer.
static void mapPagesToFrame( char st, unsigned page, char count );
// calls the EMS driver to map pages into the frame buffer.
static void far *framePageAddr( char page );
// returns the conventional memory address of a page in the
// frame buffer.
static void unmapFramePages( char st, char count );
// calls the EMS driver to swap 'locked' frame buffer pages
// back into EMS memory.
};

// Class DiskMemory
// Derived from: MemoryObject
// Desc:
// DiskMemory uses a disk file for memory allocation. Use:
// extern char DefaultDiskMemDir[MAXPATH]; to set which directory is used
// to open the temp file (default is "."). Since DiskMemory requires
// a conventional memory buffer when locked, ConvMemory and EmsMemory are
// used to allocate this buffer. Use:
// extern int DiskFrameOrder = x;
// to set the order in which this allocation is performed; for x=0 (default)
// first ConvMemory is tried, then EmsMemory; for x=1, first EmsMemory is
// tried, then ConvMemory. DiskMemory has a static member lastAddr, which
// is the size of the temp file. memAvail() returns how much of this file
// is available for allocation (does not count disk space); maxAvail()
// returns the biggest unused block within this file (no disk space). If
// you are NOT writing into files on this disk, you can use the DIR.H
// run-time library functions to get the available disk space, add it to
// mxxAvail() and get a better reading of what's actually available; this
// is not done by DiskMemory since you may be writing to files and this
// would give an erroneous reading. Note that lastAddr will grow (unlike
// in ConvMemory and EmsMemory, where its fixed) as blocks are allocated
// at the end of the file.
// Like EmsMemory, DiskMemory comprises the elements of a linked-list
// for first-available method of allocation.

class DiskMemory : public MemoryObject
{
public:

DiskMemory();
DiskMemory( size_t sz );
~DiskMemory();

virtual int type() { return MemDisk; }
virtual int allocate( size_t sz );
virtual void free();
virtual void far *lock();
virtual void unlock();
virtual long memAvail();
virtual long maxAvail();

friend void ClearDisk();

protected:

static int handle; // file handle of the temp file.
static int isInitialized; // flag.
static DiskMemory *head; // head of linked list.
static long lastAddr; // temp file size.

MemoryObject *frame; // locked buffer to hold block when locked.
void far *frameBuf; // pointer to the buffer.
DiskMemory *next; // next item in linked list.
long addr; // linear offset in file of this block.

void init(); // initialization.
static int fitsInto( long addr, long next, size_t sz );
// checks if sz bytes can fit between addr and next.
};

// Class VMemManager
// Desc:
// VMemManager represents a primitive virtual memory manager. All
// methods are static, so you can instantiate as many of these objects as
// you like, though none are needed. Member allocScheme should be set
// to one of the enumerated allocation schemes at the top of this file;
// by default it uses ConvEmsDisk (ie fastest to slowest). allocate() will
// return a pointer to a MemoryObject whose type() is the first available
// that can allocate sz bytes.

class VMemManager
{
public:

static MemoryObject *allocate( size_t sz );
static int allocScheme;
};

#endif // __MEMORY_H


  3 Responses to “Category : C++ Source Code
Archive   : VMEMPP.ZIP
Filename : MEMORY.H

  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/