Back to home page

OSCL-LXR

 
 

    


0001 # export-to-sqlite.py: export perf data to a sqlite3 database
0002 # Copyright (c) 2017, Intel Corporation.
0003 #
0004 # This program is free software; you can redistribute it and/or modify it
0005 # under the terms and conditions of the GNU General Public License,
0006 # version 2, as published by the Free Software Foundation.
0007 #
0008 # This program is distributed in the hope it will be useful, but WITHOUT
0009 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0010 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
0011 # more details.
0012 
0013 from __future__ import print_function
0014 
0015 import os
0016 import sys
0017 import struct
0018 import datetime
0019 
0020 # To use this script you will need to have installed package python-pyside which
0021 # provides LGPL-licensed Python bindings for Qt.  You will also need the package
0022 # libqt4-sql-sqlite for Qt sqlite3 support.
0023 #
0024 # Examples of installing pyside:
0025 #
0026 # ubuntu:
0027 #
0028 #   $ sudo apt-get install python-pyside.qtsql libqt4-sql-psql
0029 #
0030 #   Alternately, to use Python3 and/or pyside 2, one of the following:
0031 #
0032 #       $ sudo apt-get install python3-pyside.qtsql libqt4-sql-psql
0033 #       $ sudo apt-get install python-pyside2.qtsql libqt5sql5-psql
0034 #       $ sudo apt-get install python3-pyside2.qtsql libqt5sql5-psql
0035 # fedora:
0036 #
0037 #   $ sudo yum install python-pyside
0038 #
0039 #   Alternately, to use Python3 and/or pyside 2, one of the following:
0040 #       $ sudo yum install python3-pyside
0041 #       $ pip install --user PySide2
0042 #       $ pip3 install --user PySide2
0043 #
0044 # An example of using this script with Intel PT:
0045 #
0046 #   $ perf record -e intel_pt//u ls
0047 #   $ perf script -s ~/libexec/perf-core/scripts/python/export-to-sqlite.py pt_example branches calls
0048 #   2017-07-31 14:26:07.326913 Creating database...
0049 #   2017-07-31 14:26:07.538097 Writing records...
0050 #   2017-07-31 14:26:09.889292 Adding indexes
0051 #   2017-07-31 14:26:09.958746 Done
0052 #
0053 # To browse the database, sqlite3 can be used e.g.
0054 #
0055 #   $ sqlite3 pt_example
0056 #   sqlite> .header on
0057 #   sqlite> select * from samples_view where id < 10;
0058 #   sqlite> .mode column
0059 #   sqlite> select * from samples_view where id < 10;
0060 #   sqlite> .tables
0061 #   sqlite> .schema samples_view
0062 #   sqlite> .quit
0063 #
0064 # An example of using the database is provided by the script
0065 # exported-sql-viewer.py.  Refer to that script for details.
0066 #
0067 # The database structure is practically the same as created by the script
0068 # export-to-postgresql.py. Refer to that script for details.  A notable
0069 # difference is  the 'transaction' column of the 'samples' table which is
0070 # renamed 'transaction_' in sqlite because 'transaction' is a reserved word.
0071 
0072 pyside_version_1 = True
0073 if not "pyside-version-1" in sys.argv:
0074     try:
0075         from PySide2.QtSql import *
0076         pyside_version_1 = False
0077     except:
0078         pass
0079 
0080 if pyside_version_1:
0081     from PySide.QtSql import *
0082 
0083 sys.path.append(os.environ['PERF_EXEC_PATH'] + \
0084     '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
0085 
0086 # These perf imports are not used at present
0087 #from perf_trace_context import *
0088 #from Core import *
0089 
0090 perf_db_export_mode = True
0091 perf_db_export_calls = False
0092 perf_db_export_callchains = False
0093 
0094 def printerr(*args, **keyword_args):
0095     print(*args, file=sys.stderr, **keyword_args)
0096 
0097 def printdate(*args, **kw_args):
0098         print(datetime.datetime.today(), *args, sep=' ', **kw_args)
0099 
0100 def usage():
0101     printerr("Usage is: export-to-sqlite.py <database name> [<columns>] [<calls>] [<callchains>] [<pyside-version-1>]");
0102     printerr("where:  columns            'all' or 'branches'");
0103     printerr("        calls              'calls' => create calls and call_paths table");
0104     printerr("        callchains         'callchains' => create call_paths table");
0105     printerr("        pyside-version-1   'pyside-version-1' => use pyside version 1");
0106     raise Exception("Too few or bad arguments")
0107 
0108 if (len(sys.argv) < 2):
0109     usage()
0110 
0111 dbname = sys.argv[1]
0112 
0113 if (len(sys.argv) >= 3):
0114     columns = sys.argv[2]
0115 else:
0116     columns = "all"
0117 
0118 if columns not in ("all", "branches"):
0119     usage()
0120 
0121 branches = (columns == "branches")
0122 
0123 for i in range(3,len(sys.argv)):
0124     if (sys.argv[i] == "calls"):
0125         perf_db_export_calls = True
0126     elif (sys.argv[i] == "callchains"):
0127         perf_db_export_callchains = True
0128     elif (sys.argv[i] == "pyside-version-1"):
0129         pass
0130     else:
0131         usage()
0132 
0133 def do_query(q, s):
0134     if (q.exec_(s)):
0135         return
0136     raise Exception("Query failed: " + q.lastError().text())
0137 
0138 def do_query_(q):
0139     if (q.exec_()):
0140         return
0141     raise Exception("Query failed: " + q.lastError().text())
0142 
0143 printdate("Creating database ...")
0144 
0145 db_exists = False
0146 try:
0147     f = open(dbname)
0148     f.close()
0149     db_exists = True
0150 except:
0151     pass
0152 
0153 if db_exists:
0154     raise Exception(dbname + " already exists")
0155 
0156 db = QSqlDatabase.addDatabase('QSQLITE')
0157 db.setDatabaseName(dbname)
0158 db.open()
0159 
0160 query = QSqlQuery(db)
0161 
0162 do_query(query, 'PRAGMA journal_mode = OFF')
0163 do_query(query, 'BEGIN TRANSACTION')
0164 
0165 do_query(query, 'CREATE TABLE selected_events ('
0166         'id     integer     NOT NULL    PRIMARY KEY,'
0167         'name       varchar(80))')
0168 do_query(query, 'CREATE TABLE machines ('
0169         'id     integer     NOT NULL    PRIMARY KEY,'
0170         'pid        integer,'
0171         'root_dir   varchar(4096))')
0172 do_query(query, 'CREATE TABLE threads ('
0173         'id     integer     NOT NULL    PRIMARY KEY,'
0174         'machine_id bigint,'
0175         'process_id bigint,'
0176         'pid        integer,'
0177         'tid        integer)')
0178 do_query(query, 'CREATE TABLE comms ('
0179         'id     integer     NOT NULL    PRIMARY KEY,'
0180         'comm       varchar(16),'
0181         'c_thread_id    bigint,'
0182         'c_time     bigint,'
0183         'exec_flag  boolean)')
0184 do_query(query, 'CREATE TABLE comm_threads ('
0185         'id     integer     NOT NULL    PRIMARY KEY,'
0186         'comm_id    bigint,'
0187         'thread_id  bigint)')
0188 do_query(query, 'CREATE TABLE dsos ('
0189         'id     integer     NOT NULL    PRIMARY KEY,'
0190         'machine_id bigint,'
0191         'short_name varchar(256),'
0192         'long_name  varchar(4096),'
0193         'build_id   varchar(64))')
0194 do_query(query, 'CREATE TABLE symbols ('
0195         'id     integer     NOT NULL    PRIMARY KEY,'
0196         'dso_id     bigint,'
0197         'sym_start  bigint,'
0198         'sym_end    bigint,'
0199         'binding    integer,'
0200         'name       varchar(2048))')
0201 do_query(query, 'CREATE TABLE branch_types ('
0202         'id     integer     NOT NULL    PRIMARY KEY,'
0203         'name       varchar(80))')
0204 
0205 if branches:
0206     do_query(query, 'CREATE TABLE samples ('
0207         'id     integer     NOT NULL    PRIMARY KEY,'
0208         'evsel_id   bigint,'
0209         'machine_id bigint,'
0210         'thread_id  bigint,'
0211         'comm_id    bigint,'
0212         'dso_id     bigint,'
0213         'symbol_id  bigint,'
0214         'sym_offset bigint,'
0215         'ip     bigint,'
0216         'time       bigint,'
0217         'cpu        integer,'
0218         'to_dso_id  bigint,'
0219         'to_symbol_id   bigint,'
0220         'to_sym_offset  bigint,'
0221         'to_ip      bigint,'
0222         'branch_type    integer,'
0223         'in_tx      boolean,'
0224         'call_path_id   bigint,'
0225         'insn_count bigint,'
0226         'cyc_count  bigint,'
0227         'flags      integer)')
0228 else:
0229     do_query(query, 'CREATE TABLE samples ('
0230         'id     integer     NOT NULL    PRIMARY KEY,'
0231         'evsel_id   bigint,'
0232         'machine_id bigint,'
0233         'thread_id  bigint,'
0234         'comm_id    bigint,'
0235         'dso_id     bigint,'
0236         'symbol_id  bigint,'
0237         'sym_offset bigint,'
0238         'ip     bigint,'
0239         'time       bigint,'
0240         'cpu        integer,'
0241         'to_dso_id  bigint,'
0242         'to_symbol_id   bigint,'
0243         'to_sym_offset  bigint,'
0244         'to_ip      bigint,'
0245         'period     bigint,'
0246         'weight     bigint,'
0247         'transaction_   bigint,'
0248         'data_src   bigint,'
0249         'branch_type    integer,'
0250         'in_tx      boolean,'
0251         'call_path_id   bigint,'
0252         'insn_count bigint,'
0253         'cyc_count  bigint,'
0254         'flags      integer)')
0255 
0256 if perf_db_export_calls or perf_db_export_callchains:
0257     do_query(query, 'CREATE TABLE call_paths ('
0258         'id     integer     NOT NULL    PRIMARY KEY,'
0259         'parent_id  bigint,'
0260         'symbol_id  bigint,'
0261         'ip     bigint)')
0262 if perf_db_export_calls:
0263     do_query(query, 'CREATE TABLE calls ('
0264         'id     integer     NOT NULL    PRIMARY KEY,'
0265         'thread_id  bigint,'
0266         'comm_id    bigint,'
0267         'call_path_id   bigint,'
0268         'call_time  bigint,'
0269         'return_time    bigint,'
0270         'branch_count   bigint,'
0271         'call_id    bigint,'
0272         'return_id  bigint,'
0273         'parent_call_path_id    bigint,'
0274         'flags      integer,'
0275         'parent_id  bigint,'
0276         'insn_count bigint,'
0277         'cyc_count  bigint)')
0278 
0279 do_query(query, 'CREATE TABLE ptwrite ('
0280         'id     integer     NOT NULL    PRIMARY KEY,'
0281         'payload    bigint,'
0282         'exact_ip   integer)')
0283 
0284 do_query(query, 'CREATE TABLE cbr ('
0285         'id     integer     NOT NULL    PRIMARY KEY,'
0286         'cbr        integer,'
0287         'mhz        integer,'
0288         'percent    integer)')
0289 
0290 do_query(query, 'CREATE TABLE mwait ('
0291         'id     integer     NOT NULL    PRIMARY KEY,'
0292         'hints      integer,'
0293         'extensions integer)')
0294 
0295 do_query(query, 'CREATE TABLE pwre ('
0296         'id     integer     NOT NULL    PRIMARY KEY,'
0297         'cstate     integer,'
0298         'subcstate  integer,'
0299         'hw     integer)')
0300 
0301 do_query(query, 'CREATE TABLE exstop ('
0302         'id     integer     NOT NULL    PRIMARY KEY,'
0303         'exact_ip   integer)')
0304 
0305 do_query(query, 'CREATE TABLE pwrx ('
0306         'id     integer     NOT NULL    PRIMARY KEY,'
0307         'deepest_cstate integer,'
0308         'last_cstate    integer,'
0309         'wake_reason    integer)')
0310 
0311 do_query(query, 'CREATE TABLE context_switches ('
0312         'id     integer     NOT NULL    PRIMARY KEY,'
0313         'machine_id bigint,'
0314         'time       bigint,'
0315         'cpu        integer,'
0316         'thread_out_id  bigint,'
0317         'comm_out_id    bigint,'
0318         'thread_in_id   bigint,'
0319         'comm_in_id bigint,'
0320         'flags      integer)')
0321 
0322 # printf was added to sqlite in version 3.8.3
0323 sqlite_has_printf = False
0324 try:
0325     do_query(query, 'SELECT printf("") FROM machines')
0326     sqlite_has_printf = True
0327 except:
0328     pass
0329 
0330 def emit_to_hex(x):
0331     if sqlite_has_printf:
0332         return 'printf("%x", ' + x + ')'
0333     else:
0334         return x
0335 
0336 do_query(query, 'CREATE VIEW machines_view AS '
0337     'SELECT '
0338         'id,'
0339         'pid,'
0340         'root_dir,'
0341         'CASE WHEN id=0 THEN \'unknown\' WHEN pid=-1 THEN \'host\' ELSE \'guest\' END AS host_or_guest'
0342     ' FROM machines')
0343 
0344 do_query(query, 'CREATE VIEW dsos_view AS '
0345     'SELECT '
0346         'id,'
0347         'machine_id,'
0348         '(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,'
0349         'short_name,'
0350         'long_name,'
0351         'build_id'
0352     ' FROM dsos')
0353 
0354 do_query(query, 'CREATE VIEW symbols_view AS '
0355     'SELECT '
0356         'id,'
0357         'name,'
0358         '(SELECT short_name FROM dsos WHERE id=dso_id) AS dso,'
0359         'dso_id,'
0360         'sym_start,'
0361         'sym_end,'
0362         'CASE WHEN binding=0 THEN \'local\' WHEN binding=1 THEN \'global\' ELSE \'weak\' END AS binding'
0363     ' FROM symbols')
0364 
0365 do_query(query, 'CREATE VIEW threads_view AS '
0366     'SELECT '
0367         'id,'
0368         'machine_id,'
0369         '(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,'
0370         'process_id,'
0371         'pid,'
0372         'tid'
0373     ' FROM threads')
0374 
0375 do_query(query, 'CREATE VIEW comm_threads_view AS '
0376     'SELECT '
0377         'comm_id,'
0378         '(SELECT comm FROM comms WHERE id = comm_id) AS command,'
0379         'thread_id,'
0380         '(SELECT pid FROM threads WHERE id = thread_id) AS pid,'
0381         '(SELECT tid FROM threads WHERE id = thread_id) AS tid'
0382     ' FROM comm_threads')
0383 
0384 if perf_db_export_calls or perf_db_export_callchains:
0385     do_query(query, 'CREATE VIEW call_paths_view AS '
0386         'SELECT '
0387             'c.id,'
0388             + emit_to_hex('c.ip') + ' AS ip,'
0389             'c.symbol_id,'
0390             '(SELECT name FROM symbols WHERE id = c.symbol_id) AS symbol,'
0391             '(SELECT dso_id FROM symbols WHERE id = c.symbol_id) AS dso_id,'
0392             '(SELECT dso FROM symbols_view  WHERE id = c.symbol_id) AS dso_short_name,'
0393             'c.parent_id,'
0394             + emit_to_hex('p.ip') + ' AS parent_ip,'
0395             'p.symbol_id AS parent_symbol_id,'
0396             '(SELECT name FROM symbols WHERE id = p.symbol_id) AS parent_symbol,'
0397             '(SELECT dso_id FROM symbols WHERE id = p.symbol_id) AS parent_dso_id,'
0398             '(SELECT dso FROM symbols_view  WHERE id = p.symbol_id) AS parent_dso_short_name'
0399         ' FROM call_paths c INNER JOIN call_paths p ON p.id = c.parent_id')
0400 if perf_db_export_calls:
0401     do_query(query, 'CREATE VIEW calls_view AS '
0402         'SELECT '
0403             'calls.id,'
0404             'thread_id,'
0405             '(SELECT pid FROM threads WHERE id = thread_id) AS pid,'
0406             '(SELECT tid FROM threads WHERE id = thread_id) AS tid,'
0407             '(SELECT comm FROM comms WHERE id = comm_id) AS command,'
0408             'call_path_id,'
0409             + emit_to_hex('ip') + ' AS ip,'
0410             'symbol_id,'
0411             '(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,'
0412             'call_time,'
0413             'return_time,'
0414             'return_time - call_time AS elapsed_time,'
0415             'branch_count,'
0416             'insn_count,'
0417             'cyc_count,'
0418             'CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC,'
0419             'call_id,'
0420             'return_id,'
0421             '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,'
0422             'parent_call_path_id,'
0423             'calls.parent_id'
0424         ' FROM calls INNER JOIN call_paths ON call_paths.id = call_path_id')
0425 
0426 do_query(query, 'CREATE VIEW samples_view AS '
0427     'SELECT '
0428         'id,'
0429         'time,'
0430         'cpu,'
0431         '(SELECT pid FROM threads WHERE id = thread_id) AS pid,'
0432         '(SELECT tid FROM threads WHERE id = thread_id) AS tid,'
0433         '(SELECT comm FROM comms WHERE id = comm_id) AS command,'
0434         '(SELECT name FROM selected_events WHERE id = evsel_id) AS event,'
0435         + emit_to_hex('ip') + ' AS ip_hex,'
0436         '(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,'
0437         'sym_offset,'
0438         '(SELECT short_name FROM dsos WHERE id = dso_id) AS dso_short_name,'
0439         + emit_to_hex('to_ip') + ' AS to_ip_hex,'
0440         '(SELECT name FROM symbols WHERE id = to_symbol_id) AS to_symbol,'
0441         'to_sym_offset,'
0442         '(SELECT short_name FROM dsos WHERE id = to_dso_id) AS to_dso_short_name,'
0443         '(SELECT name FROM branch_types WHERE id = branch_type) AS branch_type_name,'
0444         'in_tx,'
0445         'insn_count,'
0446         'cyc_count,'
0447         'CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC,'
0448         'flags'
0449     ' FROM samples')
0450 
0451 do_query(query, 'CREATE VIEW ptwrite_view AS '
0452     'SELECT '
0453         'ptwrite.id,'
0454         'time,'
0455         'cpu,'
0456         + emit_to_hex('payload') + ' AS payload_hex,'
0457         'CASE WHEN exact_ip=0 THEN \'False\' ELSE \'True\' END AS exact_ip'
0458     ' FROM ptwrite'
0459     ' INNER JOIN samples ON samples.id = ptwrite.id')
0460 
0461 do_query(query, 'CREATE VIEW cbr_view AS '
0462     'SELECT '
0463         'cbr.id,'
0464         'time,'
0465         'cpu,'
0466         'cbr,'
0467         'mhz,'
0468         'percent'
0469     ' FROM cbr'
0470     ' INNER JOIN samples ON samples.id = cbr.id')
0471 
0472 do_query(query, 'CREATE VIEW mwait_view AS '
0473     'SELECT '
0474         'mwait.id,'
0475         'time,'
0476         'cpu,'
0477         + emit_to_hex('hints') + ' AS hints_hex,'
0478         + emit_to_hex('extensions') + ' AS extensions_hex'
0479     ' FROM mwait'
0480     ' INNER JOIN samples ON samples.id = mwait.id')
0481 
0482 do_query(query, 'CREATE VIEW pwre_view AS '
0483     'SELECT '
0484         'pwre.id,'
0485         'time,'
0486         'cpu,'
0487         'cstate,'
0488         'subcstate,'
0489         'CASE WHEN hw=0 THEN \'False\' ELSE \'True\' END AS hw'
0490     ' FROM pwre'
0491     ' INNER JOIN samples ON samples.id = pwre.id')
0492 
0493 do_query(query, 'CREATE VIEW exstop_view AS '
0494     'SELECT '
0495         'exstop.id,'
0496         'time,'
0497         'cpu,'
0498         'CASE WHEN exact_ip=0 THEN \'False\' ELSE \'True\' END AS exact_ip'
0499     ' FROM exstop'
0500     ' INNER JOIN samples ON samples.id = exstop.id')
0501 
0502 do_query(query, 'CREATE VIEW pwrx_view AS '
0503     'SELECT '
0504         'pwrx.id,'
0505         'time,'
0506         'cpu,'
0507         'deepest_cstate,'
0508         'last_cstate,'
0509         'CASE     WHEN wake_reason=1 THEN \'Interrupt\''
0510             ' WHEN wake_reason=2 THEN \'Timer Deadline\''
0511             ' WHEN wake_reason=4 THEN \'Monitored Address\''
0512             ' WHEN wake_reason=8 THEN \'HW\''
0513             ' ELSE wake_reason '
0514         'END AS wake_reason'
0515     ' FROM pwrx'
0516     ' INNER JOIN samples ON samples.id = pwrx.id')
0517 
0518 do_query(query, 'CREATE VIEW power_events_view AS '
0519     'SELECT '
0520         'samples.id,'
0521         'time,'
0522         'cpu,'
0523         'selected_events.name AS event,'
0524         'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT cbr FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS cbr,'
0525         'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT mhz FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS mhz,'
0526         'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT percent FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS percent,'
0527         'CASE WHEN selected_events.name=\'mwait\' THEN (SELECT ' + emit_to_hex('hints') + ' FROM mwait WHERE mwait.id = samples.id) ELSE "" END AS hints_hex,'
0528         'CASE WHEN selected_events.name=\'mwait\' THEN (SELECT ' + emit_to_hex('extensions') + ' FROM mwait WHERE mwait.id = samples.id) ELSE "" END AS extensions_hex,'
0529         'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT cstate FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS cstate,'
0530         'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT subcstate FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS subcstate,'
0531         'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT hw FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS hw,'
0532         'CASE WHEN selected_events.name=\'exstop\' THEN (SELECT exact_ip FROM exstop WHERE exstop.id = samples.id) ELSE "" END AS exact_ip,'
0533         'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT deepest_cstate FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS deepest_cstate,'
0534         'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT last_cstate FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS last_cstate,'
0535         'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT '
0536             'CASE     WHEN wake_reason=1 THEN \'Interrupt\''
0537                 ' WHEN wake_reason=2 THEN \'Timer Deadline\''
0538                 ' WHEN wake_reason=4 THEN \'Monitored Address\''
0539                 ' WHEN wake_reason=8 THEN \'HW\''
0540                 ' ELSE wake_reason '
0541             'END'
0542         ' FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS wake_reason'
0543     ' FROM samples'
0544     ' INNER JOIN selected_events ON selected_events.id = evsel_id'
0545     ' WHERE selected_events.name IN (\'cbr\',\'mwait\',\'exstop\',\'pwre\',\'pwrx\')')
0546 
0547 do_query(query, 'CREATE VIEW context_switches_view AS '
0548     'SELECT '
0549         'context_switches.id,'
0550         'context_switches.machine_id,'
0551         'context_switches.time,'
0552         'context_switches.cpu,'
0553         'th_out.pid AS pid_out,'
0554         'th_out.tid AS tid_out,'
0555         'comm_out.comm AS comm_out,'
0556         'th_in.pid AS pid_in,'
0557         'th_in.tid AS tid_in,'
0558         'comm_in.comm AS comm_in,'
0559         'CASE     WHEN context_switches.flags = 0 THEN \'in\''
0560             ' WHEN context_switches.flags = 1 THEN \'out\''
0561             ' WHEN context_switches.flags = 3 THEN \'out preempt\''
0562             ' ELSE context_switches.flags '
0563         'END AS flags'
0564     ' FROM context_switches'
0565     ' INNER JOIN threads AS th_out ON th_out.id   = context_switches.thread_out_id'
0566     ' INNER JOIN threads AS th_in  ON th_in.id    = context_switches.thread_in_id'
0567     ' INNER JOIN comms AS comm_out ON comm_out.id = context_switches.comm_out_id'
0568     ' INNER JOIN comms AS comm_in  ON comm_in.id  = context_switches.comm_in_id')
0569 
0570 do_query(query, 'END TRANSACTION')
0571 
0572 evsel_query = QSqlQuery(db)
0573 evsel_query.prepare("INSERT INTO selected_events VALUES (?, ?)")
0574 machine_query = QSqlQuery(db)
0575 machine_query.prepare("INSERT INTO machines VALUES (?, ?, ?)")
0576 thread_query = QSqlQuery(db)
0577 thread_query.prepare("INSERT INTO threads VALUES (?, ?, ?, ?, ?)")
0578 comm_query = QSqlQuery(db)
0579 comm_query.prepare("INSERT INTO comms VALUES (?, ?, ?, ?, ?)")
0580 comm_thread_query = QSqlQuery(db)
0581 comm_thread_query.prepare("INSERT INTO comm_threads VALUES (?, ?, ?)")
0582 dso_query = QSqlQuery(db)
0583 dso_query.prepare("INSERT INTO dsos VALUES (?, ?, ?, ?, ?)")
0584 symbol_query = QSqlQuery(db)
0585 symbol_query.prepare("INSERT INTO symbols VALUES (?, ?, ?, ?, ?, ?)")
0586 branch_type_query = QSqlQuery(db)
0587 branch_type_query.prepare("INSERT INTO branch_types VALUES (?, ?)")
0588 sample_query = QSqlQuery(db)
0589 if branches:
0590     sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
0591 else:
0592     sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
0593 if perf_db_export_calls or perf_db_export_callchains:
0594     call_path_query = QSqlQuery(db)
0595     call_path_query.prepare("INSERT INTO call_paths VALUES (?, ?, ?, ?)")
0596 if perf_db_export_calls:
0597     call_query = QSqlQuery(db)
0598     call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
0599 ptwrite_query = QSqlQuery(db)
0600 ptwrite_query.prepare("INSERT INTO ptwrite VALUES (?, ?, ?)")
0601 cbr_query = QSqlQuery(db)
0602 cbr_query.prepare("INSERT INTO cbr VALUES (?, ?, ?, ?)")
0603 mwait_query = QSqlQuery(db)
0604 mwait_query.prepare("INSERT INTO mwait VALUES (?, ?, ?)")
0605 pwre_query = QSqlQuery(db)
0606 pwre_query.prepare("INSERT INTO pwre VALUES (?, ?, ?, ?)")
0607 exstop_query = QSqlQuery(db)
0608 exstop_query.prepare("INSERT INTO exstop VALUES (?, ?)")
0609 pwrx_query = QSqlQuery(db)
0610 pwrx_query.prepare("INSERT INTO pwrx VALUES (?, ?, ?, ?)")
0611 context_switch_query = QSqlQuery(db)
0612 context_switch_query.prepare("INSERT INTO context_switches VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")
0613 
0614 def trace_begin():
0615     printdate("Writing records...")
0616     do_query(query, 'BEGIN TRANSACTION')
0617     # id == 0 means unknown.  It is easier to create records for them than replace the zeroes with NULLs
0618     evsel_table(0, "unknown")
0619     machine_table(0, 0, "unknown")
0620     thread_table(0, 0, 0, -1, -1)
0621     comm_table(0, "unknown", 0, 0, 0)
0622     dso_table(0, 0, "unknown", "unknown", "")
0623     symbol_table(0, 0, 0, 0, 0, "unknown")
0624     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)
0625     if perf_db_export_calls or perf_db_export_callchains:
0626         call_path_table(0, 0, 0, 0)
0627         call_return_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
0628 
0629 unhandled_count = 0
0630 
0631 def is_table_empty(table_name):
0632     do_query(query, 'SELECT * FROM ' + table_name + ' LIMIT 1');
0633     if query.next():
0634         return False
0635     return True
0636 
0637 def drop(table_name):
0638     do_query(query, 'DROP VIEW ' + table_name + '_view');
0639     do_query(query, 'DROP TABLE ' + table_name);
0640 
0641 def trace_end():
0642     do_query(query, 'END TRANSACTION')
0643 
0644     printdate("Adding indexes")
0645     if perf_db_export_calls:
0646         do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)')
0647         do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)')
0648         do_query(query, 'ALTER TABLE comms ADD has_calls boolean')
0649         do_query(query, 'UPDATE comms SET has_calls = 1 WHERE comms.id IN (SELECT DISTINCT comm_id FROM calls)')
0650 
0651     printdate("Dropping unused tables")
0652     if is_table_empty("ptwrite"):
0653         drop("ptwrite")
0654     if is_table_empty("mwait") and is_table_empty("pwre") and is_table_empty("exstop") and is_table_empty("pwrx"):
0655         do_query(query, 'DROP VIEW power_events_view');
0656         drop("mwait")
0657         drop("pwre")
0658         drop("exstop")
0659         drop("pwrx")
0660         if is_table_empty("cbr"):
0661             drop("cbr")
0662     if is_table_empty("context_switches"):
0663         drop("context_switches")
0664 
0665     if (unhandled_count):
0666         printdate("Warning: ", unhandled_count, " unhandled events")
0667     printdate("Done")
0668 
0669 def trace_unhandled(event_name, context, event_fields_dict):
0670     global unhandled_count
0671     unhandled_count += 1
0672 
0673 def sched__sched_switch(*x):
0674     pass
0675 
0676 def bind_exec(q, n, x):
0677     for xx in x[0:n]:
0678         q.addBindValue(str(xx))
0679     do_query_(q)
0680 
0681 def evsel_table(*x):
0682     bind_exec(evsel_query, 2, x)
0683 
0684 def machine_table(*x):
0685     bind_exec(machine_query, 3, x)
0686 
0687 def thread_table(*x):
0688     bind_exec(thread_query, 5, x)
0689 
0690 def comm_table(*x):
0691     bind_exec(comm_query, 5, x)
0692 
0693 def comm_thread_table(*x):
0694     bind_exec(comm_thread_query, 3, x)
0695 
0696 def dso_table(*x):
0697     bind_exec(dso_query, 5, x)
0698 
0699 def symbol_table(*x):
0700     bind_exec(symbol_query, 6, x)
0701 
0702 def branch_type_table(*x):
0703     bind_exec(branch_type_query, 2, x)
0704 
0705 def sample_table(*x):
0706     if branches:
0707         for xx in x[0:15]:
0708             sample_query.addBindValue(str(xx))
0709         for xx in x[19:25]:
0710             sample_query.addBindValue(str(xx))
0711         do_query_(sample_query)
0712     else:
0713         bind_exec(sample_query, 25, x)
0714 
0715 def call_path_table(*x):
0716     bind_exec(call_path_query, 4, x)
0717 
0718 def call_return_table(*x):
0719     bind_exec(call_query, 14, x)
0720 
0721 def ptwrite(id, raw_buf):
0722     data = struct.unpack_from("<IQ", raw_buf)
0723     flags = data[0]
0724     payload = data[1]
0725     exact_ip = flags & 1
0726     ptwrite_query.addBindValue(str(id))
0727     ptwrite_query.addBindValue(str(payload))
0728     ptwrite_query.addBindValue(str(exact_ip))
0729     do_query_(ptwrite_query)
0730 
0731 def cbr(id, raw_buf):
0732     data = struct.unpack_from("<BBBBII", raw_buf)
0733     cbr = data[0]
0734     MHz = (data[4] + 500) / 1000
0735     percent = ((cbr * 1000 / data[2]) + 5) / 10
0736     cbr_query.addBindValue(str(id))
0737     cbr_query.addBindValue(str(cbr))
0738     cbr_query.addBindValue(str(MHz))
0739     cbr_query.addBindValue(str(percent))
0740     do_query_(cbr_query)
0741 
0742 def mwait(id, raw_buf):
0743     data = struct.unpack_from("<IQ", raw_buf)
0744     payload = data[1]
0745     hints = payload & 0xff
0746     extensions = (payload >> 32) & 0x3
0747     mwait_query.addBindValue(str(id))
0748     mwait_query.addBindValue(str(hints))
0749     mwait_query.addBindValue(str(extensions))
0750     do_query_(mwait_query)
0751 
0752 def pwre(id, raw_buf):
0753     data = struct.unpack_from("<IQ", raw_buf)
0754     payload = data[1]
0755     hw = (payload >> 7) & 1
0756     cstate = (payload >> 12) & 0xf
0757     subcstate = (payload >> 8) & 0xf
0758     pwre_query.addBindValue(str(id))
0759     pwre_query.addBindValue(str(cstate))
0760     pwre_query.addBindValue(str(subcstate))
0761     pwre_query.addBindValue(str(hw))
0762     do_query_(pwre_query)
0763 
0764 def exstop(id, raw_buf):
0765     data = struct.unpack_from("<I", raw_buf)
0766     flags = data[0]
0767     exact_ip = flags & 1
0768     exstop_query.addBindValue(str(id))
0769     exstop_query.addBindValue(str(exact_ip))
0770     do_query_(exstop_query)
0771 
0772 def pwrx(id, raw_buf):
0773     data = struct.unpack_from("<IQ", raw_buf)
0774     payload = data[1]
0775     deepest_cstate = payload & 0xf
0776     last_cstate = (payload >> 4) & 0xf
0777     wake_reason = (payload >> 8) & 0xf
0778     pwrx_query.addBindValue(str(id))
0779     pwrx_query.addBindValue(str(deepest_cstate))
0780     pwrx_query.addBindValue(str(last_cstate))
0781     pwrx_query.addBindValue(str(wake_reason))
0782     do_query_(pwrx_query)
0783 
0784 def synth_data(id, config, raw_buf, *x):
0785     if config == 0:
0786         ptwrite(id, raw_buf)
0787     elif config == 1:
0788         mwait(id, raw_buf)
0789     elif config == 2:
0790         pwre(id, raw_buf)
0791     elif config == 3:
0792         exstop(id, raw_buf)
0793     elif config == 4:
0794         pwrx(id, raw_buf)
0795     elif config == 5:
0796         cbr(id, raw_buf)
0797 
0798 def context_switch_table(*x):
0799     bind_exec(context_switch_query, 9, x)