home *** CD-ROM | disk | FTP | other *** search
- #---------------------------------------------------------------------------
- #
- # Copyright (c) 1992 by Westmount Technology B.V., Delft, The Netherlands.
- #
- # This software is furnished under a license and may be used only in
- # accordance with the terms of such license and with the inclusion of
- # the above copyright notice. This software or any other copies thereof
- # may not be provided or otherwise made available to any other person.
- # No title to and ownership of the software is hereby transferred.
- #
- # The information in this software is subject to change without notice
- # and should not be construed as a commitment by Westmount Technology B.V.
- #
- #---------------------------------------------------------------------------
- #
- # File : @(#)profrep.tcl 1.3 (1.1)
- # Author : Karl Lehenbauer and Mark Diekhans
- # Original date : Tue Sep 1 16:24:28 MET DST 1992
- # Description : Tcl part of profile package
- # extended with 'cpc': CPU time per call
- #
- #---------------------------------------------------------------------------
- #
- # @(#)profrep.tcl 1.3 (1.1) 15 May 1995 Copyright 1992 Westmount Technology
- #
- #---------------------------------------------------------------------------
- #@package: profrep profrep
-
- # If this isn't Extended Tcl, define some support procs.
-
- if {[info commands clength] == ""} {
- proc clength {str} {return [string length $str]}
- }
- if {[info commands max] == ""} {
- proc max {a b} {if {$a > $b} {return $a} else {return $b}}
- }
-
- if {[info commands replicate] == ""} {
- proc replicate {str cnt} {
- set result {}
- for {set i 0} {$i < $cnt} {incr i} {
- append result $str
- }
- }
- }
-
- #
- # Summarize the data from the profile command to the specified significant
- # stack depth. Returns the maximum number of characters of any significant
- # stack. (useful in columnizing reports).
- #
- proc profrep:summarize {profDataVar stackDepth sumProfDataVar} {
- upvar $profDataVar profData $sumProfDataVar sumProfData
-
- if {(![info exists profData]) || ([catch {array size profData}] != 0)} {
- error "`profDataVar' must be the name of an array returned by the `profile off' command"
- }
- set maxNameLen 0
- foreach procStack [array names profData] {
- if {[llength $procStack] < $stackDepth} {
- set sigProcStack $procStack
- } else {
- set sigProcStack [lrange $procStack 0 [expr {$stackDepth - 1}]]
- }
- set maxNameLen [max $maxNameLen [clength $sigProcStack]]
- if [info exists sumProfData($sigProcStack)] {
- set cur $sumProfData($sigProcStack)
- set add $profData($procStack)
- set new [expr [lindex $cur 0]+[lindex $add 0]]
- lappend new [expr [lindex $cur 1]+[lindex $add 1]]
- lappend new [expr [lindex $cur 2]+[lindex $add 2]]
- set sumProfData($sigProcStack) $new
- } else {
- set sumProfData($sigProcStack) $profData($procStack)
- }
- }
- return $maxNameLen
- }
-
- #
- # Generate a list, sorted in descending order by the specified key, contain
- # the indices into the summarized data.
- #
- proc profrep:sort {sumProfDataVar sortKey} {
- upvar $sumProfDataVar sumProfData
-
- case $sortKey {
- {calls} {set keyIndex 0}
- {real} {set keyIndex 1}
- {cpu} {set keyIndex 2}
- {cpc} {set keyIndex 3}
- default {
- error "Expected a sort of: `calls', `cpu', `cpc' or ` real'"}
- }
-
- # Build a list to sort cosisting of a fix-length string containing the
- # key value and proc stack. Then sort it.
-
- foreach procStack [array names sumProfData] {
- set calls [lindex $sumProfData($procStack) 0]
- set cpu [lindex $sumProfData($procStack) 2]
- lappend sumProfData($procStack) [expr $cpu/$calls]
- set key [format "%016d" [lindex $sumProfData($procStack) $keyIndex]]
- lappend keyProcList [list $key $procStack]
- }
- set keyProcList [lsort $keyProcList]
-
- # Convert the assending sorted list into a descending list of proc stacks.
-
- for {set idx [expr [llength $keyProcList]-1]} {$idx >= 0} {incr idx -1} {
- lappend sortedProcList [lindex [lindex $keyProcList $idx] 1]
- }
- return $sortedProcList
- }
-
- #
- # Print the sorted report
- #
-
- proc profrep:print {sumProfDataVar sortedProcList maxNameLen outFile
- userTitle} {
- upvar $sumProfDataVar sumProfData
-
- if {$outFile == ""} {
- set outFH stdout
- } else {
- set outFH [open $outFile w]
- }
-
- # Output a header.
-
- set stackTitle "Procedure Call Stack"
- set maxNameLen [max $maxNameLen [clength $stackTitle]]
- set hdr [format "%-${maxNameLen}s %10s %10s %10s %10s" $stackTitle \
- "Calls" "Real Time" "CPU Time" "CPU/Call"]
- if {$userTitle != ""} {
- puts $outFH [replicate - [clength $hdr]]
- puts $outFH $userTitle
- }
- puts $outFH [replicate - [clength $hdr]]
- puts $outFH $hdr
- puts $outFH [replicate - [clength $hdr]]
-
- # Output the data in sorted order.
-
- foreach procStack $sortedProcList {
- set data $sumProfData($procStack)
- puts $outFH [format "%-${maxNameLen}s %10d %10d %10d %10d" $procStack \
- [lindex $data 0] [lindex $data 1] [lindex $data 2] [lindex $data 3]]
- }
- if {$outFile != ""} {
- close $outFH
- }
- }
-
- #------------------------------------------------------------------------------
- # Generate a report from data collect from the profile command.
- # o profDataVar (I) - The name of the array containing the data from profile.
- # o sortKey (I) - Value to sort by. One of "calls", "cpu" or "real".
- # o stackDepth (I) - The stack depth to consider significant.
- # o outFile (I) - Name of file to write the report to. If omitted, stdout
- # is assumed.
- # o userTitle (I) - Title line to add to output.
-
- proc profrep {profDataVar sortKey stackDepth {outFile {}} {userTitle {}}} {
- upvar $profDataVar profData
-
- set maxNameLen [profrep:summarize profData $stackDepth sumProfData]
- set sortedProcList [profrep:sort sumProfData $sortKey]
- profrep:print sumProfData $sortedProcList $maxNameLen $outFile $userTitle
-
- }
-