brintos

brintos / linux-shallow public Read only

0
0
Text · 24.1 KiB · 73c992f Raw
800 lines · python
1# export-to-sqlite.py: export perf data to a sqlite3 database2# Copyright (c) 2017, Intel Corporation.3#4# This program is free software; you can redistribute it and/or modify it5# under the terms and conditions of the GNU General Public License,6# version 2, as published by the Free Software Foundation.7#8# This program is distributed in the hope it will be useful, but WITHOUT9# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for11# more details.12 13from __future__ import print_function14 15import os16import sys17import struct18import datetime19 20# To use this script you will need to have installed package python-pyside which21# provides LGPL-licensed Python bindings for Qt.  You will also need the package22# libqt4-sql-sqlite for Qt sqlite3 support.23#24# Examples of installing pyside:25#26# ubuntu:27#28#	$ sudo apt-get install python-pyside.qtsql libqt4-sql-psql29#30#	Alternately, to use Python3 and/or pyside 2, one of the following:31#32#		$ sudo apt-get install python3-pyside.qtsql libqt4-sql-psql33#		$ sudo apt-get install python-pyside2.qtsql libqt5sql5-psql34#		$ sudo apt-get install python3-pyside2.qtsql libqt5sql5-psql35# fedora:36#37#	$ sudo yum install python-pyside38#39#	Alternately, to use Python3 and/or pyside 2, one of the following:40#		$ sudo yum install python3-pyside41#		$ pip install --user PySide242#		$ pip3 install --user PySide243#44# An example of using this script with Intel PT:45#46#	$ perf record -e intel_pt//u ls47#	$ perf script -s ~/libexec/perf-core/scripts/python/export-to-sqlite.py pt_example branches calls48#	2017-07-31 14:26:07.326913 Creating database...49#	2017-07-31 14:26:07.538097 Writing records...50#	2017-07-31 14:26:09.889292 Adding indexes51#	2017-07-31 14:26:09.958746 Done52#53# To browse the database, sqlite3 can be used e.g.54#55#	$ sqlite3 pt_example56#	sqlite> .header on57#	sqlite> select * from samples_view where id < 10;58#	sqlite> .mode column59#	sqlite> select * from samples_view where id < 10;60#	sqlite> .tables61#	sqlite> .schema samples_view62#	sqlite> .quit63#64# An example of using the database is provided by the script65# exported-sql-viewer.py.  Refer to that script for details.66#67# The database structure is practically the same as created by the script68# export-to-postgresql.py. Refer to that script for details.  A notable69# difference is  the 'transaction' column of the 'samples' table which is70# renamed 'transaction_' in sqlite because 'transaction' is a reserved word.71 72pyside_version_1 = True73if not "pyside-version-1" in sys.argv:74	try:75		from PySide2.QtSql import *76		pyside_version_1 = False77	except:78		pass79 80if pyside_version_1:81	from PySide.QtSql import *82 83sys.path.append(os.environ['PERF_EXEC_PATH'] + \84	'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')85 86# These perf imports are not used at present87#from perf_trace_context import *88#from Core import *89 90perf_db_export_mode = True91perf_db_export_calls = False92perf_db_export_callchains = False93 94def printerr(*args, **keyword_args):95	print(*args, file=sys.stderr, **keyword_args)96 97def printdate(*args, **kw_args):98        print(datetime.datetime.today(), *args, sep=' ', **kw_args)99 100def usage():101	printerr("Usage is: export-to-sqlite.py <database name> [<columns>] [<calls>] [<callchains>] [<pyside-version-1>]");102	printerr("where:  columns            'all' or 'branches'");103	printerr("        calls              'calls' => create calls and call_paths table");104	printerr("        callchains         'callchains' => create call_paths table");105	printerr("        pyside-version-1   'pyside-version-1' => use pyside version 1");106	raise Exception("Too few or bad arguments")107 108if (len(sys.argv) < 2):109	usage()110 111dbname = sys.argv[1]112 113if (len(sys.argv) >= 3):114	columns = sys.argv[2]115else:116	columns = "all"117 118if columns not in ("all", "branches"):119	usage()120 121branches = (columns == "branches")122 123for i in range(3,len(sys.argv)):124	if (sys.argv[i] == "calls"):125		perf_db_export_calls = True126	elif (sys.argv[i] == "callchains"):127		perf_db_export_callchains = True128	elif (sys.argv[i] == "pyside-version-1"):129		pass130	else:131		usage()132 133def do_query(q, s):134	if (q.exec_(s)):135		return136	raise Exception("Query failed: " + q.lastError().text())137 138def do_query_(q):139	if (q.exec_()):140		return141	raise Exception("Query failed: " + q.lastError().text())142 143printdate("Creating database ...")144 145db_exists = False146try:147	f = open(dbname)148	f.close()149	db_exists = True150except:151	pass152 153if db_exists:154	raise Exception(dbname + " already exists")155 156db = QSqlDatabase.addDatabase('QSQLITE')157db.setDatabaseName(dbname)158db.open()159 160query = QSqlQuery(db)161 162do_query(query, 'PRAGMA journal_mode = OFF')163do_query(query, 'BEGIN TRANSACTION')164 165do_query(query, 'CREATE TABLE selected_events ('166		'id		integer		NOT NULL	PRIMARY KEY,'167		'name		varchar(80))')168do_query(query, 'CREATE TABLE machines ('169		'id		integer		NOT NULL	PRIMARY KEY,'170		'pid		integer,'171		'root_dir 	varchar(4096))')172do_query(query, 'CREATE TABLE threads ('173		'id		integer		NOT NULL	PRIMARY KEY,'174		'machine_id	bigint,'175		'process_id	bigint,'176		'pid		integer,'177		'tid		integer)')178do_query(query, 'CREATE TABLE comms ('179		'id		integer		NOT NULL	PRIMARY KEY,'180		'comm		varchar(16),'181		'c_thread_id	bigint,'182		'c_time		bigint,'183		'exec_flag	boolean)')184do_query(query, 'CREATE TABLE comm_threads ('185		'id		integer		NOT NULL	PRIMARY KEY,'186		'comm_id	bigint,'187		'thread_id	bigint)')188do_query(query, 'CREATE TABLE dsos ('189		'id		integer		NOT NULL	PRIMARY KEY,'190		'machine_id	bigint,'191		'short_name	varchar(256),'192		'long_name	varchar(4096),'193		'build_id	varchar(64))')194do_query(query, 'CREATE TABLE symbols ('195		'id		integer		NOT NULL	PRIMARY KEY,'196		'dso_id		bigint,'197		'sym_start	bigint,'198		'sym_end	bigint,'199		'binding	integer,'200		'name		varchar(2048))')201do_query(query, 'CREATE TABLE branch_types ('202		'id		integer		NOT NULL	PRIMARY KEY,'203		'name		varchar(80))')204 205if branches:206	do_query(query, 'CREATE TABLE samples ('207		'id		integer		NOT NULL	PRIMARY KEY,'208		'evsel_id	bigint,'209		'machine_id	bigint,'210		'thread_id	bigint,'211		'comm_id	bigint,'212		'dso_id		bigint,'213		'symbol_id	bigint,'214		'sym_offset	bigint,'215		'ip		bigint,'216		'time		bigint,'217		'cpu		integer,'218		'to_dso_id	bigint,'219		'to_symbol_id	bigint,'220		'to_sym_offset	bigint,'221		'to_ip		bigint,'222		'branch_type	integer,'223		'in_tx		boolean,'224		'call_path_id	bigint,'225		'insn_count	bigint,'226		'cyc_count	bigint,'227		'flags		integer)')228else:229	do_query(query, 'CREATE TABLE samples ('230		'id		integer		NOT NULL	PRIMARY KEY,'231		'evsel_id	bigint,'232		'machine_id	bigint,'233		'thread_id	bigint,'234		'comm_id	bigint,'235		'dso_id		bigint,'236		'symbol_id	bigint,'237		'sym_offset	bigint,'238		'ip		bigint,'239		'time		bigint,'240		'cpu		integer,'241		'to_dso_id	bigint,'242		'to_symbol_id	bigint,'243		'to_sym_offset	bigint,'244		'to_ip		bigint,'245		'period		bigint,'246		'weight		bigint,'247		'transaction_	bigint,'248		'data_src	bigint,'249		'branch_type	integer,'250		'in_tx		boolean,'251		'call_path_id	bigint,'252		'insn_count	bigint,'253		'cyc_count	bigint,'254		'flags		integer)')255 256if perf_db_export_calls or perf_db_export_callchains:257	do_query(query, 'CREATE TABLE call_paths ('258		'id		integer		NOT NULL	PRIMARY KEY,'259		'parent_id	bigint,'260		'symbol_id	bigint,'261		'ip		bigint)')262if perf_db_export_calls:263	do_query(query, 'CREATE TABLE calls ('264		'id		integer		NOT NULL	PRIMARY KEY,'265		'thread_id	bigint,'266		'comm_id	bigint,'267		'call_path_id	bigint,'268		'call_time	bigint,'269		'return_time	bigint,'270		'branch_count	bigint,'271		'call_id	bigint,'272		'return_id	bigint,'273		'parent_call_path_id	bigint,'274		'flags		integer,'275		'parent_id	bigint,'276		'insn_count	bigint,'277		'cyc_count	bigint)')278 279do_query(query, 'CREATE TABLE ptwrite ('280		'id		integer		NOT NULL	PRIMARY KEY,'281		'payload	bigint,'282		'exact_ip	integer)')283 284do_query(query, 'CREATE TABLE cbr ('285		'id		integer		NOT NULL	PRIMARY KEY,'286		'cbr		integer,'287		'mhz		integer,'288		'percent	integer)')289 290do_query(query, 'CREATE TABLE mwait ('291		'id		integer		NOT NULL	PRIMARY KEY,'292		'hints		integer,'293		'extensions	integer)')294 295do_query(query, 'CREATE TABLE pwre ('296		'id		integer		NOT NULL	PRIMARY KEY,'297		'cstate		integer,'298		'subcstate	integer,'299		'hw		integer)')300 301do_query(query, 'CREATE TABLE exstop ('302		'id		integer		NOT NULL	PRIMARY KEY,'303		'exact_ip	integer)')304 305do_query(query, 'CREATE TABLE pwrx ('306		'id		integer		NOT NULL	PRIMARY KEY,'307		'deepest_cstate	integer,'308		'last_cstate	integer,'309		'wake_reason	integer)')310 311do_query(query, 'CREATE TABLE context_switches ('312		'id		integer		NOT NULL	PRIMARY KEY,'313		'machine_id	bigint,'314		'time		bigint,'315		'cpu		integer,'316		'thread_out_id	bigint,'317		'comm_out_id	bigint,'318		'thread_in_id	bigint,'319		'comm_in_id	bigint,'320		'flags		integer)')321 322# printf was added to sqlite in version 3.8.3323sqlite_has_printf = False324try:325	do_query(query, 'SELECT printf("") FROM machines')326	sqlite_has_printf = True327except:328	pass329 330def emit_to_hex(x):331	if sqlite_has_printf:332		return 'printf("%x", ' + x + ')'333	else:334		return x335 336do_query(query, 'CREATE VIEW machines_view AS '337	'SELECT '338		'id,'339		'pid,'340		'root_dir,'341		'CASE WHEN id=0 THEN \'unknown\' WHEN pid=-1 THEN \'host\' ELSE \'guest\' END AS host_or_guest'342	' FROM machines')343 344do_query(query, 'CREATE VIEW dsos_view AS '345	'SELECT '346		'id,'347		'machine_id,'348		'(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,'349		'short_name,'350		'long_name,'351		'build_id'352	' FROM dsos')353 354do_query(query, 'CREATE VIEW symbols_view AS '355	'SELECT '356		'id,'357		'name,'358		'(SELECT short_name FROM dsos WHERE id=dso_id) AS dso,'359		'dso_id,'360		'sym_start,'361		'sym_end,'362		'CASE WHEN binding=0 THEN \'local\' WHEN binding=1 THEN \'global\' ELSE \'weak\' END AS binding'363	' FROM symbols')364 365do_query(query, 'CREATE VIEW threads_view AS '366	'SELECT '367		'id,'368		'machine_id,'369		'(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,'370		'process_id,'371		'pid,'372		'tid'373	' FROM threads')374 375do_query(query, 'CREATE VIEW comm_threads_view AS '376	'SELECT '377		'comm_id,'378		'(SELECT comm FROM comms WHERE id = comm_id) AS command,'379		'thread_id,'380		'(SELECT pid FROM threads WHERE id = thread_id) AS pid,'381		'(SELECT tid FROM threads WHERE id = thread_id) AS tid'382	' FROM comm_threads')383 384if perf_db_export_calls or perf_db_export_callchains:385	do_query(query, 'CREATE VIEW call_paths_view AS '386		'SELECT '387			'c.id,'388			+ emit_to_hex('c.ip') + ' AS ip,'389			'c.symbol_id,'390			'(SELECT name FROM symbols WHERE id = c.symbol_id) AS symbol,'391			'(SELECT dso_id FROM symbols WHERE id = c.symbol_id) AS dso_id,'392			'(SELECT dso FROM symbols_view  WHERE id = c.symbol_id) AS dso_short_name,'393			'c.parent_id,'394			+ emit_to_hex('p.ip') + ' AS parent_ip,'395			'p.symbol_id AS parent_symbol_id,'396			'(SELECT name FROM symbols WHERE id = p.symbol_id) AS parent_symbol,'397			'(SELECT dso_id FROM symbols WHERE id = p.symbol_id) AS parent_dso_id,'398			'(SELECT dso FROM symbols_view  WHERE id = p.symbol_id) AS parent_dso_short_name'399		' FROM call_paths c INNER JOIN call_paths p ON p.id = c.parent_id')400if perf_db_export_calls:401	do_query(query, 'CREATE VIEW calls_view AS '402		'SELECT '403			'calls.id,'404			'thread_id,'405			'(SELECT pid FROM threads WHERE id = thread_id) AS pid,'406			'(SELECT tid FROM threads WHERE id = thread_id) AS tid,'407			'(SELECT comm FROM comms WHERE id = comm_id) AS command,'408			'call_path_id,'409			+ emit_to_hex('ip') + ' AS ip,'410			'symbol_id,'411			'(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,'412			'call_time,'413			'return_time,'414			'return_time - call_time AS elapsed_time,'415			'branch_count,'416			'insn_count,'417			'cyc_count,'418			'CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC,'419			'call_id,'420			'return_id,'421			'CASE WHEN flags=0 THEN \'\' WHEN flags=1 THEN \'no call\' WHEN flags=2 THEN \'no return\' WHEN flags=3 THEN \'no call/return\' WHEN flags=6 THEN \'jump\' ELSE flags END AS flags,'422			'parent_call_path_id,'423			'calls.parent_id'424		' FROM calls INNER JOIN call_paths ON call_paths.id = call_path_id')425 426do_query(query, 'CREATE VIEW samples_view AS '427	'SELECT '428		'id,'429		'time,'430		'cpu,'431		'(SELECT pid FROM threads WHERE id = thread_id) AS pid,'432		'(SELECT tid FROM threads WHERE id = thread_id) AS tid,'433		'(SELECT comm FROM comms WHERE id = comm_id) AS command,'434		'(SELECT name FROM selected_events WHERE id = evsel_id) AS event,'435		+ emit_to_hex('ip') + ' AS ip_hex,'436		'(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,'437		'sym_offset,'438		'(SELECT short_name FROM dsos WHERE id = dso_id) AS dso_short_name,'439		+ emit_to_hex('to_ip') + ' AS to_ip_hex,'440		'(SELECT name FROM symbols WHERE id = to_symbol_id) AS to_symbol,'441		'to_sym_offset,'442		'(SELECT short_name FROM dsos WHERE id = to_dso_id) AS to_dso_short_name,'443		'(SELECT name FROM branch_types WHERE id = branch_type) AS branch_type_name,'444		'in_tx,'445		'insn_count,'446		'cyc_count,'447		'CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC,'448		'flags'449	' FROM samples')450 451do_query(query, 'CREATE VIEW ptwrite_view AS '452	'SELECT '453		'ptwrite.id,'454		'time,'455		'cpu,'456		+ emit_to_hex('payload') + ' AS payload_hex,'457		'CASE WHEN exact_ip=0 THEN \'False\' ELSE \'True\' END AS exact_ip'458	' FROM ptwrite'459	' INNER JOIN samples ON samples.id = ptwrite.id')460 461do_query(query, 'CREATE VIEW cbr_view AS '462	'SELECT '463		'cbr.id,'464		'time,'465		'cpu,'466		'cbr,'467		'mhz,'468		'percent'469	' FROM cbr'470	' INNER JOIN samples ON samples.id = cbr.id')471 472do_query(query, 'CREATE VIEW mwait_view AS '473	'SELECT '474		'mwait.id,'475		'time,'476		'cpu,'477		+ emit_to_hex('hints') + ' AS hints_hex,'478		+ emit_to_hex('extensions') + ' AS extensions_hex'479	' FROM mwait'480	' INNER JOIN samples ON samples.id = mwait.id')481 482do_query(query, 'CREATE VIEW pwre_view AS '483	'SELECT '484		'pwre.id,'485		'time,'486		'cpu,'487		'cstate,'488		'subcstate,'489		'CASE WHEN hw=0 THEN \'False\' ELSE \'True\' END AS hw'490	' FROM pwre'491	' INNER JOIN samples ON samples.id = pwre.id')492 493do_query(query, 'CREATE VIEW exstop_view AS '494	'SELECT '495		'exstop.id,'496		'time,'497		'cpu,'498		'CASE WHEN exact_ip=0 THEN \'False\' ELSE \'True\' END AS exact_ip'499	' FROM exstop'500	' INNER JOIN samples ON samples.id = exstop.id')501 502do_query(query, 'CREATE VIEW pwrx_view AS '503	'SELECT '504		'pwrx.id,'505		'time,'506		'cpu,'507		'deepest_cstate,'508		'last_cstate,'509		'CASE     WHEN wake_reason=1 THEN \'Interrupt\''510			' WHEN wake_reason=2 THEN \'Timer Deadline\''511			' WHEN wake_reason=4 THEN \'Monitored Address\''512			' WHEN wake_reason=8 THEN \'HW\''513			' ELSE wake_reason '514		'END AS wake_reason'515	' FROM pwrx'516	' INNER JOIN samples ON samples.id = pwrx.id')517 518do_query(query, 'CREATE VIEW power_events_view AS '519	'SELECT '520		'samples.id,'521		'time,'522		'cpu,'523		'selected_events.name AS event,'524		'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT cbr FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS cbr,'525		'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT mhz FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS mhz,'526		'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT percent FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS percent,'527		'CASE WHEN selected_events.name=\'mwait\' THEN (SELECT ' + emit_to_hex('hints') + ' FROM mwait WHERE mwait.id = samples.id) ELSE "" END AS hints_hex,'528		'CASE WHEN selected_events.name=\'mwait\' THEN (SELECT ' + emit_to_hex('extensions') + ' FROM mwait WHERE mwait.id = samples.id) ELSE "" END AS extensions_hex,'529		'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT cstate FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS cstate,'530		'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT subcstate FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS subcstate,'531		'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT hw FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS hw,'532		'CASE WHEN selected_events.name=\'exstop\' THEN (SELECT exact_ip FROM exstop WHERE exstop.id = samples.id) ELSE "" END AS exact_ip,'533		'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT deepest_cstate FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS deepest_cstate,'534		'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT last_cstate FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS last_cstate,'535		'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT '536			'CASE     WHEN wake_reason=1 THEN \'Interrupt\''537				' WHEN wake_reason=2 THEN \'Timer Deadline\''538				' WHEN wake_reason=4 THEN \'Monitored Address\''539				' WHEN wake_reason=8 THEN \'HW\''540				' ELSE wake_reason '541			'END'542		' FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS wake_reason'543	' FROM samples'544	' INNER JOIN selected_events ON selected_events.id = evsel_id'545	' WHERE selected_events.name IN (\'cbr\',\'mwait\',\'exstop\',\'pwre\',\'pwrx\')')546 547do_query(query, 'CREATE VIEW context_switches_view AS '548	'SELECT '549		'context_switches.id,'550		'context_switches.machine_id,'551		'context_switches.time,'552		'context_switches.cpu,'553		'th_out.pid AS pid_out,'554		'th_out.tid AS tid_out,'555		'comm_out.comm AS comm_out,'556		'th_in.pid AS pid_in,'557		'th_in.tid AS tid_in,'558		'comm_in.comm AS comm_in,'559		'CASE	  WHEN context_switches.flags = 0 THEN \'in\''560			' WHEN context_switches.flags = 1 THEN \'out\''561			' WHEN context_switches.flags = 3 THEN \'out preempt\''562			' ELSE context_switches.flags '563		'END AS flags'564	' FROM context_switches'565	' INNER JOIN threads AS th_out ON th_out.id   = context_switches.thread_out_id'566	' INNER JOIN threads AS th_in  ON th_in.id    = context_switches.thread_in_id'567	' INNER JOIN comms AS comm_out ON comm_out.id = context_switches.comm_out_id'568	' INNER JOIN comms AS comm_in  ON comm_in.id  = context_switches.comm_in_id')569 570do_query(query, 'END TRANSACTION')571 572evsel_query = QSqlQuery(db)573evsel_query.prepare("INSERT INTO selected_events VALUES (?, ?)")574machine_query = QSqlQuery(db)575machine_query.prepare("INSERT INTO machines VALUES (?, ?, ?)")576thread_query = QSqlQuery(db)577thread_query.prepare("INSERT INTO threads VALUES (?, ?, ?, ?, ?)")578comm_query = QSqlQuery(db)579comm_query.prepare("INSERT INTO comms VALUES (?, ?, ?, ?, ?)")580comm_thread_query = QSqlQuery(db)581comm_thread_query.prepare("INSERT INTO comm_threads VALUES (?, ?, ?)")582dso_query = QSqlQuery(db)583dso_query.prepare("INSERT INTO dsos VALUES (?, ?, ?, ?, ?)")584symbol_query = QSqlQuery(db)585symbol_query.prepare("INSERT INTO symbols VALUES (?, ?, ?, ?, ?, ?)")586branch_type_query = QSqlQuery(db)587branch_type_query.prepare("INSERT INTO branch_types VALUES (?, ?)")588sample_query = QSqlQuery(db)589if branches:590	sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")591else:592	sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")593if perf_db_export_calls or perf_db_export_callchains:594	call_path_query = QSqlQuery(db)595	call_path_query.prepare("INSERT INTO call_paths VALUES (?, ?, ?, ?)")596if perf_db_export_calls:597	call_query = QSqlQuery(db)598	call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")599ptwrite_query = QSqlQuery(db)600ptwrite_query.prepare("INSERT INTO ptwrite VALUES (?, ?, ?)")601cbr_query = QSqlQuery(db)602cbr_query.prepare("INSERT INTO cbr VALUES (?, ?, ?, ?)")603mwait_query = QSqlQuery(db)604mwait_query.prepare("INSERT INTO mwait VALUES (?, ?, ?)")605pwre_query = QSqlQuery(db)606pwre_query.prepare("INSERT INTO pwre VALUES (?, ?, ?, ?)")607exstop_query = QSqlQuery(db)608exstop_query.prepare("INSERT INTO exstop VALUES (?, ?)")609pwrx_query = QSqlQuery(db)610pwrx_query.prepare("INSERT INTO pwrx VALUES (?, ?, ?, ?)")611context_switch_query = QSqlQuery(db)612context_switch_query.prepare("INSERT INTO context_switches VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")613 614def trace_begin():615	printdate("Writing records...")616	do_query(query, 'BEGIN TRANSACTION')617	# id == 0 means unknown.  It is easier to create records for them than replace the zeroes with NULLs618	evsel_table(0, "unknown")619	machine_table(0, 0, "unknown")620	thread_table(0, 0, 0, -1, -1)621	comm_table(0, "unknown", 0, 0, 0)622	dso_table(0, 0, "unknown", "unknown", "")623	symbol_table(0, 0, 0, 0, 0, "unknown")624	sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)625	if perf_db_export_calls or perf_db_export_callchains:626		call_path_table(0, 0, 0, 0)627		call_return_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)628 629unhandled_count = 0630 631def is_table_empty(table_name):632	do_query(query, 'SELECT * FROM ' + table_name + ' LIMIT 1');633	if query.next():634		return False635	return True636 637def drop(table_name):638	do_query(query, 'DROP VIEW ' + table_name + '_view');639	do_query(query, 'DROP TABLE ' + table_name);640 641def trace_end():642	do_query(query, 'END TRANSACTION')643 644	printdate("Adding indexes")645	if perf_db_export_calls:646		do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)')647		do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)')648		do_query(query, 'ALTER TABLE comms ADD has_calls boolean')649		do_query(query, 'UPDATE comms SET has_calls = 1 WHERE comms.id IN (SELECT DISTINCT comm_id FROM calls)')650 651	printdate("Dropping unused tables")652	if is_table_empty("ptwrite"):653		drop("ptwrite")654	if is_table_empty("mwait") and is_table_empty("pwre") and is_table_empty("exstop") and is_table_empty("pwrx"):655		do_query(query, 'DROP VIEW power_events_view');656		drop("mwait")657		drop("pwre")658		drop("exstop")659		drop("pwrx")660		if is_table_empty("cbr"):661			drop("cbr")662	if is_table_empty("context_switches"):663		drop("context_switches")664 665	if (unhandled_count):666		printdate("Warning: ", unhandled_count, " unhandled events")667	printdate("Done")668 669def trace_unhandled(event_name, context, event_fields_dict):670	global unhandled_count671	unhandled_count += 1672 673def sched__sched_switch(*x):674	pass675 676def bind_exec(q, n, x):677	for xx in x[0:n]:678		q.addBindValue(str(xx))679	do_query_(q)680 681def evsel_table(*x):682	bind_exec(evsel_query, 2, x)683 684def machine_table(*x):685	bind_exec(machine_query, 3, x)686 687def thread_table(*x):688	bind_exec(thread_query, 5, x)689 690def comm_table(*x):691	bind_exec(comm_query, 5, x)692 693def comm_thread_table(*x):694	bind_exec(comm_thread_query, 3, x)695 696def dso_table(*x):697	bind_exec(dso_query, 5, x)698 699def symbol_table(*x):700	bind_exec(symbol_query, 6, x)701 702def branch_type_table(*x):703	bind_exec(branch_type_query, 2, x)704 705def sample_table(*x):706	if branches:707		for xx in x[0:15]:708			sample_query.addBindValue(str(xx))709		for xx in x[19:25]:710			sample_query.addBindValue(str(xx))711		do_query_(sample_query)712	else:713		bind_exec(sample_query, 25, x)714 715def call_path_table(*x):716	bind_exec(call_path_query, 4, x)717 718def call_return_table(*x):719	bind_exec(call_query, 14, x)720 721def ptwrite(id, raw_buf):722	data = struct.unpack_from("<IQ", raw_buf)723	flags = data[0]724	payload = data[1]725	exact_ip = flags & 1726	ptwrite_query.addBindValue(str(id))727	ptwrite_query.addBindValue(str(payload))728	ptwrite_query.addBindValue(str(exact_ip))729	do_query_(ptwrite_query)730 731def cbr(id, raw_buf):732	data = struct.unpack_from("<BBBBII", raw_buf)733	cbr = data[0]734	MHz = (data[4] + 500) / 1000735	percent = ((cbr * 1000 / data[2]) + 5) / 10736	cbr_query.addBindValue(str(id))737	cbr_query.addBindValue(str(cbr))738	cbr_query.addBindValue(str(MHz))739	cbr_query.addBindValue(str(percent))740	do_query_(cbr_query)741 742def mwait(id, raw_buf):743	data = struct.unpack_from("<IQ", raw_buf)744	payload = data[1]745	hints = payload & 0xff746	extensions = (payload >> 32) & 0x3747	mwait_query.addBindValue(str(id))748	mwait_query.addBindValue(str(hints))749	mwait_query.addBindValue(str(extensions))750	do_query_(mwait_query)751 752def pwre(id, raw_buf):753	data = struct.unpack_from("<IQ", raw_buf)754	payload = data[1]755	hw = (payload >> 7) & 1756	cstate = (payload >> 12) & 0xf757	subcstate = (payload >> 8) & 0xf758	pwre_query.addBindValue(str(id))759	pwre_query.addBindValue(str(cstate))760	pwre_query.addBindValue(str(subcstate))761	pwre_query.addBindValue(str(hw))762	do_query_(pwre_query)763 764def exstop(id, raw_buf):765	data = struct.unpack_from("<I", raw_buf)766	flags = data[0]767	exact_ip = flags & 1768	exstop_query.addBindValue(str(id))769	exstop_query.addBindValue(str(exact_ip))770	do_query_(exstop_query)771 772def pwrx(id, raw_buf):773	data = struct.unpack_from("<IQ", raw_buf)774	payload = data[1]775	deepest_cstate = payload & 0xf776	last_cstate = (payload >> 4) & 0xf777	wake_reason = (payload >> 8) & 0xf778	pwrx_query.addBindValue(str(id))779	pwrx_query.addBindValue(str(deepest_cstate))780	pwrx_query.addBindValue(str(last_cstate))781	pwrx_query.addBindValue(str(wake_reason))782	do_query_(pwrx_query)783 784def synth_data(id, config, raw_buf, *x):785	if config == 0:786		ptwrite(id, raw_buf)787	elif config == 1:788		mwait(id, raw_buf)789	elif config == 2:790		pwre(id, raw_buf)791	elif config == 3:792		exstop(id, raw_buf)793	elif config == 4:794		pwrx(id, raw_buf)795	elif config == 5:796		cbr(id, raw_buf)797 798def context_switch_table(*x):799	bind_exec(context_switch_query, 9, x)800