1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
## -*- tcl -*-
# # ## ### ##### ######## ############# #####################
## Copyright (c) 2008 Andreas Kupries.
#
# This software is licensed as described in the file LICENSE, which
# you should have received as part of this distribution.
#
# This software consists of voluntary contributions made by many
# individuals. For exact contribution history, see the revision
# history and logs, available at http://fossil-scm.hwaci.com/fossil
# # ## ### ##### ######## ############# #####################
## Utilities for memory tracking
# # ## ### ##### ######## ############# #####################
## Requirements
package require Tcl 8.4 ; # Required runtime
package require struct::list ; # List assignment
# # ## ### ##### ######## ############# #####################
##
namespace eval ::vc::tools::mem {
# # ## ### ##### ######## #############
## Public API, Methods
if {[llength [info commands memory]]} {
proc minfo {} {
# memory info reduced to the set of relevant numbers in the output
struct::list assign [split [memory info] \n] tm tf cpa cba mpa mba
struct::list assign $tm _ _ tm
struct::list assign $tf _ _ tf
struct::list assign $cpa _ _ _ cpa
struct::list assign $cba _ _ _ cba
struct::list assign $mpa _ _ _ mpa
struct::list assign $mba _ _ _ mba
return [list $tm $tf $cpa $cba $mpa $mba]
}
} else {
proc minfo {} {return {0 0 0 0 0 0}}
}
proc mlog {} {
variable track ; if {!$track} { return {} }
variable lcba
variable lmba
variable mid
struct::list assign [minfo] _ _ _ cba _ mba
set dc [expr $cba - $lcba] ; set lcba $cba
set dm [expr $mba - $lmba] ; set lmba $mba
# projection: 1 2 3 4 5 6 7 6 8 10
return "[F [incr mid]] | [F $cba] | [F $dc] | [F $mba] | [F $dm] |=| "
}
proc mark {} {
variable track ; if {!$track} return
variable mid
variable lcba
variable lmark
set dm [expr {$lcba - $lmark}]
puts "[F $mid] | [F $lcba] | [F $dm] | [X %] | [X %] |@| [X %]"
set lmark $lcba
return
}
proc F {n} { format %10d $n }
proc X {c} { string repeat $c 10 }
proc mlimit {} {
variable track ; if {!$track} return ; # No checks if there is no memory tracking
variable limit ; if {!$limit} return ; # No checks if there is no memory limit set
struct::list assign [minfo] _ _ _ cba _ _
# Nothing to do if we are still under the limit
if {$cba <= $limit} return
# Notify user and kill the importer
puts ""
puts "\tMemory limit breached: $cba > $limit"
puts ""
exit 1
}
proc setlimit {thelimit} {
# Activate memory tracking, and set the limit. The specified
# limit is taken relative to the amount of memory allocated at
# the time of the call.
variable limit
struct::list assign [minfo] _ _ _ cba _ _
set limit [expr $cba + $thelimit]
track
return
}
proc notrack {} {
variable track 0
return
}
proc track {} {
variable track 1
return
}
# # ## ### ##### ######## #############
variable track 0 ; # Boolean flag. If set this module will track
# memory, inserting the relevant information
# whenever the application logs something.
variable limit 0 ; # The maximum amount of memory allowed to the
# application. This module will abort when
# 'current bytes allocated' goes over this
# value.
variable lcba 0 ; # Last 'current bytes allocated' (cba)
variable lmba 0 ; # Last 'maximum bytes allocated' (mba)
variable mid 0 ; # Memory id, abstract time
variable lmark 0 ; #
# # ## ### ##### ######## #############
}
namespace eval ::vc::tools::mem {
namespace export minfo mlog track notrack mlimit setlimit mark
}
# -----------------------------------------------------------------------------
# Ready
package provide vc::tools::mem 1.0
return
|