/* * memmgr.h * * Copyright (c) 1993 - 1995 by DataBeam Corporation, Lexington, KY * * Abstract: * This is the interface file for the MemoryManager class. This class * is used to efficiently manage the passing of data through a system. * There are two primary techniques it uses to accomplish the goal of * efficiency: * * 1. Use of locally managed "blocked" memory. When this class is * instantiated, it allocates a large block of memory which it then * chops up into various size blocks. These blocks are then used * to hold data, rather than having to do system calls every time * some memory is needed. * * 2. Use of a "copy on lock" algorithm. When memory is first * allocated, the source data is NOT yet copied to it. Copy * operations will implicitly use the reference rather than copying * the data. If the data needs to be retained longer than the * expected life-span of the reference, then a Lock command can be * sent to the block to cause it to be copied. * * When an object needs to allocate memory to hold some data, it calls * an allocate function within an object of this class. Assuming that * the request can be satisfied, a pointer to a Memory object is returned. * This Memory object remembers two addresses: the address of the reference * buffer (where the source data is); and the address of the copy buffer * (which is the buffer allocated to hold the data). As mentioned above, * the data is NOT copied to the copy buffer as part of the allocation * process. The data is not copied until the Memory object is locked * for the first time. * * Objects of this class keep a list of available buffers. There is one * list for each size block that is available. One of the constructor * parameters can be used to control how much data is allocated up front, * and what size blocks it is chopped up into. This makes this class very * flexible in how it can be used. * * Caveats: * None. * * Author: * James P. Galvin, Jr. */ #ifndef _MEMORY_MANAGER2_H_ #define _MEMORY_MANAGER2_H_ /* * These are the errors that can be returned from some of the memory manager * member functions. */ typedef enum { MEMORY_MANAGER_NO_ERROR, MEMORY_MANAGER_ALLOCATION_FAILURE, MEMORY_MANAGER_INVALID_PARAMETER } MemoryManagerError; typedef MemoryManagerError * PMemoryManagerError; /* * An array of this structure is passed into the constructor to define the * number and size of blocks to be created by this object. */ typedef struct { ULong block_size; ULong block_count; } MemoryTemplate; typedef MemoryTemplate * PMemoryTemplate; /* * This structure is used to maintain general information about the shared * memory region that has to be shared between all users of it. */ typedef struct { ULong free_stack_offset; ULong free_stack_count; ULong block_information_offset; ULong total_block_count; ULong current_block_count; } MemoryInformation; typedef MemoryInformation * PMemoryInformation; /* * This structure is used to keep information about each memory block that is * being managed by an instance of this class. */ typedef struct { ULong block_offset; ULong length; ULong free_stack_offset; ULong lock_count; ULong flags; } BlockInformation; typedef BlockInformation * PBlockInformation; /* * These are the masks for manipulating the flags of a BlockInformation structure */ #define FREE_FLAG 0x1 #define COMMIT_FLAG 0x2 /* * The following are definitions for macros used to handle space and space * requirements in relation to page boundaries in the system. */ #define EXPAND_TO_PAGE_BOUNDARY(p) (((p) + dwSystemPageSize - 1) & (~ (dwSystemPageSize - 1))) /* * The following number is used when the caller asks for the number of buffers remaining * within a Memory Manager where allocations are not restricted. The intention is * that this number is very large and enough for the caller to think that all its * allocation requests will succeed. */ #define LARGE_BUFFER_COUNT 0x1000 /* * These typedefs define a container that is used to hold block information * structure pointers. This is used to hold information about blocks that * are externally allocated, but are managed by this class. */ typedef DictionaryClass BlockInformationList; /* * This is the class definition for the MemoryManager class. */ class MemoryManager { public: MemoryManager (); MemoryManager ( PMemoryTemplate memory_template, ULong memory_count, PMemoryManagerError memory_manager_error, ULong ulMaxExternalBlocks, BOOL bAllocsRestricted = TRUE); virtual ~MemoryManager (); virtual PMemory AllocateMemory ( PUChar reference_ptr, ULong length, MemoryLockMode memory_lock_mode = MEMORY_LOCK_NORMAL); virtual Void FreeMemory ( PMemory memory); virtual PMemory CreateMemory ( BlockNumber block_number, MemoryLockMode memory_lock_mode = MEMORY_LOCK_NORMAL); virtual Void LockMemory ( PMemory memory); virtual Void UnlockMemory ( PMemory memory); ULong GetBufferCount () { return((bAllocs_Restricted) ? Memory_Information->current_block_count : LARGE_BUFFER_COUNT); }; virtual ULong GetBufferCount ( ULong length); private: Void ReleaseMemory ( PMemory memory); protected: ULong CalculateMemoryBufferSize ( PMemoryTemplate memory_template, ULong memory_count, ULong * pulCommittedBytes); Void AllocateMemoryBuffer ( ULong memory_buffer_size); Void InitializeMemoryBuffer ( PMemoryTemplate memory_template, ULong memory_count); static DWORD dwSystemPageSize; HPUChar Memory_Buffer; PMemoryInformation Memory_Information; PFreeStack Free_Stack; ULong Free_Stack_Count; HPUChar Block_Information; BlockInformationList *pExternal_Block_Information; ULong Max_External_Blocks; BOOL fIsSharedMemory; BOOL bAllocs_Restricted; }; typedef MemoryManager * PMemoryManager; /* * MemoryManager ( * PMemoryTemplate memory_template, * USHORT memory_count, * PMemoryManagerError memory_manager_error) * * Functional Description: * This is the constructor for the MemoryManager class. It uses the * information in the specified memory templates to allocate a block * of memory and chop it up into fixed size pieces. It then puts * these pieces into a set of free block lists, so that it can allocate * memory on an as needed basis. * * Formal Parameters: * memory_template * This is the base address of an array of memory template structures. * Each element of this structure specifies how many blocks of a * specified block size should be allocated. The constructor scans * the array, totaling the required memory, and then makes one memory * allocation call. It then chops the memory as specified by the * memory templates. It is VERY important the memory templates be * specified in ascending order of block sizes. In other words, * smaller blocks should be specified first. * memory_count * This simply indicates how mamy memory templates there are in the * list. * memory_manager_error * This is the return value from the constructor. If anything besides * MEMORY_MANAGER_NO_ERROR is returned, the object was not able to * initialize itself properly, and should be destroyed immediately * without being used. * * Return Value: * None. * * Side Effects: * None. * * Caveats: * None. */ /* * ~MemoryManager () * * Functional Description: * This is the destructor for the MemoryManager class. It frees up all * resources being used by the Memory Manager object, including the * memory block allocated to hold all user data. * * Formal Parameters: * None. * * Return Value: * None. * * Side Effects: * None. * * Caveats: * None. */ /* * PMemory AllocateMemory ( * PUChar address, * ULong length) * * Functional Description: * This function is used to allocate a piece of memory from the Memory * Manager object. Note that the return value is not a pointer to the * memory, but rather, a pointer to a Memory object. The memory object * contains a buffer that is large enough to handle the reference data. * * Note that the reference data is not automatically copied into the * copy buffer of the Memory object. This copy operation does not occur * until the first time the Memory object is locked (through a Memory * Manager call, as defined below). * * * Formal Parameters: * address * This is the address of the reference data (or the source data). * length * This is the length of the reference data. * * Return Value: * A pointer to a Memory object if the request is successful. * NULL otherwise. * * Side Effects: * None. * * Caveats: * None. */ /* * Void FreeMemory ( * PMemory memory) * * Functional Description: * This function is used to free a previously allocated Memory object. * Note that if the lock count of the Memory object is not 0 (zero), the * object will not actually be freed yet. This call merely enables the * object to be freed (when the lock count does hit 0). * * In summary, for a Memory object to actually be freed, two conditions * must exist simultaneously: the Memory object must have been freed * with a call to this function; and the lock count must hit zero. * * Formal Parameters: * memory * This is a pointer to the Memory object being freed. * * Return Value: * None. * * Side Effects: * None. * * Caveats: * None. */ /* * Void LockMemory ( * PMemory memory) * * Functional Description: * This function is sued to lock an existing Memory object. A locked * Memory object will not be freed until the lock count hits zero. * * When the lock count transitions from 0 to 1, the reference data is * copied into the internal copy buffer. * * Formal Parameters: * memory * This is a pointer to the Memory object being locked. * * Return Value: * None. * * Side Effects: * None. * * Caveats: * None. */ /* * Void UnlockMemory ( * PMemory memory) * * Functional Description: * This function is used to unlock a Memory object that was previously * locked. Each time an object is unlocked, the lock count is decremented. * When the lock count hits zero, the memory will be freed if-and-only-if * the FreeMemory call has also been made. In essence, for a Memory * object to be freed, a call to FreeMemory must have been made, AND the * lock count must be zero. * * Formal Parameters: * memory * This is a pointer to the Memory object being unlocked. * * Return Value: * None. * * Side Effects: * None. * * Caveats: * None. */ /* * ULong GetBufferCount () * * Functional Description: * This function is used to determine the total number of available * buffers that remain in the pool. This should be used to determine * general resource levels only. It cannot be used to determine whether * or not there is a buffer of a particular size. * * Formal Parameters: * None. * * Return Value: * The total number of buffers available (regardless of size). * * Side Effects: * None. * * Caveats: * None. */ /* * ULong GetBufferCount ( * ULong buffer_size) * * Functional Description: * This function is used to determine the number of X size buffers * that remain in the pool. * * Formal Parameters: * buffer_size * The buffer size that we want to count. * * Return Value: * The number of 'buffer_size' buffers available. * * Side Effects: * None. * * Caveats: * None. */ #endif