4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1994, by Sun Microsytems, Inc.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <sys/types.h>
43 #define STREQ(s1, s2, n) (strncmp(s1, s2, n) == 0)
45 #define IS_64BIT(kind) ((1 << kind) & \
46 ((1 << TNF_K_UINT64) | (1 << TNF_K_INT64)))
48 #define PROBE_TYPE "tnf_probe_type"
50 static void print_event (entry_t
*ent
);
51 static void insert_event (tnf_datum_t
, tnf_datum_t
);
52 static void describe_c_brief (tnf_datum_t
);
53 static void describe_target (tnf_datum_t
);
54 static void describe_c_struct (tnf_datum_t
);
55 static void describe_probe_type (tnf_datum_t
);
56 static void describe_event (tnf_datum_t
, tnf_datum_t
, hrtime_t
);
58 static hrtime_t base_time
= 0;
63 (void) printf("%16s %16s %5s %5s %10s %3s %-25s %s\n",
64 "----------------", "----------------", "-----", "-----",
65 "----------", "---", "-------------------------",
66 "------------------------");
67 (void) printf("%16s %16s %5s %5s %10s %3s %-25s %s\n",
68 "Elapsed (ms)", "Delta (ms)", "PID", "LWPID",
69 " TID ", "CPU", "Probe Name", "Data / Description . . .");
70 (void) printf("%16s %16s %5s %5s %10s %3s %-25s %s\n",
71 "----------------", "----------------", "-----", "-----",
72 "----------", "---", "-------------------------",
73 "------------------------");
77 print_event(entry_t
*ent
)
79 tnf_datum_t evt
, sched
;
80 hrtime_t normalized_time
;
83 sched
= tnf_get_tag_arg(evt
);
84 if (sched
== TNF_DATUM_NULL
) {
86 * should never happen because it had a schedule
89 fail(0, gettext("event without a schedule record"));
91 normalized_time
= ent
->time
- base_time
;
92 describe_event(evt
, sched
, normalized_time
);
96 print_sorted_events(void)
101 ent
= table_get_entry_indexed(0);
103 base_time
= ent
->time
;
105 table_print(&print_event
);
109 describe_c_record(tnf_datum_t datum
)
112 tnf_datum_t schedule_rec
;
114 switch (tnf_get_kind(datum
)) {
117 /* print only event records */
118 schedule_rec
= tnf_get_tag_arg(datum
);
119 if (schedule_rec
!= TNF_DATUM_NULL
) {
121 insert_event(datum
, schedule_rec
);
126 /* Skip arrays at top level */
129 name_str
= tnf_get_type_name(datum
);
130 /* REMIND: filter based on property */
131 if (STREQ(name_str
, PROBE_TYPE
, strlen(name_str
)))
132 describe_probe_type(datum
);
135 fail(0, gettext("illegal record at %x (%d)"),
136 tnf_get_raw(datum
), tnf_get_kind(datum
));
143 describe_probe_type(tnf_datum_t datum
)
149 n
= tnf_get_slot_count(datum
);
151 /* print the OUTPUT PAD */
152 (void) printf("%16s %14s %5s %5s %8s %3s %-25s",
153 "-", "-", "-", "-", "-", "-", "-");
155 (void) printf("probe\t");
156 for (i
= 0; i
< n
; i
++) {
157 slotname
= tnf_get_slot_name(datum
, i
);
158 slot_len
= strlen(slotname
);
160 /* print all fields except ... */
161 if ((!STREQ(slotname
, TNF_N_TAG
, slot_len
)) &&
162 (!STREQ(slotname
, TNF_N_PROPERTIES
, slot_len
)) &&
163 (!STREQ(slotname
, TNF_N_SLOT_TYPES
, slot_len
)) &&
164 (!STREQ(slotname
, TNF_N_TYPE_SIZE
, slot_len
)) &&
165 (!STREQ(slotname
, TNF_N_SLOT_NAMES
, slot_len
))) {
167 (void) printf("%s: ", slotname
);
168 describe_c_brief(tnf_get_slot_indexed(datum
,
176 insert_event(tnf_datum_t datum
, tnf_datum_t schedule_rec
)
180 unsigned time_delta
= 0;
183 temp
= tnf_get_slot_named(schedule_rec
, TNF_N_TIME_BASE
);
184 evt_time
= tnf_get_int64(temp
);
185 temp
= tnf_get_slot_named(datum
, TNF_N_TIME_DELTA
);
186 time_delta
= (unsigned) tnf_get_int32(temp
);
187 evt_time
= evt_time
+ time_delta
;
189 element
.time
= evt_time
;
190 element
.record
= datum
;
191 table_insert(&element
);
194 #define K_TID "tnf_kthread_id"
195 #define CPUID "cpuid"
198 describe_event(tnf_datum_t datum
, tnf_datum_t schedule_rec
, hrtime_t evt_time
)
201 char *slotname
, *eventname
, *tidtype
;
203 int lwpid
= 0, pid
= 0;
205 static hrtime_t last_time
= 0;
206 unsigned long long tid
= 0;
208 temp
= tnf_get_slot_named(schedule_rec
, TNF_N_TID
);
209 if (IS_64BIT(tnf_get_kind(temp
))) {
210 tid
= tnf_get_int64(temp
);
212 tid
= (unsigned int)tnf_get_int32(temp
);
214 tidtype
= tnf_get_type_name(temp
);
216 temp
= tnf_get_slot_named(schedule_rec
, TNF_N_LWPID
);
217 lwpid
= tnf_get_int32(temp
);
218 temp
= tnf_get_slot_named(schedule_rec
, TNF_N_PID
);
219 pid
= tnf_get_int32(temp
);
221 /* XXX should use TNF_N_KERNEL_SCHEDULE, TNF_N_USER_SCHEDULE */
222 if (strcmp(tidtype
, K_TID
) == 0) {
224 /* XXX Assumes cpuid always exists in kernel schedule */
225 cpuid
= tnf_get_int32(tnf_get_slot_named(schedule_rec
, CPUID
));
226 /* print the OUTPUT schedule record for Kernel case */
227 (void) printf("%16.6f %16.6f %5u %5u 0x%-8llx %3d",
228 evt_time
/ 1000000.0,
229 (evt_time
- last_time
)/1000000.0,
230 pid
, lwpid
, tid
, cpuid
);
232 /* print the OUTPUT schedule record */
233 (void) printf("%16.6f %16.6f %5u %5u %10llu %3s",
234 evt_time
/ 1000000.0,
235 (evt_time
- last_time
)/1000000.0,
236 pid
, lwpid
, tid
, "-");
239 eventname
= tnf_type_get_name(tnf_get_slot_named(datum
, TNF_N_TAG
));
240 (void) printf(" %-25s", eventname
);
242 /* heuristic - start of data is after TIME_DELTA field */
243 start_slots
= tnf_get_slot_index(datum
, TNF_N_TIME_DELTA
);
246 n
= tnf_get_slot_count(datum
);
248 /* print the rest of the fields */
249 for (i
= start_slots
; i
< n
; i
++) {
251 slotname
= tnf_get_slot_name(datum
, i
);
252 (void) printf("%s: ", slotname
);
253 describe_target(tnf_get_slot_indexed(datum
, i
));
256 last_time
= evt_time
;
260 describe_c_struct(tnf_datum_t datum
)
262 unsigned n
, i
, tag_index
;
265 n
= tnf_get_slot_count(datum
);
269 (void) printf("%s: ", "type");
270 describe_c_brief(tnf_get_slot_named(datum
, TNF_N_TAG
));
271 tag_index
= tnf_get_slot_index(datum
, TNF_N_TAG
);
273 for (i
= 0; i
< n
; i
++) {
274 /* print the rest of the members */
275 if (i
!= tag_index
) {
277 slotname
= tnf_get_slot_name(datum
, i
);
278 (void) printf("%s: ", slotname
);
279 describe_target(tnf_get_slot_indexed(datum
, i
));
285 describe_c_brief(tnf_datum_t datum
)
287 if (datum
== TNF_DATUM_NULL
) /* allowed */
288 (void) printf("0x%-8x <NULL>", 0);
290 else if (tnf_is_scalar(datum
))
291 describe_scalar(datum
);
293 else if (tnf_is_record(datum
)) {
295 switch (tnf_get_kind(datum
)) {
297 (void) printf("%s", tnf_type_get_name(datum
));
300 (void) printf("\"%s\"", tnf_get_chars(datum
));
303 (void) printf("<%s>", tnf_get_type_name(datum
));
306 fail(0, gettext("inline aggregate slots/elements unhandled"));
310 describe_target(tnf_datum_t datum
)
312 if (datum
== TNF_DATUM_NULL
) /* allowed */
313 (void) printf("0x%-8x <NULL>", 0);
315 else if (tnf_is_scalar(datum
))
316 describe_scalar(datum
);
318 else if (tnf_is_record(datum
)) {
320 switch (tnf_get_kind(datum
)) {
323 describe_c_struct(datum
);
327 (void) printf("%s", tnf_type_get_name(datum
));
330 (void) printf("\"%s\"", tnf_get_chars(datum
));
333 (void) printf("<%s>", tnf_get_type_name(datum
));
336 fail(0, gettext("inline aggregate slots/elements unhandled"));