home *** CD-ROM | disk | FTP | other *** search
- (*
- ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓▓·── ──·▓▓▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓▓│ │░░▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓▓ Unit was conceived, designed and written ░░▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓▓ by Floor A.C. Naaijkens for ░░▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓▓ UltiHouse Software / The ECO Group. ░░▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓▓ ░░▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓▓ (C) MCMXCII by EUROCON PANATIONAL CORPORATION. ░░▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓▓ All Rights Reserved for The ECO Group. ░░▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓▓ ░░▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓▓│ │░░▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓▓·── ──·░░▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
- ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
- *)
- {$S-,R-,I-,B-,D-,F-}
- unit eco_stak;
- {-unit for monitoring stack and heap usage}
- interface
- const
- {If True, results are reported automatically at the end of the program. Set
- to false if you want to display results in another manner.}
- reportstackusage : boolean = true;
-
- var
- {The following variables, like the two procedures that follow, are interfaced
- solely for the purpose of displaying results. You should never alter any of
- these variables.}
- ourss : word; {value of ss register when program began}
- initialsp : word; {value of sp register when program began}
- lowestsp : word; {lowest value for sp register}
- heaphigh : pointer; {highest address pointed to by heapptr}
-
- procedure calcstackusage(var stackusage : word; var heapusage : longint);
- {-calculate stack and heap usage}
-
- procedure showstackusage;
- {-display stack and heap usage information}
-
- {The next two routines are interfaced in case you need or want to deinstall the
- INT $8 handler temporarily, as you might when using the Exec procedure in the
- dos unit.}
-
- procedure installint8;
- {-save int $8 vector and install our isr, if not already installed}
-
- procedure restoreint8;
- {-restore the old int $8 handler if our isr is installed}
-
- {The following routine allows you to alter the rate at which samples are taken.
- For it to have any effect, it must be preceded by a call to RestoreInt8 and
- followed by a call to installint8.}
-
- procedure setsamplerate(rate : word);
- {-set number of samples per second. default is 1165, minimum is 18.}
-
- {==========================================================================}
-
- implementation
-
- type
- segofs = {structure of a 32-bit pointer}
- record
- offset, segment : word;
- end;
- const
- int8installed : boolean = false; {true if our int $8 handler is installed}
- defaultrate = 1024; {corresponds to 1165 samples/second}
- var
- saveint8 : ^pointer; {pointer to original int $8 vector}
- saveexitproc : pointer; {saved value for exitproc}
- vectors : array[0..$ff] of pointer absolute $0:$0;
- rate8253,
- counts,
- countspertick : word;
-
- procedure intsoff;
- {-turn off cpu interrupts}
- inline($fa);
-
- procedure intson;
- {-turn on cpu interrupts}
- inline($fb);
-
- {$L ECO_STAK.OBJ}
-
- procedure actualsaveint8;
- {-actually a pointer variable in cs}
- external {tpstack} ;
-
- procedure int8;
- {-interrupt service routine used to monitor stack and heap usage}
- external {tpstack} ;
-
- procedure settimerrate(rate : word);
- {-program system 8253 timer number 0 to run at specified rate}
- begin {settimerrate}
- intsoff;
- port[$43] := $36;
- port[$40] := lo(rate);
- inline($eb/$00); {null jump}
- port[$40] := hi(rate);
- intson;
- end; {settimerrate}
-
- procedure installint8;
- {-save int $8 vector and install our isr, if not already installed}
- begin {installint8}
- {make sure we're not already installed, in case we are called twice.
- if we don't do this check, SaveInt8 could get pointed to *our* ISR}
- if not int8installed then begin
- {save the current vector}
- saveint8^ := vectors[$8];
-
- {set counts til next system timer tick}
- counts := 0;
-
- {keep interrupts off}
- intsoff;
-
- {take over the timer tick}
- vectors[$8] := @int8;
-
- {reprogram the timer to run at the new rate}
- settimerrate(rate8253);
-
- {restore interrupts}
- intson;
-
- {now we're installed}
- int8installed := true;
- end;
- end; {installint8}
-
- procedure restoreint8;
- {-restore the old int $8 handler if our isr is installed}
- begin {restoreint8}
- {if we're currently installed, then deinstall}
- if int8installed then begin
- {no more samples}
- intsoff;
-
- {give back the timer interrupt}
- vectors[$8] := saveint8^;
-
- {reprogram the clock to run at normal rate}
- settimerrate(0);
-
- {normal interrupts again}
- intson;
-
- {no longer installed}
- int8installed := false;
- end;
- end; {restoreint8}
-
- procedure setsamplerate(rate : word);
- {-set number of samples per second. default is 1165, minimum is 18.}
- var
- disable : boolean;
- begin {setsamplerate}
- if (rate >= 18) then begin
- {deactivate int8 temporarily if necessary}
- disable := int8installed;
- if disable then
- restoreint8;
-
- rate8253 := longint($123400) div longint(rate);
- countspertick := longint($10000) div longint(rate8253);
-
- {reactivate int8 if necessary}
- if disable then
- installint8;
- end;
- end; {setsamplerate}
-
- procedure calcstackusage(var stackusage : word; var heapusage : longint);
- {-calculate stack and heap usage}
- begin {calcstackusage}
- {calculate stack usage}
- stackusage := initialsp-lowestsp;
-
- {calculate heap usage}
- heapusage :=
- (longint(segofs(heaphigh).segment-segofs(heaporg).segment) * 16) +
- longint(segofs(heaphigh).offset-segofs(heaporg).offset);
- end; {calcstackusage}
-
- procedure showstackusage;
- {-display stack and heap usage information}
- var
- stackusage : word;
- heapusage : longint;
- begin {showstackusage}
- {calculate stack and heap usage}
- calcstackusage(stackusage, heapusage);
-
- {show them}
- writeln('Stack usage: ', stackusage, ' bytes.');
- writeln('Heap usage: ', heapusage, ' bytes.');
- end; {showstackusage}
-
- {$F+} {Don't forget that exit handlers are always called FAR!}
- procedure ourexitproc;
- {-deinstalls our int $8 handler and reports stack/heap usage}
- begin {ourexitproc}
- {restore exitproc}
- exitproc := saveexitproc;
-
- {restore int $8}
- restoreint8;
-
- {show results if desired}
- if reportstackusage then
- showstackusage;
- end; {ourexitproc}
- {$F-}
-
- begin {tpstack}
- {initialize saveint8}
- saveint8 := @actualsaveint8;
-
- {initialize rate8253 and countspertick}
- setsamplerate(defaultrate);
-
- {save current value for ss}
- ourss := sseg;
-
- {save current value of sp and account for the return address on the stack}
- initialsp := sptr+sizeof(pointer);
- lowestsp := initialsp;
-
- {save current position of heapptr}
- heaphigh := heapptr;
-
- {install our isr}
- installint8;
-
- {save exitproc and install our exit handler}
- saveexitproc := exitproc;
- exitproc := @ourexitproc;
- end. {tpstack}
-