summaryrefslogtreecommitdiffstats
path: root/runtime/staprun/stap_merge.tcl
blob: 47d419ce6b61d9914e8802affece208f53c74746 (plain)
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
#!/usr/bin/env tclsh
#
# stap_merge.tcl - systemtap merge program
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# Copyright (C) Red Hat Inc, 2007
#
#

proc usage {} {
	puts stderr "$::argv0 \[-v\] \[-o output_filename\] input_files ...\n"
	exit 1
}

set outfile "stdout"
set verbose 0
set index 0
while {[string match -* [lindex $argv $index]]} {
    switch -glob -- [lindex $argv $index] {
	-v {set verbose 1}
	-o   {incr index; set outfile [lindex $argv $index]}
	default {usage}
    }
    incr index
}

if {$tcl_platform(byteOrder) == "littleEndian"} {
    set int_format i
} else {
    set int_format I
}

set files [lrange $argv $index end]

set n 0
foreach file $files {
    if {[catch {open $file} fd($n)]} {
	puts stderr $fd($n)
	exit 1
    }
    fconfigure $fd($n) -translation binary
    if {![binary scan [read $fd($n) 4] $int_format timestamp($n)]} {
	continue
    }
    set timestamp($n) [expr $timestamp($n) & 0xFFFFFFFF]
    incr n
}
set ncpus $n

if {$outfile != "stdout"} {
    if {[catch {open $outfile w} outfile]} {
	puts stderr $outfile
	exit 1
    }
}
fconfigure $outfile -translation binary

while {1} {
    set mincpu -1
    for {set n 0} {$n < $ncpus} {incr n} {
	if {[info exists fd($n)] && (![info exists min] || $timestamp($n) <= $min)} {
	    set min $timestamp($n)
	    set mincpu $n
	}
    }

    if {![info exists min]} {break}

    if {![binary scan [read $fd($mincpu) 4] $int_format len]} {
	puts stderr "Error reading length from channel $mincpu"
	exit 1
    }

    if {$verbose == 1} {
	puts stderr "\[CPU:$mincpu, seq=$min, length=$len\]"
    }

    set data [read $fd($mincpu) $len]
    puts -nonewline $outfile $data

    set data [read $fd($mincpu) 4]
    if {$data == ""} {
	unset fd($mincpu)
    } else {
	binary scan $data $int_format timestamp($mincpu)
	set timestamp($mincpu) [expr $timestamp($mincpu) & 0xFFFFFFFF]
    }
    unset min
}