80 columns formatting
[lttv.git] / ltt / branches / poly / lttv / plugins / asciiDump.c
CommitLineData
59121f0c 1
2#include "ltt_module.h"
3
4/* This module dumps all events in a simple ascii format */
5
6static gboolean
7 ascii_dump = FALSE,
8 syscall_stats = FALSE;
9
10static gchar *dump_file = NULL;
11
12static FILE *dump_fp = stdout;
13
14struct poptOption
15 ascii_dump_option = { "ascii-dump", 'd', POPT_ARG_NONE, &ascii_dump, 0},
16 ascii_dump_option = { "dump-file", 'f', POPT_ARG_STRING, &dump_file, 0},
17 syscall_stats_option = { "syscall-stats", 's', POPT_ARG_NONE,
18 &syscall_stats, 0};
19
20static void after_options_hook(gpointer hook_data, gpointer call_data);
21
22static void before_trace_hook(gpointer hook_data, gpointer call_data);
23
24static void after_trace_hook(gpointer hook_data, gpointer call_data);
25
26static void events_hook(gpointer hook_data, gpointer call_data);
27
28void init(int argc, char **argv)
29{
30 ltt_add_command_option(&ascii_dump_option);
31 ltt_add_command_option(&syscall_stats_option);
32 ltt_add_hook(ltt_after_options_hooks,after_options_hook,NULL)
33}
34
35/* Check the command line options and insert hooks to do the work */
36
37static void after_options_hook(gpointer hook_data, gpointer call_data)
38{
39 if(ascii_dump_option || syscall_stats) {
40 ltt_add_hook(ltt_before_process_each_trace_hooks,before_trace_hook,NULL);
41 if(dump_file != NULL) {
42 dump_fp = fopen(dump_file,"w");
43 if(dump_fp == NULL) g_critical("cannot open output file %s",dump_file);
44 }
45 ltt_add_hook(ltt_after_process_each_trace_hooks,after_trace_hook,NULL);
46 }
47}
48
49/* Insert the hooks to print the events and compute and print the statistics */
50
51static unsigned *eventsCounters;
52
53struct CPUState {
54 lttProcess *current_process;
55 lttStatKey *key;
56 lttTime lastTime;
57} *CPUStates;
58
59static void before_trace_hook(gpointer hook_data, gpointer call_data) {
60 ltt_add_hook(ltt_trace_events_hooks,events_hooks,NULL);
61 fprintf(dump_fp,"Trace %s\n",(struct trace *)call_data->name);
62
63 if(ascii_dump) fprintf(dump_fp,"\nEvents\n");
64
65 /* To gather stats, register a few hooks */
66
67 if(syscall_stats) {
68 eventsCounters = g_new0(unsigned,nbEventType);
69 CPUStates = g_new0(struct CPUState, nbCPU);
70 /* initialize the state of each CPU and associated process */
71 CHECK
72 }
73}
74
75/* Print the events */
76
77static void events_hook(gpointer hook_data, gpointer call_data)
78{
79 event_struct event;
80
81 int i;
82
83 event = (struct_event *)call_data;
84
85 if(ascii_dump) {
86 fprintf(dump_fp,"\n%s.%s t=%d.%d CPU%d",event->facility_handle->name,
87 event->event_handle->name, event->time.tv_seconds,
88 event->time.tv_nanoseconds,event->CPU_id);
89
90 for(i = 0 ; i < event->base_field->nb_elements ; i++) {
91 field = event->base_field->fields + i;
92 fprintf(dump_fp," %s=",field->name);
93 switch(field->type) {
94 case INT:
95 fprintf(dump_fp,"%d",ltt_get_integer(field,event->data));
96 break;
97 case UINT:
98 fprintf(dump_fp,"%u",ltt_get_uinteger(field,event->data));
99 break;
100 case FLOAT:
101 fprintf(dump_fp,"%lg",ltt_get_float(field,event->data));
102 break;
103 case DOUBLE:
104 fprintf(dump_fp,"%g",ltt_get_double(field,event->data));
105 break;
106 case STRING:
107 fprintf(dump_fp,"%s",ltt_get_string(field,event->data));
108 break;
109 case ENUM:
110 fprintf(dump_fp,"%d",ltt_get_integer(field,event->data));
111 break;
112 case ARRAY:
113 fprintf(dump_fp,"<nested array>");
114 break;
115 case SEQUENCE:
116 fprintf(dump_fp,"<nested sequence>");
117 break;
118 case STRUCT:
119 fprintf(dump_fp,"<nested struct>");
120 break;
121 }
122 }
123 }
124
125 /* Collect statistics about each event type */
126
127 if(syscall_stats) {
128 /* Get the key for the corresponding CPU. It already contains the
129 path components for the ip, CPU, process, state, subState.
130 We add the event id and increment the statistic with that key. */
131
132 key = (GQuark *)CPUStates[event->CPUid]->key1;
133 path = key->data;
134 path[5] = eventsQuark[event->id];
135 pval = ltt_get_integer(currentStats,key);
136 (*pval)++;
137
138 /* Count the time spent in the current state. Could be done only
139 at state changes to optimize. */
140
141 key = (GQuark *)CPUStates[event->CPUid]->key2;
142 path = key->data;
143 ptime = ltt_get_time(currentStats,key);
144 (*ptime) = ltt_add_time((*ptime),ltt_sub_time(lastTime,event->time));
145 }
146}
147
148/* Specific hooks to note process and state changes, compute the following values: number of bytes read/written,
149 time elapsed, user, system, waiting, time spent in each system call,
150 name for each process. */
151
152maintain the process table, process state, last time... what we are waiting for
153
154syscall_entry_hook
155syscall_exit_hook
156trap_entry_hook
157trap_exit_hook
158irq_entry_hook
159irq_exit_hook
160sched_change_hook -> not waiting
161fork_hook -> wait fork
162wait_hook -> waiting
163wakeup_hook -> not waiting add up waiting time
164exit_hook
165exec_hook -> note file name
166open_hook -> keep track of fd/name
167close_hook -> keep track of fd
168read_hook -> bytes read, if server CPU for client...
169write_hook -> bytes written
170select_hook -> wait reason
171poll_hook -> wait reason
172mmap_hook -> keep track of fd
173munmap_hook -> keep track of fd
174setitimer_hook -> wait reason
175settimeout_hook -> wait reason
176sockcreate_hook -> client/server
177sockbind_hook -> client/server
178sockaccept_hook -> client/server
179sockconnect_hook -> client/server
180/* Close the output file and print the statistics, globally for all CPUs and
181 processes, per CPU, per process. */
182
183static void after_trace_hook(gpointer hook_data, gpointer call_data)
184{
185 lttTrace t;
186
187 unsigned nbEvents = 0;
188
189 t = (lttTrace *)call_data;
190
191 fprintf(dump_fp,"\n");
192 fclose(dump_fp);
193
194 if(syscall_stats) {
195 fprintf(dump_fp,"\n\nStatistics\n\n");
196
197 /* Trace start, end and duration */
198
199 fprintf(dump_fp,"Trace started %s, ended %s, duration %s",
200 ltt_format_time(t->startTime),ltt_format_time(t->endTime),
201 ltt_format_time(ltt_sub_time(t->endTime,t->startTime)));
202
203 /* Number of events of each type */
204
205 for(i = 0 ; i < t->nbEventTypes ; i++) {
206 nbEvents += eventsCounters[i];
207 if(eventsCounters[i] > 0)
208 fprintf(dump_fp,"%s: %u\n",t->types[i]->name,eventsCounters[i]);
209 }
210 fprintf(dump_fp,"\n\nTotal number of events: %u\n",nbEvents);
211
212 /* Print the details for each process */
213 }
214}
215
216
217
This page took 0.029923 seconds and 4 git commands to generate.