home *** CD-ROM | disk | FTP | other *** search
- unit overinit;
- {$F+,O-}
-
- INTERFACE
-
- function heapfunc(size: word): integer;
-
-
- {ShrinkOverlay: Free memory by dynamically reducing overlay buffer
- during program execution. "Robbing Peter to pay Paul"
-
- Steve Safigan 8/14/90 CompuServe ID 72251,2274
- Universal Tax Systems, Inc.
- 102 Margo Trail
- Rome, GA 30161
- (404) 232-7757
-
- Donated to the public domain.
- Thanks to Kim Kokonen for providing direction.
- Thanks to ????? for upgrading to version 6.0 and for the HEAPERROR hook.
-
- The most common means of reducing run-time memory requirements is by using
- overlays. This presents a paradox, because the overlay buffer must be
- fixed at program startup, reducing total free memory. The programmer is
- usually forced to define the smallest overlay buffer he (she) can get away
- with in order to leave enough room for dynamic variables. This slows
- program performance as the program has to swap code into and out of the
- overlay buffer often.
-
- A better solution is to start the program with a very large overlay buffer
- to reduce swapping. As the program requires more dynamic memory, the
- boundary between the overlay buffer and the heap can be adjusted to provide
- more memory to the heap, and less to the overlay buffer. Eventually,
- the overlay buffer may be reduced to a minimum size. At this point, the
- program may be thrashing terribly, but it may be more acceptable than
- running out of memory completely.
-
- Unfortunately, TP does not support changing the overlay buffer size
- after any variables are allocated. But the routine ShrinkOverlay does.
- It works by clearing the overlay buffer, changing the boundary between the
- overlay buffer and the heap, then adding a free list entry to the heap.
-
- ShrinkOverlay may be called explicitly by your program, or it may be called
- explicitly by a HEAPERROR routine when your program runs out of heap
- space. If you call ShrinkOverlay explicitly, it must take the following
- form:
-
- MEMORY_AMT := $8000
- IF MAXAVAIL < $8000 THEN ShrinkOverlay(MEMORY_AMT);
-
- MEMORY_AMT is the amount of memory to rob from the overlay buffer. It
- must be passed via a variable, because ShrinkOverlay returns the
- amount of memory actually freed. If the overlay buffer is already at
- its minimum size, or if no heap free list entries are available,
- ShrinkOverlay returns 0. The maximum amount of memory freed in a single
- call to ShrinkOverlay is 64K. ShrinkOverlay will round the memory freed
- to the next higher multiple of 16 bytes, so that it frees an even
- number of paragraphs.
-
- You may instead wish to use the supplied HEAPFUNC in order to invoke
- ShrinkOverlay automatically when the heap runs out of space. In order
- to use heapfunc, you must include the following line in your main
- program:
-
- heaperror := @heapfunc;
-
- This replaces TP's standard heap error handling routine with HEAPFUNC.
-
-
- Although calling ShrinkOverlay is as simple as that, there are a few
- additional steps needed in order to initialize. The sample unit OVERINIT
- shows initializing the memory buffer in preparation for ShrinkOverlay.
- Since this unit initializes the overlay buffer, it should appear first
- in your USES clause. You may replace the overlay initialization section
- with your own.
-
- The variable MinimumOverlay must be initialized to the minimum overlay
- buffer size your program will accept. This value must not be less than
- the initial value of OVRGETBUF, or you will not be able to fit your
- largest overlayed unit into the overlay buffer.
-
- This version was submitted to me as an upgrade to my TP5.5 Version.
- Regrettably, I have thrown out the fax I received listing the author of
- this version! If the author would like to identify himself, I would be
- happy to give him full credit.
-
- If anybody has any corrections or enhancements to ShrinkOverlay, contact
- me at the above address. Although it seems to work fine on my machine,
- I can't warrant that it will work properly in all environments. I'm
- looking for an implementation that would reverse this routine and restore
- the overlay buffer to its original size. Any ideas?}
-
- IMPLEMENTATION
-
- uses
- overlay;
-
- type
- linktype = record
- next: pointer;
- bytes: word;
- paragraphs: word;
- end;
-
- os = record
- o,s: word;
- end;
-
- var
- minimumoverlay: longint;
-
- procedure shrinkoverlay(var size: word);
- var
- tempsize: word;
- work: linktype;
- begin
- if ovrgetbuf - size < minimumoverlay then
- size := ovrgetbuf - minimumoverlay;
- size := size - (size mod 16);
- if size > 0 then
- begin
- tempsize := size div 16;
- ovrclearbuf;
- dec(ovrheapend,tempsize);
- os(heaporg).s := ovrheapend;
- os(heaporg).o := 0;
- work.next := freelist;
- work.paragraphs := tempsize;
- work.bytes := 0;
- move(work,heaporg^,8);
- freelist := heaporg;
- if ovrgetretry > ovrgetbuf then
- ovrsetretry(ovrgetbuf div 3);
- end;
- end;
-
- function heapfunc(size: word): integer;
- var
- x: word;
- begin
- if size > 0 then
- begin
- x := size + 16;
- if maxavail < size then
- shrinkoverlay(x)
- else
- x := 0;
- if x < size then
- heapfunc := 0
- else
- heapfunc := 2;
- end;
- end;
-
-
- begin
- minimumoverlay := ovrgetbuf;
- ovrsetbuf(ovrgetbuf + $F000); {set your own value here}
- ovrsetretry(ovrgetbuf div 3);
- end.