1*2987e32fSAdrian Hunter# export-to-postgresql.py: export perf data to a postgresql database
2*2987e32fSAdrian Hunter# Copyright (c) 2014, Intel Corporation.
3*2987e32fSAdrian Hunter#
4*2987e32fSAdrian Hunter# This program is free software; you can redistribute it and/or modify it
5*2987e32fSAdrian Hunter# under the terms and conditions of the GNU General Public License,
6*2987e32fSAdrian Hunter# version 2, as published by the Free Software Foundation.
7*2987e32fSAdrian Hunter#
8*2987e32fSAdrian Hunter# This program is distributed in the hope it will be useful, but WITHOUT
9*2987e32fSAdrian Hunter# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10*2987e32fSAdrian Hunter# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11*2987e32fSAdrian Hunter# more details.
12*2987e32fSAdrian Hunter
13*2987e32fSAdrian Hunterimport os
14*2987e32fSAdrian Hunterimport sys
15*2987e32fSAdrian Hunterimport struct
16*2987e32fSAdrian Hunterimport datetime
17*2987e32fSAdrian Hunter
18*2987e32fSAdrian Hunterfrom PySide.QtSql import *
19*2987e32fSAdrian Hunter
20*2987e32fSAdrian Hunter# Need to access PostgreSQL C library directly to use COPY FROM STDIN
21*2987e32fSAdrian Hunterfrom ctypes import *
22*2987e32fSAdrian Hunterlibpq = CDLL("libpq.so.5")
23*2987e32fSAdrian HunterPQconnectdb = libpq.PQconnectdb
24*2987e32fSAdrian HunterPQconnectdb.restype = c_void_p
25*2987e32fSAdrian HunterPQfinish = libpq.PQfinish
26*2987e32fSAdrian HunterPQstatus = libpq.PQstatus
27*2987e32fSAdrian HunterPQexec = libpq.PQexec
28*2987e32fSAdrian HunterPQexec.restype = c_void_p
29*2987e32fSAdrian HunterPQresultStatus = libpq.PQresultStatus
30*2987e32fSAdrian HunterPQputCopyData = libpq.PQputCopyData
31*2987e32fSAdrian HunterPQputCopyData.argtypes = [ c_void_p, c_void_p, c_int ]
32*2987e32fSAdrian HunterPQputCopyEnd = libpq.PQputCopyEnd
33*2987e32fSAdrian HunterPQputCopyEnd.argtypes = [ c_void_p, c_void_p ]
34*2987e32fSAdrian Hunter
35*2987e32fSAdrian Huntersys.path.append(os.environ['PERF_EXEC_PATH'] + \
36*2987e32fSAdrian Hunter	'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
37*2987e32fSAdrian Hunter
38*2987e32fSAdrian Hunter# These perf imports are not used at present
39*2987e32fSAdrian Hunter#from perf_trace_context import *
40*2987e32fSAdrian Hunter#from Core import *
41*2987e32fSAdrian Hunter
42*2987e32fSAdrian Hunterperf_db_export_mode = True
43*2987e32fSAdrian Hunter
44*2987e32fSAdrian Hunterdef usage():
45*2987e32fSAdrian Hunter	print >> sys.stderr, "Usage is: export-to-postgresql.py <database name> [<columns>]"
46*2987e32fSAdrian Hunter	print >> sys.stderr, "where:	columns		'all' or 'branches'"
47*2987e32fSAdrian Hunter	raise Exception("Too few arguments")
48*2987e32fSAdrian Hunter
49*2987e32fSAdrian Hunterif (len(sys.argv) < 2):
50*2987e32fSAdrian Hunter	usage()
51*2987e32fSAdrian Hunter
52*2987e32fSAdrian Hunterdbname = sys.argv[1]
53*2987e32fSAdrian Hunter
54*2987e32fSAdrian Hunterif (len(sys.argv) >= 3):
55*2987e32fSAdrian Hunter	columns = sys.argv[2]
56*2987e32fSAdrian Hunterelse:
57*2987e32fSAdrian Hunter	columns = "all"
58*2987e32fSAdrian Hunter
59*2987e32fSAdrian Hunterif columns not in ("all", "branches"):
60*2987e32fSAdrian Hunter	usage()
61*2987e32fSAdrian Hunter
62*2987e32fSAdrian Hunterbranches = (columns == "branches")
63*2987e32fSAdrian Hunter
64*2987e32fSAdrian Hunteroutput_dir_name = os.getcwd() + "/" + dbname + "-perf-data"
65*2987e32fSAdrian Hunteros.mkdir(output_dir_name)
66*2987e32fSAdrian Hunter
67*2987e32fSAdrian Hunterdef do_query(q, s):
68*2987e32fSAdrian Hunter	if (q.exec_(s)):
69*2987e32fSAdrian Hunter		return
70*2987e32fSAdrian Hunter	raise Exception("Query failed: " + q.lastError().text())
71*2987e32fSAdrian Hunter
72*2987e32fSAdrian Hunterprint datetime.datetime.today(), "Creating database..."
73*2987e32fSAdrian Hunter
74*2987e32fSAdrian Hunterdb = QSqlDatabase.addDatabase('QPSQL')
75*2987e32fSAdrian Hunterquery = QSqlQuery(db)
76*2987e32fSAdrian Hunterdb.setDatabaseName('postgres')
77*2987e32fSAdrian Hunterdb.open()
78*2987e32fSAdrian Huntertry:
79*2987e32fSAdrian Hunter	do_query(query, 'CREATE DATABASE ' + dbname)
80*2987e32fSAdrian Hunterexcept:
81*2987e32fSAdrian Hunter	os.rmdir(output_dir_name)
82*2987e32fSAdrian Hunter	raise
83*2987e32fSAdrian Hunterquery.finish()
84*2987e32fSAdrian Hunterquery.clear()
85*2987e32fSAdrian Hunterdb.close()
86*2987e32fSAdrian Hunter
87*2987e32fSAdrian Hunterdb.setDatabaseName(dbname)
88*2987e32fSAdrian Hunterdb.open()
89*2987e32fSAdrian Hunter
90*2987e32fSAdrian Hunterquery = QSqlQuery(db)
91*2987e32fSAdrian Hunterdo_query(query, 'SET client_min_messages TO WARNING')
92*2987e32fSAdrian Hunter
93*2987e32fSAdrian Hunterdo_query(query, 'CREATE TABLE selected_events ('
94*2987e32fSAdrian Hunter		'id		bigint		NOT NULL,'
95*2987e32fSAdrian Hunter		'name		varchar(80))')
96*2987e32fSAdrian Hunterdo_query(query, 'CREATE TABLE machines ('
97*2987e32fSAdrian Hunter		'id		bigint		NOT NULL,'
98*2987e32fSAdrian Hunter		'pid		integer,'
99*2987e32fSAdrian Hunter		'root_dir 	varchar(4096))')
100*2987e32fSAdrian Hunterdo_query(query, 'CREATE TABLE threads ('
101*2987e32fSAdrian Hunter		'id		bigint		NOT NULL,'
102*2987e32fSAdrian Hunter		'machine_id	bigint,'
103*2987e32fSAdrian Hunter		'process_id	bigint,'
104*2987e32fSAdrian Hunter		'pid		integer,'
105*2987e32fSAdrian Hunter		'tid		integer)')
106*2987e32fSAdrian Hunterdo_query(query, 'CREATE TABLE comms ('
107*2987e32fSAdrian Hunter		'id		bigint		NOT NULL,'
108*2987e32fSAdrian Hunter		'comm		varchar(16))')
109*2987e32fSAdrian Hunterdo_query(query, 'CREATE TABLE comm_threads ('
110*2987e32fSAdrian Hunter		'id		bigint		NOT NULL,'
111*2987e32fSAdrian Hunter		'comm_id	bigint,'
112*2987e32fSAdrian Hunter		'thread_id	bigint)')
113*2987e32fSAdrian Hunterdo_query(query, 'CREATE TABLE dsos ('
114*2987e32fSAdrian Hunter		'id		bigint		NOT NULL,'
115*2987e32fSAdrian Hunter		'machine_id	bigint,'
116*2987e32fSAdrian Hunter		'short_name	varchar(256),'
117*2987e32fSAdrian Hunter		'long_name	varchar(4096),'
118*2987e32fSAdrian Hunter		'build_id	varchar(64))')
119*2987e32fSAdrian Hunterdo_query(query, 'CREATE TABLE symbols ('
120*2987e32fSAdrian Hunter		'id		bigint		NOT NULL,'
121*2987e32fSAdrian Hunter		'dso_id		bigint,'
122*2987e32fSAdrian Hunter		'sym_start	bigint,'
123*2987e32fSAdrian Hunter		'sym_end	bigint,'
124*2987e32fSAdrian Hunter		'binding	integer,'
125*2987e32fSAdrian Hunter		'name		varchar(2048))')
126*2987e32fSAdrian Hunterif branches:
127*2987e32fSAdrian Hunter	do_query(query, 'CREATE TABLE samples ('
128*2987e32fSAdrian Hunter		'id		bigint		NOT NULL,'
129*2987e32fSAdrian Hunter		'evsel_id	bigint,'
130*2987e32fSAdrian Hunter		'machine_id	bigint,'
131*2987e32fSAdrian Hunter		'thread_id	bigint,'
132*2987e32fSAdrian Hunter		'comm_id	bigint,'
133*2987e32fSAdrian Hunter		'dso_id		bigint,'
134*2987e32fSAdrian Hunter		'symbol_id	bigint,'
135*2987e32fSAdrian Hunter		'sym_offset	bigint,'
136*2987e32fSAdrian Hunter		'ip		bigint,'
137*2987e32fSAdrian Hunter		'time		bigint,'
138*2987e32fSAdrian Hunter		'cpu		integer,'
139*2987e32fSAdrian Hunter		'to_dso_id	bigint,'
140*2987e32fSAdrian Hunter		'to_symbol_id	bigint,'
141*2987e32fSAdrian Hunter		'to_sym_offset	bigint,'
142*2987e32fSAdrian Hunter		'to_ip		bigint)')
143*2987e32fSAdrian Hunterelse:
144*2987e32fSAdrian Hunter	do_query(query, 'CREATE TABLE samples ('
145*2987e32fSAdrian Hunter		'id		bigint		NOT NULL,'
146*2987e32fSAdrian Hunter		'evsel_id	bigint,'
147*2987e32fSAdrian Hunter		'machine_id	bigint,'
148*2987e32fSAdrian Hunter		'thread_id	bigint,'
149*2987e32fSAdrian Hunter		'comm_id	bigint,'
150*2987e32fSAdrian Hunter		'dso_id		bigint,'
151*2987e32fSAdrian Hunter		'symbol_id	bigint,'
152*2987e32fSAdrian Hunter		'sym_offset	bigint,'
153*2987e32fSAdrian Hunter		'ip		bigint,'
154*2987e32fSAdrian Hunter		'time		bigint,'
155*2987e32fSAdrian Hunter		'cpu		integer,'
156*2987e32fSAdrian Hunter		'to_dso_id	bigint,'
157*2987e32fSAdrian Hunter		'to_symbol_id	bigint,'
158*2987e32fSAdrian Hunter		'to_sym_offset	bigint,'
159*2987e32fSAdrian Hunter		'to_ip		bigint,'
160*2987e32fSAdrian Hunter		'period		bigint,'
161*2987e32fSAdrian Hunter		'weight		bigint,'
162*2987e32fSAdrian Hunter		'transaction	bigint,'
163*2987e32fSAdrian Hunter		'data_src	bigint)')
164*2987e32fSAdrian Hunter
165*2987e32fSAdrian Hunterdo_query(query, 'CREATE VIEW samples_view AS '
166*2987e32fSAdrian Hunter	'SELECT '
167*2987e32fSAdrian Hunter		'id,'
168*2987e32fSAdrian Hunter		'time,'
169*2987e32fSAdrian Hunter		'cpu,'
170*2987e32fSAdrian Hunter		'(SELECT pid FROM threads WHERE id = thread_id) AS pid,'
171*2987e32fSAdrian Hunter		'(SELECT tid FROM threads WHERE id = thread_id) AS tid,'
172*2987e32fSAdrian Hunter		'(SELECT comm FROM comms WHERE id = comm_id) AS command,'
173*2987e32fSAdrian Hunter		'(SELECT name FROM selected_events WHERE id = evsel_id) AS event,'
174*2987e32fSAdrian Hunter		'to_hex(ip) AS ip_hex,'
175*2987e32fSAdrian Hunter		'(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,'
176*2987e32fSAdrian Hunter		'sym_offset,'
177*2987e32fSAdrian Hunter		'(SELECT short_name FROM dsos WHERE id = dso_id) AS dso_short_name,'
178*2987e32fSAdrian Hunter		'to_hex(to_ip) AS to_ip_hex,'
179*2987e32fSAdrian Hunter		'(SELECT name FROM symbols WHERE id = to_symbol_id) AS to_symbol,'
180*2987e32fSAdrian Hunter		'to_sym_offset,'
181*2987e32fSAdrian Hunter		'(SELECT short_name FROM dsos WHERE id = to_dso_id) AS to_dso_short_name'
182*2987e32fSAdrian Hunter	' FROM samples')
183*2987e32fSAdrian Hunter
184*2987e32fSAdrian Hunter
185*2987e32fSAdrian Hunterfile_header = struct.pack("!11sii", "PGCOPY\n\377\r\n\0", 0, 0)
186*2987e32fSAdrian Hunterfile_trailer = "\377\377"
187*2987e32fSAdrian Hunter
188*2987e32fSAdrian Hunterdef open_output_file(file_name):
189*2987e32fSAdrian Hunter	path_name = output_dir_name + "/" + file_name
190*2987e32fSAdrian Hunter	file = open(path_name, "w+")
191*2987e32fSAdrian Hunter	file.write(file_header)
192*2987e32fSAdrian Hunter	return file
193*2987e32fSAdrian Hunter
194*2987e32fSAdrian Hunterdef close_output_file(file):
195*2987e32fSAdrian Hunter	file.write(file_trailer)
196*2987e32fSAdrian Hunter	file.close()
197*2987e32fSAdrian Hunter
198*2987e32fSAdrian Hunterdef copy_output_file_direct(file, table_name):
199*2987e32fSAdrian Hunter	close_output_file(file)
200*2987e32fSAdrian Hunter	sql = "COPY " + table_name + " FROM '" + file.name + "' (FORMAT 'binary')"
201*2987e32fSAdrian Hunter	do_query(query, sql)
202*2987e32fSAdrian Hunter
203*2987e32fSAdrian Hunter# Use COPY FROM STDIN because security may prevent postgres from accessing the files directly
204*2987e32fSAdrian Hunterdef copy_output_file(file, table_name):
205*2987e32fSAdrian Hunter	conn = PQconnectdb("dbname = " + dbname)
206*2987e32fSAdrian Hunter	if (PQstatus(conn)):
207*2987e32fSAdrian Hunter		raise Exception("COPY FROM STDIN PQconnectdb failed")
208*2987e32fSAdrian Hunter	file.write(file_trailer)
209*2987e32fSAdrian Hunter	file.seek(0)
210*2987e32fSAdrian Hunter	sql = "COPY " + table_name + " FROM STDIN (FORMAT 'binary')"
211*2987e32fSAdrian Hunter	res = PQexec(conn, sql)
212*2987e32fSAdrian Hunter	if (PQresultStatus(res) != 4):
213*2987e32fSAdrian Hunter		raise Exception("COPY FROM STDIN PQexec failed")
214*2987e32fSAdrian Hunter	data = file.read(65536)
215*2987e32fSAdrian Hunter	while (len(data)):
216*2987e32fSAdrian Hunter		ret = PQputCopyData(conn, data, len(data))
217*2987e32fSAdrian Hunter		if (ret != 1):
218*2987e32fSAdrian Hunter			raise Exception("COPY FROM STDIN PQputCopyData failed, error " + str(ret))
219*2987e32fSAdrian Hunter		data = file.read(65536)
220*2987e32fSAdrian Hunter	ret = PQputCopyEnd(conn, None)
221*2987e32fSAdrian Hunter	if (ret != 1):
222*2987e32fSAdrian Hunter		raise Exception("COPY FROM STDIN PQputCopyEnd failed, error " + str(ret))
223*2987e32fSAdrian Hunter	PQfinish(conn)
224*2987e32fSAdrian Hunter
225*2987e32fSAdrian Hunterdef remove_output_file(file):
226*2987e32fSAdrian Hunter	name = file.name
227*2987e32fSAdrian Hunter	file.close()
228*2987e32fSAdrian Hunter	os.unlink(name)
229*2987e32fSAdrian Hunter
230*2987e32fSAdrian Hunterevsel_file		= open_output_file("evsel_table.bin")
231*2987e32fSAdrian Huntermachine_file		= open_output_file("machine_table.bin")
232*2987e32fSAdrian Hunterthread_file		= open_output_file("thread_table.bin")
233*2987e32fSAdrian Huntercomm_file		= open_output_file("comm_table.bin")
234*2987e32fSAdrian Huntercomm_thread_file	= open_output_file("comm_thread_table.bin")
235*2987e32fSAdrian Hunterdso_file		= open_output_file("dso_table.bin")
236*2987e32fSAdrian Huntersymbol_file		= open_output_file("symbol_table.bin")
237*2987e32fSAdrian Huntersample_file		= open_output_file("sample_table.bin")
238*2987e32fSAdrian Hunter
239*2987e32fSAdrian Hunterdef trace_begin():
240*2987e32fSAdrian Hunter	print datetime.datetime.today(), "Writing to intermediate files..."
241*2987e32fSAdrian Hunter	# id == 0 means unknown.  It is easier to create records for them than replace the zeroes with NULLs
242*2987e32fSAdrian Hunter	evsel_table(0, "unknown")
243*2987e32fSAdrian Hunter	machine_table(0, 0, "unknown")
244*2987e32fSAdrian Hunter	thread_table(0, 0, 0, -1, -1)
245*2987e32fSAdrian Hunter	comm_table(0, "unknown")
246*2987e32fSAdrian Hunter	dso_table(0, 0, "unknown", "unknown", "")
247*2987e32fSAdrian Hunter	symbol_table(0, 0, 0, 0, 0, "unknown")
248*2987e32fSAdrian Hunter
249*2987e32fSAdrian Hunterunhandled_count = 0
250*2987e32fSAdrian Hunter
251*2987e32fSAdrian Hunterdef trace_end():
252*2987e32fSAdrian Hunter	print datetime.datetime.today(), "Copying to database..."
253*2987e32fSAdrian Hunter	copy_output_file(evsel_file,		"selected_events")
254*2987e32fSAdrian Hunter	copy_output_file(machine_file,		"machines")
255*2987e32fSAdrian Hunter	copy_output_file(thread_file,		"threads")
256*2987e32fSAdrian Hunter	copy_output_file(comm_file,		"comms")
257*2987e32fSAdrian Hunter	copy_output_file(comm_thread_file,	"comm_threads")
258*2987e32fSAdrian Hunter	copy_output_file(dso_file,		"dsos")
259*2987e32fSAdrian Hunter	copy_output_file(symbol_file,		"symbols")
260*2987e32fSAdrian Hunter	copy_output_file(sample_file,		"samples")
261*2987e32fSAdrian Hunter
262*2987e32fSAdrian Hunter	print datetime.datetime.today(), "Removing intermediate files..."
263*2987e32fSAdrian Hunter	remove_output_file(evsel_file)
264*2987e32fSAdrian Hunter	remove_output_file(machine_file)
265*2987e32fSAdrian Hunter	remove_output_file(thread_file)
266*2987e32fSAdrian Hunter	remove_output_file(comm_file)
267*2987e32fSAdrian Hunter	remove_output_file(comm_thread_file)
268*2987e32fSAdrian Hunter	remove_output_file(dso_file)
269*2987e32fSAdrian Hunter	remove_output_file(symbol_file)
270*2987e32fSAdrian Hunter	remove_output_file(sample_file)
271*2987e32fSAdrian Hunter	os.rmdir(output_dir_name)
272*2987e32fSAdrian Hunter	print datetime.datetime.today(), "Adding primary keys"
273*2987e32fSAdrian Hunter	do_query(query, 'ALTER TABLE selected_events ADD PRIMARY KEY (id)')
274*2987e32fSAdrian Hunter	do_query(query, 'ALTER TABLE machines        ADD PRIMARY KEY (id)')
275*2987e32fSAdrian Hunter	do_query(query, 'ALTER TABLE threads         ADD PRIMARY KEY (id)')
276*2987e32fSAdrian Hunter	do_query(query, 'ALTER TABLE comms           ADD PRIMARY KEY (id)')
277*2987e32fSAdrian Hunter	do_query(query, 'ALTER TABLE comm_threads    ADD PRIMARY KEY (id)')
278*2987e32fSAdrian Hunter	do_query(query, 'ALTER TABLE dsos            ADD PRIMARY KEY (id)')
279*2987e32fSAdrian Hunter	do_query(query, 'ALTER TABLE symbols         ADD PRIMARY KEY (id)')
280*2987e32fSAdrian Hunter	do_query(query, 'ALTER TABLE samples         ADD PRIMARY KEY (id)')
281*2987e32fSAdrian Hunter
282*2987e32fSAdrian Hunter	print datetime.datetime.today(), "Adding foreign keys"
283*2987e32fSAdrian Hunter	do_query(query, 'ALTER TABLE threads '
284*2987e32fSAdrian Hunter					'ADD CONSTRAINT machinefk  FOREIGN KEY (machine_id)   REFERENCES machines   (id),'
285*2987e32fSAdrian Hunter					'ADD CONSTRAINT processfk  FOREIGN KEY (process_id)   REFERENCES threads    (id)')
286*2987e32fSAdrian Hunter	do_query(query, 'ALTER TABLE comm_threads '
287*2987e32fSAdrian Hunter					'ADD CONSTRAINT commfk     FOREIGN KEY (comm_id)      REFERENCES comms      (id),'
288*2987e32fSAdrian Hunter					'ADD CONSTRAINT threadfk   FOREIGN KEY (thread_id)    REFERENCES threads    (id)')
289*2987e32fSAdrian Hunter	do_query(query, 'ALTER TABLE dsos '
290*2987e32fSAdrian Hunter					'ADD CONSTRAINT machinefk  FOREIGN KEY (machine_id)   REFERENCES machines   (id)')
291*2987e32fSAdrian Hunter	do_query(query, 'ALTER TABLE symbols '
292*2987e32fSAdrian Hunter					'ADD CONSTRAINT dsofk      FOREIGN KEY (dso_id)       REFERENCES dsos       (id)')
293*2987e32fSAdrian Hunter	do_query(query, 'ALTER TABLE samples '
294*2987e32fSAdrian Hunter					'ADD CONSTRAINT evselfk    FOREIGN KEY (evsel_id)     REFERENCES selected_events (id),'
295*2987e32fSAdrian Hunter					'ADD CONSTRAINT machinefk  FOREIGN KEY (machine_id)   REFERENCES machines   (id),'
296*2987e32fSAdrian Hunter					'ADD CONSTRAINT threadfk   FOREIGN KEY (thread_id)    REFERENCES threads    (id),'
297*2987e32fSAdrian Hunter					'ADD CONSTRAINT commfk     FOREIGN KEY (comm_id)      REFERENCES comms      (id),'
298*2987e32fSAdrian Hunter					'ADD CONSTRAINT dsofk      FOREIGN KEY (dso_id)       REFERENCES dsos       (id),'
299*2987e32fSAdrian Hunter					'ADD CONSTRAINT symbolfk   FOREIGN KEY (symbol_id)    REFERENCES symbols    (id),'
300*2987e32fSAdrian Hunter					'ADD CONSTRAINT todsofk    FOREIGN KEY (to_dso_id)    REFERENCES dsos       (id),'
301*2987e32fSAdrian Hunter					'ADD CONSTRAINT tosymbolfk FOREIGN KEY (to_symbol_id) REFERENCES symbols    (id)')
302*2987e32fSAdrian Hunter
303*2987e32fSAdrian Hunter	if (unhandled_count):
304*2987e32fSAdrian Hunter		print datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events"
305*2987e32fSAdrian Hunter	print datetime.datetime.today(), "Done"
306*2987e32fSAdrian Hunter
307*2987e32fSAdrian Hunterdef trace_unhandled(event_name, context, event_fields_dict):
308*2987e32fSAdrian Hunter	global unhandled_count
309*2987e32fSAdrian Hunter	unhandled_count += 1
310*2987e32fSAdrian Hunter
311*2987e32fSAdrian Hunterdef sched__sched_switch(*x):
312*2987e32fSAdrian Hunter	pass
313*2987e32fSAdrian Hunter
314*2987e32fSAdrian Hunterdef evsel_table(evsel_id, evsel_name, *x):
315*2987e32fSAdrian Hunter	n = len(evsel_name)
316*2987e32fSAdrian Hunter	fmt = "!hiqi" + str(n) + "s"
317*2987e32fSAdrian Hunter	value = struct.pack(fmt, 2, 8, evsel_id, n, evsel_name)
318*2987e32fSAdrian Hunter	evsel_file.write(value)
319*2987e32fSAdrian Hunter
320*2987e32fSAdrian Hunterdef machine_table(machine_id, pid, root_dir, *x):
321*2987e32fSAdrian Hunter	n = len(root_dir)
322*2987e32fSAdrian Hunter	fmt = "!hiqiii" + str(n) + "s"
323*2987e32fSAdrian Hunter	value = struct.pack(fmt, 3, 8, machine_id, 4, pid, n, root_dir)
324*2987e32fSAdrian Hunter	machine_file.write(value)
325*2987e32fSAdrian Hunter
326*2987e32fSAdrian Hunterdef thread_table(thread_id, machine_id, process_id, pid, tid, *x):
327*2987e32fSAdrian Hunter	value = struct.pack("!hiqiqiqiiii", 5, 8, thread_id, 8, machine_id, 8, process_id, 4, pid, 4, tid)
328*2987e32fSAdrian Hunter	thread_file.write(value)
329*2987e32fSAdrian Hunter
330*2987e32fSAdrian Hunterdef comm_table(comm_id, comm_str, *x):
331*2987e32fSAdrian Hunter	n = len(comm_str)
332*2987e32fSAdrian Hunter	fmt = "!hiqi" + str(n) + "s"
333*2987e32fSAdrian Hunter	value = struct.pack(fmt, 2, 8, comm_id, n, comm_str)
334*2987e32fSAdrian Hunter	comm_file.write(value)
335*2987e32fSAdrian Hunter
336*2987e32fSAdrian Hunterdef comm_thread_table(comm_thread_id, comm_id, thread_id, *x):
337*2987e32fSAdrian Hunter	fmt = "!hiqiqiq"
338*2987e32fSAdrian Hunter	value = struct.pack(fmt, 3, 8, comm_thread_id, 8, comm_id, 8, thread_id)
339*2987e32fSAdrian Hunter	comm_thread_file.write(value)
340*2987e32fSAdrian Hunter
341*2987e32fSAdrian Hunterdef dso_table(dso_id, machine_id, short_name, long_name, build_id, *x):
342*2987e32fSAdrian Hunter	n1 = len(short_name)
343*2987e32fSAdrian Hunter	n2 = len(long_name)
344*2987e32fSAdrian Hunter	n3 = len(build_id)
345*2987e32fSAdrian Hunter	fmt = "!hiqiqi" + str(n1) + "si"  + str(n2) + "si" + str(n3) + "s"
346*2987e32fSAdrian Hunter	value = struct.pack(fmt, 5, 8, dso_id, 8, machine_id, n1, short_name, n2, long_name, n3, build_id)
347*2987e32fSAdrian Hunter	dso_file.write(value)
348*2987e32fSAdrian Hunter
349*2987e32fSAdrian Hunterdef symbol_table(symbol_id, dso_id, sym_start, sym_end, binding, symbol_name, *x):
350*2987e32fSAdrian Hunter	n = len(symbol_name)
351*2987e32fSAdrian Hunter	fmt = "!hiqiqiqiqiii" + str(n) + "s"
352*2987e32fSAdrian Hunter	value = struct.pack(fmt, 6, 8, symbol_id, 8, dso_id, 8, sym_start, 8, sym_end, 4, binding, n, symbol_name)
353*2987e32fSAdrian Hunter	symbol_file.write(value)
354*2987e32fSAdrian Hunter
355*2987e32fSAdrian Hunterdef sample_table(sample_id, evsel_id, machine_id, thread_id, comm_id, dso_id, symbol_id, sym_offset, ip, time, cpu, to_dso_id, to_symbol_id, to_sym_offset, to_ip, period, weight, transaction, data_src, *x):
356*2987e32fSAdrian Hunter	if branches:
357*2987e32fSAdrian Hunter		value = struct.pack("!hiqiqiqiqiqiqiqiqiqiqiiiqiqiqiq", 15, 8, sample_id, 8, evsel_id, 8, machine_id, 8, thread_id, 8, comm_id, 8, dso_id, 8, symbol_id, 8, sym_offset, 8, ip, 8, time, 4, cpu, 8, to_dso_id, 8, to_symbol_id, 8, to_sym_offset, 8, to_ip)
358*2987e32fSAdrian Hunter	else:
359*2987e32fSAdrian Hunter		value = struct.pack("!hiqiqiqiqiqiqiqiqiqiqiiiqiqiqiqiqiqiqiq", 19, 8, sample_id, 8, evsel_id, 8, machine_id, 8, thread_id, 8, comm_id, 8, dso_id, 8, symbol_id, 8, sym_offset, 8, ip, 8, time, 4, cpu, 8, to_dso_id, 8, to_symbol_id, 8, to_sym_offset, 8, to_ip, 8, period, 8, weight, 8, transaction, 8, data_src)
360*2987e32fSAdrian Hunter	sample_file.write(value)
361