File: mem.tcl

package info (click to toggle)
fossil 1%3A1.22.1%2Bdfsg-0.1
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 10,588 kB
  • sloc: ansic: 151,799; tcl: 10,291; sh: 4,413; makefile: 1,822; sql: 376
file content (139 lines) | stat: -rw-r--r-- 3,880 bytes parent folder | download | duplicates (3)
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