home *** CD-ROM | disk | FTP | other *** search
- ; FILE: MEM.INC
- ; Copyright (c) 1991 By Borland International, Inc.
- page
-
-
- ;
- ; shrink_memory - The main program should call this routine before
- ; initializing any memory system objects. This shrinks
- ; the DOS memory block used by the program to the
- ; minimum possible size.
- ;
- global shrink_memory:proc
-
-
- ;****************************************************************
- ; Memory manager
- ; This memory manager supports simple allocation
- ; and deallocation of blocks from memory.
- ;
- ;
-
- ; This value is used in the NEXT pointer to indicate a FREE block
- FREE_BLOCK = 0FFFFH
-
-
- ; Note that the VMT's for the objects in this file must be included in
- ; one of the .OBJ's of a project. This is accomplished by the MEM.ASM
- ; module defining the following equate before including this file:
- ;_MAKE_MEMVMT_ = 1
-
- ; Memory_block
- ; A memory block is created for each unit on the heap. Memory
- ; blocks for unused areas of the heap are larger, and contain more
- ; information, than used blocks on the heap. Note that there are
- ; derived classes that handle implementing used_blocks.
- ;
- ; \/ Not yet implemented
- ; initget- Handles getting an extra block of memory from DOS, and
- ; allocating getting it set up. It does not need to be
- ; passed the address of a memory block to init.
- ; This is an example of a constructor that even does it's
- ; own allocation, as well as setting up of VMT.
- ; Arguments:(segments of previous and next blocks)
- ; Returns: AX segment of block that was allocated
- ;
- ;
- ; init - Handles initializing a block to an unused state.
- ; Includes setting the VMT pointer to type the block as a
- ; memory_block and it also sets the next pointer and the
- ; size. The previous block pointer is unused since the
- ; memory system does not always find the previous block out
- ; of efficiency considerations.
- ; Arguments:(DS:SI instance ptr), (segments of previous and next blocks)
- ;
- ;
- ; deinit - Handles destruction of the memory block. Currently has no
- ; function for memory_block or memory_usedblock. No protocol
- ; for usage is setup.
- ;
- ; memstart - Returns fixed offset within memory blocks that marks the
- ; start of information that is only optionally used if the
- ; block is empty. This allows descendants to increase the
- ; amount of bookkeeping information used in the memory_block
- ; for all blocks, free and used.
- ; Users of the memory system only need to store segment
- ; values of alloced blocks, and they can use this function to
- ; fill in the offset if they want.
- ; Of course, this behaviour may not be compatible with future
- ; memory blocks which might not neccessarily return a constant
- ; value for the memstart.
- ; Arguments: None
- ; Returns: BX with fixed offset value
- ;
- ;
- ; Show - Shows whether or not the block is free.
- ; If the block is free, additional information concerning the block
- ; is printed, including it's next pointer and the size of the free
- ; area.
- ; Arguments: DS:SI - Address of the memory block
- ;
- ;
- ; MatchNext - Finds the address if the block whose next pointer points
- ; to the given block
- ; Arguments: DS:SI - Address of memory block
- ; AX - Segment address of block to find next ptr to.
- ; Returns: AX - Segment of memory block that points to the
- ; given block with next.
- ; AX=0 if a previous block was not found.
- ; DS:SI - Changed
- ;
- ; ScanFree - If the current block is not free, this routine scans forward
- ; until a free block is free
- ; Arguments: DS:SI - Address of memory block
- ; Returns: DS:SI - Points to a free block.
- ; DS=0 if no more free blocks
- ; AX - Size of block in paragraphs. 0 if not free.
- ; Size is already adjusted for bookkeeping info.
- ;
- ;
- ; GetNext - Returns the segment address of the next block.
- ; Arguments: DS:SI - Address of memory block
- ; Returns: AX - Segment of next memory block
- ;
- ;
- ; SetNext - Sets the pointer to the next block
- ; Arguments: DS:SI - Address of memory block
- ; AX - Segment of next memory block
- ; Returns: None
- ;
- ;
- ifdef _DO_SETPREV_
- ; SetPrev - Sets the pointer to the previous memory block. If the
- ; block is in use, this call does nothing.
- ; Arguments: DS:SI - Address of memory block
- ; AX - Segment of prev memroy block
- ; Returns: None
- endif
- ;
- ; SetSize - Sets the size field of the memory block. If the
- ; block is in use, this call does nothing.
- ; Arguments: DS:SI - Address of memory block
- ; AX - Size of the memory block
- ; Returns: None
- ;
- ; IsFree
- ; Arguments: DS:SI - Address of the memory block
- ; Returns Z flag set if the block is free.
- ;
- ;
- ; MarkUsed - Marks the block as used. This is done by copying the
- ; NEXT2 pointer into NEXT. This will erase the FFFF
- ; signature in the NEXT ptr, which will show the
- ; block as used. This does nothing if the block is already
- ; marked as used.
- ;
- ; Arguments: DS:SI - Address of the memory block
- ;
- ; MarkFree - Marks the block as free. This is done by copying the
- ; NEXT pointer into NEXT2, and putting 0FFFFH in NEXT.
- ; Also the size of the block is calculated and filled in.
- ; Also the previous block pointer is filled in.
- ;
- ; Arguments: DS:SI - Address of the memory block
- ; AX - Previous block
- ;
- ; RawBlockSize - Returns the total size in paragraphs of the block,
- ; including bookkeeping information. Only works for
- ; blocks that are free.
- ; Arguments: DS:SI - Address of memory block
- ; Returns: AX
- ;
- ; BreakBlock - Breaks a free block in two.
- ; Arguments: DS:SI - Address of the memory block
- ; AX - New desired size of the block, not counting
- ; bookkeeping info.
- ; Returns: AX Segment address of new free block, if block broken
- ; off, or returns same as original DS if whole block
- ; is used.
- ;
- ; Combine - Combines a block with it's previous block, if both are free.
- ; The previous block is guaranteed to be free if this is called.
- ; Alloc calls this during it's forward walk thru the stack.
- ; Blocks that are not free should ignore this call.
- ; Arguments: DS:SI - Address of the memory block
- ; AX - Address of the previous block.
- ; Returns: DS:SI - Address of the previous block if the combine was
- ; done, otherwise they are unchanged.
- ;
- ;
- ; LockBlock - Currently not used. This call should be made before using the
- ; contents of a block of memory allocated from the heap. This
- ; routine may return a new address to use as a pointer to the
- ; actual memory contents.
- ; This is automatically called before the ALLOC call terminates.
- ;
- ; UnLockBlock - Currently not used. This call should be given the value
- ; returned by the UnLockBlock routine.
- ;
- ; AllocFail - This method is called for all blocks if an allocation
- ; request of the memory system is about to fail. If the
- ; block does nothing with this request, it needs to return
- ; the Z flag set. If it is able to process this request
- ; and cause memory to be freed, or in some other way enable
- ; the memory system to possibly succeed, then it can return
- ; the zero flag unset, and the memory_system will retry the
- ; allocation request.
- ; Example: Diskswapping memory blocks could delay actual
- ; swap out until they recieve this call. Memory blocks and
- ; the controlling swap block should know the location of
- ; each other, so they both can respond to the request.
- ; Blocks that implement memory swapping might even try to
- ; swap out several blocks before returning with the Z flag
- ; unset.
-
-
- ; Note the size of PREV & NEXT. Because MASM mode makes all symbols
- ; be global in scope, if other structures define their own PREV or
- ; NEXT pointers, they must be of the same size, and at the same
- ; location within the structure. Since other routines may want
- ; fullsize NEXT and PREV pointers, this structure defines them to be
- ; the same size.... However, a more advanced memory block could
- ; make use of the extra word to implement some sort of disk cacheing
- ; or other use, especially if lock/unlock system is used for all
- ; blocks.
- ; Note that FindPrev_ is defined to avoid conflict with memory system
- ; FindPrev routine.
- ; Note also show
-
- global memory_block_initget:proc
- global memory_block_init:proc
- global memory_block_deinit:proc
- global mb_show:proc
- global memory_block_reserved_size:proc
- global mb_findprev:proc
- global mb_scan:proc
- global mb_getnext:proc
- global mb_isfree:proc
- global mb_setprev:proc
- global mb_setnext:proc
- global mb_setsize:proc
- global mb_rawblocksize:proc
- global mb_breakblock:proc
- global memory_block_markused:proc
- global memory_block_combine:proc
- global memory_block_markfree:proc
- global memory_block_lock:proc
- global memory_block_unlock:proc
- global memory_block_allocfail:proc
-
- memory_block STRUC METHOD {
- initget:mptr=memory_block_initget ; SI returns seg of allocated block.
- init:mptr=memory_block_init ; DS:SI is block.
- virtual deinit:mptr=memory_block_deinit
- virtual show:mptr=mb_show
- virtual memstart:mptr=memory_block_reserved_size
- virtual MatchNext:mptr=mb_findprev
- virtual ScanFree:mptr=mb_scan
- virtual GetNext:mptr=mb_getnext
- virtual IsFree:mptr=mb_isfree
- virtual SetPrev:mptr=mb_setprev
- virtual SetNext:mptr=mb_setnext
- virtual SetSize:mptr=mb_setsize
- virtual RawBlockSize:mptr=mb_rawblocksize
- virtual BreakBlock:mptr=mb_breakblock
- virtual MarkUsed:mptr=memory_block_markused
- virtual Combine:mptr=memory_block_combine
- virtual MarkFree:mptr=memory_block_markfree
- virtual LockBlock:mptr=memory_block_lock
- virtual UnLockBlock:mptr=memory_block_unlock
- virtual AllocFail:mptr=memory_block_allocfail
- }
-
- TBLPTR
- next dd ? ; Segment of the next block in memory.
- ; (Only used as a word. High word set to blank in init.)
- ; FFFF if this block is unused.
- ; 0000 if this is the last block.
-
- ; Mark this offset to be returned as where the caller can start at
- ; using this block of memory.
- @memory_block_used_start label byte
-
- ; The following are only for unused blocks
- next2 dd ? ; The segment of the next block if this block is unused.
- ; (Only used as a word. High word set to blank in init.)
- ifdef _DO_SETPREV_
- prev dd ? ; Segment of the previous block.
- ; (Only used as a word. High word set to blank in init.)
- endif
- blksize dw ? ; Size of the block in paragraphs.
- ; This should be the size of the allocateable area,
- ; (corrected for the bookkeeping area)
-
- memory_block ends
-
-
- ifdef _MAKE_MEMVMT_
- ; Make the VMT for the memory blocks
- MAKE_VMT
- endif
-
- ;mbsize = size @TableAddr_MEMORY_BLOCK
-
-
- ; memory_usedblock
- ; When a block of memory on the heap is in use, it's VMT is changed
- ; so that the block becomes used. The usedblock routines handle returning,
- ; in a faster way, the results for various block methods. The block
- ; methods for invalid operations on used blocks are quickly trapped,
- ; and can even vector to internal_error display routines.
- ; While the normal memory_block routines do extensive checking with the
- ; IsFree method, changing used blocks to this type should speed many
- ; operations
-
- global memory_usedblock_init:proc
- global memory_usedblock_getnext:proc
- global memory_usedblock_scan:proc
- global memory_usedblock_isfree:proc
- global memory_usedblock_invalid:proc
- global memory_usedblock_setnext:proc
- global memory_usedblock_markfree:proc
- global memory_usedblock_show:proc
- global memory_usedblock_combine:proc
- global memory_usedblock_lock:proc
- global memory_usedblock_unlock:proc
-
- memory_usedblock struc memory_block method {
- init:mptr = memory_usedblock_init
- virtual getnext:mptr=memory_usedblock_getnext
- virtual ScanFree:mptr=memory_usedblock_scan
- virtual IsFree:mptr=memory_usedblock_isfree
- virtual SetPrev:mptr=memory_usedblock_invalid
- virtual SetSize:mptr=memory_usedblock_invalid
- virtual SetNext:mptr=memory_usedblock_setnext
- virtual BreakBlock:mptr=memory_usedblock_invalid
- virtual MarkFree:mptr=memory_usedblock_markfree
- virtual MarkUsed:mptr=memory_usedblock_invalid
- virtual show:mptr = memory_usedblock_show
- virtual Combine:mptr=memory_usedblock_combine
- virtual LockBlock:mptr=memory_usedblock_lock
- virtual UnLockBlock:mptr=memory_usedblock_unlock
- }
- memory_usedblock ends
-
-
- ifdef _MAKE_MEMVMT_
- ; Make the VMT for the memory usedblocks
- MAKE_VMT
- endif
-
- ; memory_endblock
- ; This block is placed at the end of the memory heap. It should
- ; be only a paragraph in size, just large enough for the bookkeeping
- ; info of the segment. This allows all other blocks on the heap to
- ; be guarranteed that a block follows them, and therefore they can all
- ; use simple segment arithmetic to calculate their size. While the
- ; size of the memory block can be made a part of the information that
- ; is stored for the free blocks, used blocks do not have room for this
- ; information. Since the block does not have access to the last segment
- ; variable of the heap, the ending block on the heap would have no way
- ; to calculate it's size if it is used, since the next pointer would
- ; be zero. This block handles the whole matter, by appearing to be a
- ; permanently used block at the end of the heap. Since the next pointer
- ; is zero, all heapwalks will stop with this block.
-
- global memory_endblock_init:proc
- global memory_endblock_show:proc
- global memory_endblock_getnext:proc
- global memory_endblock_ignore:proc
-
- memory_endblock struc memory_usedblock method {
- init:mptr = memory_endblock_init
- virtual getnext:mptr = memory_endblock_getnext
- virtual show:mptr = memory_endblock_show
- virtual RawBlockSize:mptr=memory_endblock_getnext
- virtual LockBlock:mptr=memory_endblock_ignore
- virtual UnLockBlock:mptr=memory_endblock_ignore
- }
- memory_endblock ends
-
-
- ifdef _MAKE_MEMVMT_
- ; Make the VMT for the memory endblocks
- MAKE_VMT
- endif
-
-
- ; MEMORY_SYSTEM
- ;
- ; init - Handles setting up a block of memory for memory allocation
- ; management.
- ; Arguments: DS:SI - Address of memory system object
- ; AX - 0 - Allocate maximum block.
- ; other - Size of desired block
- ; High-bit of AX - If 1 - Allow smaller block
- ; If 0 - Fail if not enough memory
- ; Returns: Memory block initialized.
- ; DS:SI unchanged.
- ; AX is size of actual block. (Note that maximum allocateable
- ; size is a paragraph less than this value because of
- ; memory_block bookkeeping.)
- ;
- ;
- ; alloc - Allocates an area in the memory block.
- ; Arguments: DS:SI - Address of memory system object
- ; AX - Size in bytes of area to allocate
- ; Returns: AX is segment of memory block
- ; BX is the offset into the memory block
- ; DS:SI unchanged
- ; If no block can be allocated, then AX is zero, and
- ; BX is the size of the largest block.
- ;
- ;
- ; free - Frees an allocated area
- ; Arguments: DS:SI - Address of the memory system object
- ; AX - Segment of area to be freed
- ; Returns: None
- ;
- ;
- ; blockofs - Returns fixed offset within memory blocks that marks the
- ; start of information that is only optionally used if the
- ; block is empty. This allows descendants to increase the
- ; amount of bookkeeping information used in the memory_block
- ; for all blocks, free and used.
- ; Users of the memory system only need to store segment
- ; values of alloced blocks, and they can use this function to
- ; fill in the offset if they want.
- ; Arguments: AX Segment of block to find this value for
- ; (If AX=0, then root block's blockofs is returned.)
- ; Returns: AX with fixed offset value
- ;
- ;
- ; resetrover - Makes rover point at the root block. This causes the
- ; next alloc call to use the earliest possible free
- ; block in the heap.
- ;
- ;
- ;
- ; show - Displays global status information for the memory_system, and
- ; then calls the show method for each of the individual memory
- ; blocks.
- ;
- ;
- ; freeall - Frees all blocks on the heap.
- ;
- ;***** Lower Level Calls:
- ;
- ; FindPrev - Finds the address if the block current to the previous block.
- ; Arguments: DS:SI - Address of memory system
- ; AX - Segment address of block to find previous for
- ; Returns: AX - Segment of previous memory block
- ; AX=0 if a previous block was not found.
- ; DS:SI - Unchanged
-
- ; This is the global memory system manager object.
-
- global memory_system_init:proc
- global memory_system_deinit:proc
- global memory_system_show:proc
- global memory_system_alloc:proc
- global memory_system_free:proc
- global memory_system_blockofs:proc
- global memory_system_freeall:proc
- global memory_system_resetrover:proc
- global memory_system_findprev:proc
-
- memory_system STRUC METHOD {
- init:mptr = memory_system_init
- virtual deinit:mptr=memory_system_deinit
- virtual show:mptr=memory_system_show
- virtual alloc:mptr=memory_system_alloc
- virtual free:mptr=memory_system_free
- blockofs:mptr=memory_system_blockofs
- virtual freeall:mptr=memory_system_freeall
- virtual resetrover:mptr=memory_system_resetrover
- virtual FindPrev:mptr=memory_system_findprev
- }
- TBLPTR
-
- blocksize dw ? ; Size of the block of memory managed by this
- ; memory system manager.
- root dw ? ; The first block of memory
- last dw ? ; The last block of memory
- rover dw ? ; Moves through memory
-
- freespace dw ? ; Remembers the amount of free space total in paragraphs
- usedspace dw ? ; Remembers the amount of used memory in paragraphs
- memory_system ends
- ;mssize = size @TableAddr_MEMORY_system
-
- ifdef _MAKE_MEMVMT_
- ; Make the VMT for the memory endblocks
- MAKE_VMT
- endif
-
-
-