typo
[lttv.git] / ltt / branches / poly / lttv / modules / gui / lttvwindow / lttvwindow / lttvwindowtraces.c
CommitLineData
a1a2b649 1/* This file is part of the Linux Trace Toolkit Graphic User Interface
2 * Copyright (C) 2003-2004 Mathieu Desnoyers
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
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
16 * MA 02111-1307, USA.
17 */
18
19/* This file is the API used to launch any background computation on a trace */
20
21/* Here is the implementation of the API */
22
0fdb8bb0 23#include <sys/types.h>
24#include <sys/stat.h>
25#include <unistd.h>
26
a1a2b649 27#include <ltt/time.h>
28#include <ltt/trace.h>
29#include <glib.h>
30#include <lttv/lttv.h>
31#include <lttv/traceset.h>
32#include <lttv/attribute.h>
33#include <lttv/tracecontext.h>
34#include <lttvwindow/lttvwindowtraces.h>
35
36
37typedef struct _BackgroundRequest {
38 LttvAttributeName module_name; /* Hook path in global attributes,
39 where all standard hooks under computation/.
40 i.e. modulename */
41 LttvTrace *trace; /* trace concerned */
42} BackgroundRequest;
43
44typedef struct _BackgroundNotify {
45 gpointer owner;
46 LttvTrace *trace; /* trace */
47 LttTime notify_time;
48 LttvTracesetContextPosition *notify_position;
49 LttvHooks *notify; /* Hook to call when the notify is
50 passed, or at the end of trace */
51} BackgroundNotify;
52
53
54
55/* Get a trace by its path name.
56 *
57 * @param path path of the trace on the virtual file system.
58 * @return Pointer to trace if found
59 * NULL is returned if the trace is not present
60 */
61
62LttvTrace *lttvwindowtraces_get_trace_by_name(gchar *path)
63{
64 LttvAttribute *attribute = lttv_global_attributes();
65 guint i;
66
67 for(i=0;i<lttvwindowtraces_get_number();i++) {
68 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
69 LttTrace *trace;
70 gchar *name;
71
72 g_assert(trace_v != NULL);
73
74 trace = lttv_trace(trace_v);
75 g_assert(trace != NULL);
76 name = ltt_trace_name(trace);
77
78 if(strcmp(name, path) == 0) {
79 /* Found */
80 return trace_v;
81 }
82 }
83
84 return NULL;
85}
86
87/* Get a trace by its number identifier */
88
89LttvTrace *lttvwindowtraces_get_trace(guint num)
90{
91 LttvAttribute *g_attribute = lttv_global_attributes();
92 LttvAttribute *attribute;
93 LttvAttributeType type;
94 LttvAttributeName name;
95 LttvAttributeValue value;
96
97 g_assert(attribute =
98 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
99 LTTV_TRACES)));
100
101 type = lttv_iattribute_get(LTTV_IATTRIBUTE(attribute), num, &name, &value);
102
103 if(type == LTTV_POINTER) {
104 return (LttvTrace *)*(value.v_pointer);
105 }
106
107 return NULL;
108}
109
110/* Total number of traces */
111
112guint lttvwindowtraces_get_number()
113{
114 LttvAttribute *g_attribute = lttv_global_attributes();
115 LttvAttribute *attribute;
116 LttvAttributeValue value;
117
118 g_assert(attribute =
119 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
120 LTTV_TRACES)));
121
122 return ( lttv_iattribute_get_number(LTTV_IATTRIBUTE(attribute)) );
123}
124
125/* Add a trace to the global attributes */
126
127void lttvwindowtraces_add_trace(LttvTrace *trace)
128{
129 LttvAttribute *g_attribute = lttv_global_attributes();
130 LttvAttribute *attribute;
131 LttvAttributeValue value;
132 guint num;
0fdb8bb0 133 struct stat buf;
134 gchar attribute_path[PATH_MAX];
a1a2b649 135
0fdb8bb0 136 if(stat(ltt_trace_name(lttv_trace(trace)), &buf)) {
137 g_warning("lttvwindowtraces_add_trace: Trace %s not found",
138 ltt_trace_name(lttv_trace(trace)));
139 return;
140 }
141 g_assert(
142 snprintf(attribute_path, PATH_MAX, "%lu:%lu", buf.st_dev, buf.st_ino) >= 0);
143
a1a2b649 144 g_assert(attribute =
145 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
146 LTTV_TRACES)));
0fdb8bb0 147
a1a2b649 148 value = lttv_attribute_add(attribute,
0fdb8bb0 149 g_quark_from_string(attribute_path),
a1a2b649 150 LTTV_POINTER);
151
152 *(value.v_pointer) = (gpointer)trace;
153}
154
155/* Remove a trace from the global attributes */
156
157void lttvwindowtraces_remove_trace(LttvTrace *trace)
158{
159 LttvAttribute *g_attribute = lttv_global_attributes();
160 LttvAttribute *attribute;
161 LttvAttributeValue value;
162 guint i;
163
164 g_assert(attribute =
165 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute),
166 LTTV_TRACES)));
167
168 for(i=0;i<lttvwindowtraces_get_number();i++) {
169 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
170
171 g_assert(trace_v != NULL);
172
173 if(trace_v == trace) {
174 /* Found */
175 lttv_attribute_remove(attribute, i);
176 return;
177 }
178 }
179}
180
181
182/**
183 * Function to request data from a specific trace
184 *
185 * The memory allocated for the request will be managed by the API.
186 *
187 * @param trace the trace to compute
188 * @param module_name the name of the module which registered global computation
189 * hooks.
190 */
191
192void lttvwindowtraces_background_request_queue
193 (LttvTrace *trace, gchar *module_name)
194{
195 BackgroundRequest *bg_req;
196 LttvAttribute *attribute = lttv_trace_attribute(trace);
197 LttvAttributeValue value;
198 GSList **slist;
199 guint num;
200
201 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
202 LTTV_REQUESTS_QUEUE,
203 LTTV_POINTER,
204 &value));
205 slist = (GSList**)(value.v_pointer);
206
207 bg_req = g_new(BackgroundRequest,1);
208 bg_req->module_name = g_quark_from_string(module_name);
209 bg_req->trace = trace;
210
211 *slist = g_slist_append(*slist, bg_req);
212}
213
214/**
215 * Remove a background request from a trace.
216 *
217 * This should ONLY be used by the modules which registered the global hooks
218 * (module_name). If this is called by the viewers, it may lead to incomplete
219 * and incoherent background processing information.
220 *
221 * Even if the module which deals with the hooks removes the background
222 * requests, it may cause a problem if the module gets loaded again in the
223 * session : the data will be partially calculated. The calculation function
224 * must deal with this case correctly.
225 *
226 * @param trace the trace to compute
227 * @param module_name the name of the module which registered global computation
228 * hooks.
229 */
230
231void lttvwindowtraces_background_request_remove
232 (LttvTrace *trace, gchar *module_name)
233{
234 LttvAttribute *attribute = lttv_trace_attribute(trace);
235 LttvAttributeValue value;
236 GSList *iter = NULL;
237 GSList **slist;
238
239 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
240 LTTV_REQUESTS_QUEUE,
241 LTTV_POINTER,
242 &value));
243 slist = (GSList**)(value.v_pointer);
244
245 for(iter=*slist;iter!=NULL;) {
246 BackgroundRequest *bg_req =
247 (BackgroundRequest *)iter->data;
248
249 if(bg_req->module_name == g_quark_from_string(module_name)) {
250 GSList *rem_iter = iter;
251 iter=g_slist_next(iter);
252 g_free(bg_req);
253 *slist = g_slist_delete_link(*slist, rem_iter);
254 } else {
255 iter=g_slist_next(iter);
256 }
257 }
258}
259
260
261/**
262 * Register a callback to be called when requested data is passed in the next
263 * queued background processing.
264 *
265 * @param owner owner of the background notification
266 * @param trace the trace computed
267 * @param notify_time time when notification hooks must be called
268 * @param notify_position position when notification hooks must be called
269 * @param notify Hook to call when the notify position is passed
270 */
271
272void lttvwindowtraces_background_notify_queue
273 (gpointer owner,
274 LttvTrace *trace,
275 LttTime notify_time,
276 const LttvTracesetContextPosition *notify_position,
277 const LttvHooks *notify)
278{
279 BackgroundNotify *bg_notify;
280 LttvAttribute *attribute = lttv_trace_attribute(trace);
281 LttvAttributeValue value;
282 GSList **slist;
283
284 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
285 LTTV_NOTIFY_QUEUE,
286 LTTV_POINTER,
287 &value));
288 slist = (GSList**)(value.v_pointer);
289
290
291 bg_notify = g_new(BackgroundNotify,1);
292
293 bg_notify->owner = owner;
294 bg_notify->trace = trace;
295 bg_notify->notify_time = notify_time;
296 bg_notify->notify_position = ltt_traceset_context_position_new();
297 lttv_traceset_context_position_copy(bg_notify->notify_position,
298 notify_position);
299 bg_notify->notify = lttv_hooks_new();
300 lttv_hooks_add_list(bg_notify->notify, notify);
301
302 *slist = g_slist_append(*slist, bg_notify);
303}
304
305/**
306 * Register a callback to be called when requested data is passed in the current
307 * background processing.
308 *
309 * @param owner owner of the background notification
310 * @param trace the trace computed
311 * @param notify_time time when notification hooks must be called
312 * @param notify_position position when notification hooks must be called
313 * @param notify Hook to call when the notify position is passed
314 */
315
316void lttvwindowtraces_background_notify_current
317 (gpointer owner,
318 LttvTrace *trace,
319 LttTime notify_time,
320 const LttvTracesetContextPosition *notify_position,
321 const LttvHooks *notify)
322{
323 BackgroundNotify *bg_notify;
324 LttvAttribute *attribute = lttv_trace_attribute(trace);
325 LttvAttributeValue value;
326 GSList **slist;
327
328 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
329 LTTV_NOTIFY_CURRENT,
330 LTTV_POINTER,
331 &value));
332 slist = (GSList**)(value.v_pointer);
333
334 bg_notify = g_new(BackgroundNotify,1);
335
336 bg_notify->owner = owner;
337 bg_notify->trace = trace;
338 bg_notify->notify_time = notify_time;
339 bg_notify->notify_position = ltt_traceset_context_position_new();
340 lttv_traceset_context_position_copy(bg_notify->notify_position,
341 notify_position);
342 bg_notify->notify = lttv_hooks_new();
343 lttv_hooks_add_list(bg_notify->notify, notify);
344
345 *slist = g_slist_append(*slist, bg_notify);
346}
347
348/**
349 * Removes all the notifications requests from a specific viewer.
350 *
351 * @param owner owner of the background notification
352 */
353
354void lttvwindowtraces_background_notify_remove(gpointer owner)
355{
356 guint i;
357
358 for(i=0;i<lttvwindowtraces_get_number();i++) {
359 LttvAttribute *attribute;
360 LttvAttributeValue value;
361 LttvTrace *trace_v = lttvwindowtraces_get_trace(i);
362 GSList **slist;
363 GSList *iter = NULL;
364
365 g_assert(trace_v != NULL);
366
367 LttvAttribute *t_a = lttv_trace_attribute(trace_v);
368
369 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
370 LTTV_NOTIFY_QUEUE,
371 LTTV_POINTER,
372 &value));
373 slist = (GSList**)(value.v_pointer);
374
375 for(iter=*slist;iter!=NULL;) {
376
377 BackgroundNotify *bg_notify = (BackgroundNotify*)iter->data;
378
379 if(bg_notify->owner == owner) {
380 GSList *rem_iter = iter;
381 iter=g_slist_next(iter);
382 lttv_traceset_context_position_destroy(
383 bg_notify->notify_position);
384 lttv_hooks_destroy(bg_notify->notify);
385 g_free(bg_notify);
386 g_slist_remove_link(*slist, rem_iter);
387 } else {
388 iter=g_slist_next(iter);
389 }
390 }
391
392 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute),
393 LTTV_NOTIFY_CURRENT,
394 LTTV_POINTER,
395 &value));
396 slist = (GSList**)(value.v_pointer);
397
398 for(iter=*slist;iter!=NULL;) {
399
400 BackgroundNotify *bg_notify = (BackgroundNotify*)iter->data;
401
402 if(bg_notify->owner == owner) {
403 GSList *rem_iter = iter;
404 iter=g_slist_next(iter);
405 lttv_traceset_context_position_destroy(
406 bg_notify->notify_position);
407 lttv_hooks_destroy(bg_notify->notify);
408 g_free(bg_notify);
409 g_slist_remove_link(*slist, rem_iter);
410 } else {
411 iter=g_slist_next(iter);
412 }
413 }
414 }
415}
416
This page took 0.036497 seconds and 4 git commands to generate.