80 columns formatting
[lttv.git] / ltt / branches / poly / lttv / plugins / asciiDump.c
1
2 #include "ltt_module.h"
3
4 /* This module dumps all events in a simple ascii format */
5
6 static gboolean
7 ascii_dump = FALSE,
8 syscall_stats = FALSE;
9
10 static gchar *dump_file = NULL;
11
12 static FILE *dump_fp = stdout;
13
14 struct 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
20 static void after_options_hook(gpointer hook_data, gpointer call_data);
21
22 static void before_trace_hook(gpointer hook_data, gpointer call_data);
23
24 static void after_trace_hook(gpointer hook_data, gpointer call_data);
25
26 static void events_hook(gpointer hook_data, gpointer call_data);
27
28 void 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
37 static 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
51 static unsigned *eventsCounters;
52
53 struct CPUState {
54 lttProcess *current_process;
55 lttStatKey *key;
56 lttTime lastTime;
57 } *CPUStates;
58
59 static 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
77 static 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
152 maintain the process table, process state, last time... what we are waiting for
153
154 syscall_entry_hook
155 syscall_exit_hook
156 trap_entry_hook
157 trap_exit_hook
158 irq_entry_hook
159 irq_exit_hook
160 sched_change_hook -> not waiting
161 fork_hook -> wait fork
162 wait_hook -> waiting
163 wakeup_hook -> not waiting add up waiting time
164 exit_hook
165 exec_hook -> note file name
166 open_hook -> keep track of fd/name
167 close_hook -> keep track of fd
168 read_hook -> bytes read, if server CPU for client...
169 write_hook -> bytes written
170 select_hook -> wait reason
171 poll_hook -> wait reason
172 mmap_hook -> keep track of fd
173 munmap_hook -> keep track of fd
174 setitimer_hook -> wait reason
175 settimeout_hook -> wait reason
176 sockcreate_hook -> client/server
177 sockbind_hook -> client/server
178 sockaccept_hook -> client/server
179 sockconnect_hook -> client/server
180 /* Close the output file and print the statistics, globally for all CPUs and
181 processes, per CPU, per process. */
182
183 static 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.033204 seconds and 4 git commands to generate.