Convert LTTngTop to C++ and state system
[lttngtop.git] / src / cputop.cpp
1 /*
2 * Copyright (C) 2011-2012 Julien Desfossez
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 */
17
18 extern "C" {
19 #include <babeltrace/babeltrace.h>
20 }
21
22 #include "lttngtoptypes.h"
23 #include "common.h"
24 #include "cputop.h"
25
26 void update_cputop_data(unsigned long timestamp, int64_t cpu,
27 int prev_pid, int next_pid, char *prev_comm, char *next_comm)
28 {
29 Quark cpu_quark;
30 Quark current_task_quark;
31 bool current_task_found;
32 int current_task_pid;
33 int current_task_tid;
34 unsigned long elapsed;
35 unsigned long task_start;
36 bool current_task_threadparent_found;
37 Quark current_task_threadparent;
38
39 cpu_quark = get_cpu(cpu, timestamp);
40 current_task_found = get_current_attribute_value_quark(&cpu_quark,
41 "current_task", current_task_quark);
42
43 if (current_task_found) {
44 get_current_attribute_value_int(&current_task_quark, "pid",
45 current_task_pid);
46 if (current_task_pid == prev_pid) {
47 get_current_attribute_value_ulong(&cpu_quark,
48 "task_start", task_start);
49 elapsed = timestamp - task_start;
50 increase_attribute(timestamp, &current_task_quark,
51 "totalcpunsec", elapsed);
52 increase_attribute(timestamp, &current_task_quark,
53 "threadstotalcpunsec", elapsed);
54 get_current_attribute_value_int(&current_task_quark,
55 "tid", current_task_tid);
56 if (current_task_tid != current_task_pid) {
57 current_task_threadparent_found =
58 get_current_attribute_value_quark(
59 &current_task_quark,
60 "threadparent",
61 current_task_threadparent);
62 if (current_task_threadparent_found)
63 increase_attribute(timestamp,
64 &current_task_threadparent,
65 "threadstotalcpuns", elapsed);
66 }
67 }
68 }
69
70 if (next_pid != 0)
71 modify_attribute(timestamp, &cpu_quark, "current_task",
72 get_proc(next_pid, next_comm, timestamp));
73 else
74 nullify_attribute(timestamp, &cpu_quark, "current_task");
75
76 modify_attribute(timestamp, &cpu_quark, "task_start", timestamp);
77 }
78
79 enum bt_cb_ret handle_sched_switch(struct bt_ctf_event *call_data,
80 void *private_data)
81 {
82 const struct definition *scope;
83 unsigned long timestamp;
84 uint64_t cpu_id;
85 char *prev_comm, *next_comm;
86 int prev_tid, next_tid;
87
88 timestamp = bt_ctf_get_timestamp(call_data);
89 if (timestamp == -1ULL)
90 goto error;
91
92 scope = bt_ctf_get_top_level_scope(call_data,
93 BT_EVENT_FIELDS);
94 prev_comm = bt_ctf_get_char_array(bt_ctf_get_field(call_data,
95 scope, "_prev_comm"));
96 if (bt_ctf_field_get_error()) {
97 fprintf(stderr, "Missing prev_comm context info\n");
98 goto error;
99 }
100
101 next_comm = bt_ctf_get_char_array(bt_ctf_get_field(call_data,
102 scope, "_next_comm"));
103 if (bt_ctf_field_get_error()) {
104 fprintf(stderr, "Missing next_comm context info\n");
105 goto error;
106 }
107
108 prev_tid = bt_ctf_get_int64(bt_ctf_get_field(call_data,
109 scope, "_prev_tid"));
110 if (bt_ctf_field_get_error()) {
111 fprintf(stderr, "Missing prev_tid context info\n");
112 goto error;
113 }
114
115 next_tid = bt_ctf_get_int64(bt_ctf_get_field(call_data,
116 scope, "_next_tid"));
117 if (bt_ctf_field_get_error()) {
118 fprintf(stderr, "Missing next_tid context info\n");
119 goto error;
120 }
121
122 cpu_id = get_cpu_id(call_data);
123
124 update_cputop_data(timestamp, cpu_id, prev_tid, next_tid,
125 prev_comm, next_comm);
126
127 return BT_CB_OK;
128
129 error:
130 return BT_CB_ERROR_STOP;
131 }
132
133 enum bt_cb_ret handle_sched_process_free(struct bt_ctf_event *call_data,
134 void *private_data)
135 {
136 const struct definition *scope;
137 unsigned long timestamp;
138 char *comm;
139 int tid;
140
141 timestamp = bt_ctf_get_timestamp(call_data);
142 if (timestamp == -1ULL)
143 goto error;
144
145 scope = bt_ctf_get_top_level_scope(call_data,
146 BT_EVENT_FIELDS);
147 comm = bt_ctf_get_char_array(bt_ctf_get_field(call_data,
148 scope, "_comm"));
149 if (bt_ctf_field_get_error()) {
150 fprintf(stderr, "Missing procname context info\n");
151 goto error;
152 }
153
154 tid = bt_ctf_get_int64(bt_ctf_get_field(call_data,
155 scope, "_tid"));
156 if (bt_ctf_field_get_error()) {
157 fprintf(stderr, "Missing tid field\n");
158 goto error;
159 }
160
161 death_proc(tid, comm, timestamp);
162
163 return BT_CB_OK;
164
165 error:
166 return BT_CB_ERROR_STOP;
167
168 }
169
This page took 0.035351 seconds and 4 git commands to generate.