home *** CD-ROM | disk | FTP | other *** search
-
-
-
- Sweep Memory Management Library
-
- Copyright (c) 1990-1991 Eric Tauck
- All Rights Reserved
-
- Eric Tauck
- 1304 Deerpass Road
- Marengo, IL 60152
- U.S.A
-
- Compuserve: 72457,1557
- Internet: 72457.1557@compuserve.com
-
- The Sweep Library is a library of routines for managing memory
- and maintaining a heap. The advantage of the Sweep Library over
- the heap routines built into Turbo Pascal or Turbo C is that the
- Sweep Library never suffers from memory fragmentation. The Sweep
- Library is ideal for applications that repeatedly allocate,
- deallocate, and resize blocks of memory.
-
- The Sweep Library is available for Turbo C and Turbo Pascal. The
- Turbo C version should work with all versions of Turbo C and all
- memory models except tiny. The Turbo C version may also work
- with other compilers that support standard LIB files and Pascal
- calling conventions. The Turbo Pascal version SWEEP5.TPU was
- compiled with Turbo Pascal version 5.5 and should work with Turbo
- Pascal versions 5.0 and 5.5, SWEEP6.TPU was compiled with Turbo
- Pascal version 6. You should rename the unit that matches your
- version of Turbo Pascal to SWEEP.TPU.
-
- This library may be freely used and distributed. The most recent
- version of the Sweep Library, including the Turbo Assembler
- source code, may be acquired on 5.25" or 3.5" disk by sending $20
- to the address above. The source code is for personal use only
- and may not be distributed. Refer to the end of this document
- for a version history of the Sweep Library.
-
- DISCLAIMER OF WARRANTY
-
- THIS SOFTWARE AND MANUAL ARE DISTRIBUTED "AS IS" AND WITHOUT
- WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR ANY OTHER
- WARRANTIES WHETHER EXPRESSED OR IMPLIED. BECAUSE OF THE VARIOUS
- HARDWARE AND SOFTWARE ENVIRONMENTS INTO WHICH THIS PROGRAM MAY BE
- PUT, NO WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE IS OFFERED.
-
- GOOD DATA PROCESSING PROCEDURE DICTATES THAT ANY PROGRAM BE
- THOROUGHLY TESTED WITH NON-CRITICAL DATA BEFORE RELYING ON IT.
- THE USER MUST ASSUME THE ENTIRE RISK OF USING THE PROGRAM. ANY
- LIABILITY OF THE SELLER WILL BE LIMITED EXCLUSIVELY TO PRODUCT
- REPLACEMENT OR REFUND OF PURCHASE PRICE.
-
-
-
- Sweep Library Description
- -------------------------
-
- The necessary files for Turbo C are:
-
- SWEEP.LIB
- SWEEP.H
-
- The Sweep Library routines are included in a Turbo C program by
- using the #include statement and linking the library file with
- your compiled program:
-
- #include "sweep.h"
-
- and compile as:
-
- tcc myprog sweep.lib
-
- The only file necessary for Turbo Pascal is:
-
- SWEEP.TPU
-
- The Sweep Library routines are included in a Turbo Pascal program
- by using the USES statement:
-
- USES Sweep;
-
- A heap is created with the HeapInit or HeapInitBlk routines.
- These routines require the address and size of a memory block in
- which to create the heap. The farcoreleft and farmalloc in Turbo
- C provide ideal functions for allocating a block of memory for
- the heap:
-
- /* Turbo C */
-
- #include "sweep.h"
-
- void far *base; /* 'far' only for small/medium mdls */
- unsigned long size;
- size = farcoreleft(); /* bytes available */
- base = farmalloc (size); /* allocate memory */
- HeapInit (base, size); /* create heap */
-
- Though you could use the MaxAvail and GetMem routines in Turbo
- Pascal, you would be limited to a heap of 64K (because GetMem
- will not allocate blocks larger than 64K). This limitation can
- be overcome by using three special Turbo Pascal routines provided
- in the Sweep unit: DosAvail, DosAlloc, and DosFree. These func-
- tions allocate memory directly from the operating system rather
- than the Turbo Pascal heap manager and are not restricted to 64K.
- Since the Turbo Pascal heap manager usually takes all available
- memory, you must use the $M directive to make some memory avail-
- able:
-
-
-
- { Turbo Pascal }
-
- {$M 16384,0,0} { tell TP not to use any extra mem. }
- USES Sweep; { remember: rename SWEEP5.TPU or SWEEP6.TPU }
-
- VAR
- base: Pointer;
- size: LongInt;
- BEGIN
- size := DosAvail; { bytes available }
- base := DosAlloc (size); { allocate memory }
- HeapInit (base, size); { create heap }
-
- Once the heap has been created, you can allocate memory with
- HeapAlloc and release memory with HeapFree. HeapAlloc does not
- return an address to the allocated memory, but rather a 16-bit
- handle. This handle type is called HeapHandle and is used by all
- the heap management routines. Memory blocks are accessed by
- retrieving their address with HeapAddr and assigning this address
- to a pointer:
-
- /* Turbo C */
- /* create an array and zero all elements */
- /* the fars are only needed for small or medium models */
-
- typedef int ArrayType [1000];
-
- HeapHandle MyArrayPtr;
- ArrayType far *MyArray;
- int i;
-
- MyArrayPtr = HeapAlloc (sizeof (ArrayType));
- MyArray = (ArrayType far *) HeapAddr(MyArrayPtr);
- for (i = 0; i < 1000; i++) (*MyArray)[i] = 0;
-
- { Turbo Pascal }
- { create an array and zero all elements }
-
- TYPE
- ArrayType = ARRAY [1..1000] OF Integer;
- VAR
- MyArrayPtr: HeapHandle;
- MyArray: ^ArrayType;
- i: Integer;
- BEGIN
- MyArrayPtr := HeapAlloc (SizeOf (ArrayType));
- MyArray := HeapAddr (MyArrayPtr);
-
- FOR i := 1 TO 1000 DO MyArray^[i] := 0;
-
- You can use HeapResult or the value of the handle returned by
- HeapAlloc and HeapResize to check for errors. The error handle
- in C is called SWEEP_NULL and in Pascal it's called SWEEP_NIL.
- The value of SWEEP_NULL and SWEEP_NIL is zero, so in C you can
-
-
-
- use the value of the handle as a conditional expression:
-
- /* Turbo C */
-
- HeapHandle h;
-
- h = HeapAlloc (10); /* allocate 10 bytes */
- if (!h) /* if not allocated */
- printf ("Allocation Error"); /* print error message */
-
- When a memory block is allocated or resized, the address of other
- blocks may change. This is a result of maintaining an unfrag-
- mented heap. The address of a block returned by HeapAddr is only
- valid until the next time the heap is manipulated.
-
- A limitation of the Sweep Library heap routines is that there is
- fixed number of blocks that can be allocated. HeapInit sets the
- maximum number of blocks to about 1/64 of the available memory
- space. The maximum number of blocks can be explicitly defined
- with HeapInitBlk.
-
- The size of the heap can be changed with HeapShrink, HeapExpand,
- and HeapReloc. HeapShrink shrinks the heap by using less space
- at the end of the heap. HeapExpand enlarges the heap by using
- more space at the end of the heap. HeapReloc changes the base
- address of an existing heap. The following example creates a
- 10000 byte heap and then increases its size by 100 bytes:
-
- /* Turbo C */
-
- void far *base;
- unsigned long size;
- size = 10000;
- base = farmalloc (size);
- HeapInit (base, size); /* create 10000 byte heap */
-
- base = farrealloc (base,size+100); /* increase by 100 bytes */
- HeapReloc (base); /* relocate heap */
- HeapExpand (100); /* expand heap */
-
- The HeapReloc is necessary in the example above because the C
- function farrealloc may change address of the memory block being
- reallocated.
-
- You can use the Sweep Library pointer manipulation routines to
- access data structures greater than 64K in Turbo Pascal. If you
- calculate the 32 bit offset of an element within a large data
- structure, you can add the offset to the base address with the
- PointerAdd function, for instance:
-
- { Turbo Pascal }
- { create array of 50000 integers and zero all elements }
-
- CONST
- MyArrayDim = 50000;
-
-
-
- MyArrayElem = SizeOf (Integer);
- VAR
- MyArrayPtr: HeapHandle;
- IntPtr: ^Integer;
- i: Word;
- BEGIN
- MyArrayPtr := HeapAlloc (MyArrayDim * MyArrayElem);
-
- FOR i := 1 TO 1000 DO
- BEGIN
- IntPtr := PointerAdd (HeapAddr (MyArrayPtr),
- LongInt(i - 1) * LongInt (MyArrayElem));
- IntPtr^ := 0;
- END;
-
- You can use the same technique to access large data structures in
- Turbo C.
-
-
-
- Sweep Routine Summary
- ---------------------
-
- PointerNormal normalize a pointer
- PointerDenormal denormalize a pointer
- PointerAdd add an offset to a pointer
- PointerSub subtract an offset from a pointer
-
- PointerValue convert a pointer to a linear value
- PointerDiff calculate the difference between two pointers
-
- CopyBlock copy a memory block
- CopyForward forward copy a memory block
- CopyBackward reverse copy a memory block
-
- HeapInit initialize a heap
- HeapInitBlk initialize a heap with a block count
-
- HeapCurrent return the current heap address
- HeapSelect switch to a new heap
- HeapMemory return the bytes available
- HeapBlocks return the blocks available
-
- HeapShrink reduce the size of a heap
- HeapExpand increase the size of a heap
- HeapReloc relocate the heap
-
- HeapAlloc allocate a memory block
- HeapResize resize a memory block
- HeapFree free a memory block
- HeapSize return the size of a memory block
- HeapAddr return the address of a memory block
-
- HeapResult return the error code of the last operation
-
- DosAvail return available system memory (Turbo Pascal)
- DosAlloc allocate system memory (Turbo Pascal)
- DosFree free system memory (Turbo Pascal)
-
-
-
- Sweep Routine Descriptions
- --------------------------
-
- Though all the pointer values accepted and returned by the Turbo
- C functions are listed as type 'far', all of the routines except
- PointerDenormal (which always returns a far pointer) will also
- work with huge pointers. A 'far' modifier for pointer variables
- is only necessary when using the small or medium memory models.
- A 'huge' or 'near' modifier is never necessary.
-
- Many of the Turbo C routines return a value when the Turbo Pascal
- equivalents don't. Ignore any return value descriptions for
- Turbo Pascal PROCEDURE types.
-
- CopyBackward
-
- - void far* CopyBackward (void far *d, void far *s,
- unsigned long c)
-
- - PROCEDURE CopyBackward (d, s: Pointer; c: LongInt)
-
- Copy a contiguous block of memory. The block may be greater
- than 64K bytes. The copy operation is started from the end of
- the block, so an overlapping copy will only work if the desti-
- nation is at a higher address than the source. The destination
- address is returned. If the source and destination do not
- overlap, this function has the same effect as CopyForward.
-
- CopyBlock
-
- - void far* CopyBlock (void far *d, void far *s,
- unsigned long c)
-
- - PROCEDURE CopyBlock (d, s: Pointer; c: LongInt)
-
- Copy a contiguous block of memory. The block may be greater
- than 64K bytes. The destination address is returned. This
- function works with all overlapping blocks (unlike CopyBackward
- or CopyForward).
-
- CopyForward
-
- - void far * CopyForward (void far *d, void far *s,
- unsigned long c)
-
- - PROCEDURE CopyForward (d, s: Pointer; c: LongInt)
-
- Copy a contiguous block of memory. The block may be greater
- than 64K bytes. The copy operation is started from the begin-
- ning of the block, so an overlapping copy will only work if the
- destination is at a lower address than the source. The desti-
- nation address is returned. If the source and destination do
- not overlap, this function has the same effect as CopyBackward.
-
-
-
- DosAlloc
-
- - FUNCTION DosAlloc (s: LongInt): Pointer;
-
- Allocate system memory. Memory must be made available using
- the $M directive. For instance {$M 16000,4000,4000} allocates
- 16000 bytes for the stack and 4000 bytes for the Turbo Pascal
- heap. All remaining system memory may be allocated by DosAl-
- loc. This function is only available in Turbo Pascal.
-
- DosAvail
-
- - FUNCTION DosAvail: LongInt;
-
- Return available system memory. Use this function find the
- largest block available for DosAlloc. This function is only
- available in Turbo Pascal.
-
- DosFree
-
- - PROCEDURE DosFree (p: Pointer);
-
- Free allocated system memory. Use this function to release
- memory allocated with DosAlloc. This function is only avail-
- able in Turbo Pascal.
-
- PointerAdd
-
- - void far * PointerAdd (void far *p, unsigned long o)
-
- - FUNCTION PointerAdd (p: Pointer; o: LongInt): Pointer;
-
- Add an offset to a far pointer. The resulting address is
- normalized.
-
- PointerDenormal
-
- - void far * PointerDenormal (void far *p)
-
- - FUNCTION PointerDenormal (p: Pointer): Pointer;
-
- Denormalize a far pointer. As much of the segment of an ad-
- dress as possible is transferred to the offset. This function
- does the opposite of PointerNormal. The result is always a far
- pointer, even when using the huge memory model.
-
- PointerDiff
-
- - unsigned long PointerDiff (void far *p1, void far *p2)
-
- - FUNCTION PointerDiff (p1, p2: Pointer): LongInt;
-
- Calculate the difference between two far pointers. The result
- is a standard 32 bit signed value (not a pointer).
-
-
-
- PointerNormal
-
- - void far * PointerNormal (void far *p)
-
- - FUNCTION PointerNormal (p: Pointer): Pointer;
-
- Normalize a far pointer. As much of the offset of an address
- as possible is transferred to the segment. This function does
- the opposite of PointerDenormal.
-
- PointerSub
-
- - void far * PointerSub (void far *p, unsigned long o)
-
- - FUNCTION PointerSub (p: Pointer; o: LongInt): Pointer;
-
- Subtract an offset from a far pointer. The resulting address
- is normalized.
-
- PointerValue
-
- - unsigned long PointerValue (void far *p)
-
- - FUNCTION PointerValue (p: Pointer): LongInt;
-
- Return the 32 bit linear value equivalent of a far pointer.
- This function is used to calculate the difference between two
- far pointers.
-
- HeapAddr
-
- - void far * HeapAddr (HeapHandle b)
-
- - FUNCTION HeapAddr (b: HeapHandle): Pointer;
-
- Return the address of a heap memory block.
-
- HeapAlloc
-
- - HeapHandle HeapAlloc (unsigned long s)
-
- - FUNCTION HeapAlloc (s: LongInt): HeapHandle;
-
- Allocate a memory block from the heap. Return the block handle
- or SWEEP_NULL (Turbo C) or SWEEP_NIL (Turbo Pascal) if error.
- 's' is the number of bytes to allocate.
-
- HeapBlocks
-
- - unsigned HeapBlocks (void)
-
- - FUNCTION HeapBlocks: Word;
-
- Return the number of available memory blocks in the heap.
-
-
-
- HeapCurrent
-
- - void far * HeapCurrent (void)
-
- - FUNCTION HeapCurrent: Pointer;
-
- Return the address of the current heap.
-
- HeapExpand
-
- - void far * HeapExpand (unsigned long s)
-
- - PROCEDURE HeapExpand (s: LongInt)
-
- Increase the size of the current heap. The heap is expanded at
- its end by 's' bytes. The current heap address is returned.
- Note: You are responsible for making sure that there is enough
- available memory to perform this operation.
-
- HeapFree
-
- - void HeapFree (HeapHandle b)
-
- - PROCEDURE HeapFree (b: HeapHandle)
-
- Free a heap memory block.
-
- HeapInit
-
- - void far * HeapInit (void far *h, unsigned long s)
-
- - PROCEDURE HeapInit (h: Pointer; s: LongInt)
-
- Initialize a heap at the given address. The minimum heap size
- is 12 bytes. The maximum number of blocks is calculated as the
- heap size divided by 64 with a minimum of 32 and a maximum of
- about 21800. The newly initialized heap becomes the current
- heap and the original heap address is returned. The function
- HeapInitBlk is identical except that the maximum number of
- memory blocks is specified by the user rather than being calcu-
- lated. 'h' is the base heap address and 's' is the number of
- bytes allocated to the heap.
-
-
-
- HeapInitBlk
-
- - void far * HeapInitBlk (void far *h, unsigned long s,
- unsigned b)
-
- - PROCEDURE HeapInitBlk (h: Pointer; s: LongInt; b: Word)
-
- Initialize a heap at the given address. The minimum heap size
- is 12 bytes. The maximum number of blocks may be adjusted down,
- so use HeapBlocks to find the actual number initialized. The
- newly initialized heap becomes the current heap and the origi-
- nal heap address is returned. The function HeapInit is identi-
- cal except that the maximum number of blocks is calculated
- rather than being specified by the user. 'h' is the base heap
- address, 's' is the number of bytes allocated to the heap, and
- 'b' is the number of blocks to assign to the heap.
-
- HeapMemory
-
- - unsigned long HeapMemory (void)
-
- - FUNCTION HeapMemory: LongInt;
-
- Return the total available bytes in the heap.
-
- HeapReloc
-
- - void far * HeapReloc (void far *h);
-
- - PROCEDURE HeapReloc (h: Pointer);
-
- Relocate the heap. The current heap block addresses are
- changed to reflect the new base address 'h'. This function is
- used if the heap is moved to a new location, though it doesn't
- actually move the heap. HeapReloc is useful when resizing the
- memory block containing the heap or reading a saved heap into
- memory.
-
- HeapResize
-
- - HeapHandle HeapResize (HeapHandle b, unsigned long s)
-
- - PROCEDURE HeapResize (b: HeapHandle; s: LongInt)
-
- Resize a heap memory block. Returns the block handle (un-
- changed) or SWEEP_NULL if error.
-
-
-
- HeapResult
-
- - int HeapResult (void)
-
- - FUNCTION HeapResult: Word;
-
- Return the error code of the last heap operation (or zero if no
- error). The error code is reset with each operation (including
- this one). An error code of 1 is out of memory and 2 is out of
- memory blocks. The symbolic constants SWEEP_NOERROR,
- SWEEP_OUTOFBLOCKS, and SWEEP_OUTOFMEMORY have been defined to
- check for these return values.
-
- HeapSelect
-
- - void far * HeapSelect (void far *h)
-
- - PROCEDURE HeapSelect (h: Pointer)
-
- Switch to a previously initialized heap. Returns the current
- heap address.
-
- HeapShrink
-
- - void far * HeapShrink (unsigned long s)
-
- - PROCEDURE HeapShrink (s: LongInt)
-
- Decrease the size of the heap. The heap is adjusted at its end
- by 's' bytes. The current heap address is returned. Note: the
- heap MUST have at least 's' bytes free.
-
- HeapSize
-
- - unsigned long HeapSize (HeapHandle b)
-
- - FUNCTION HeapSize (b: HeapHandle): LongInt;
-
- Return the size of a heap memory block.
-
-
-
- Version History
- ---------------
-
- Version Description
- ------- -----------
-
- 1.00 Initial release.
-
- 1.10 HeapReloc and CopyBlock functions added. HeapShrink
- and HeapExpand now return the heap address (C versions
- only). The value of SWEEP_NULL and SWEEP_NIL, returned
- by a HeapAlloc and HeapResize failure, is now zero.
- This allows the handle to be used in a C conditional
- statement (zero indicates failure, non-zero indicates
- success). This library version is also slightly fast-
- er, primarily in memory copying.