1 /* This file is part of the Linux Trace Toolkit Graphic User Interface
2 * Copyright (C) 2003-2004 Mathieu Desnoyers
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;
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.
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,
19 /* This file is the API used to launch any background computation on a trace */
21 /* Here is the implementation of the API */
23 #include <sys/types.h>
28 #include <ltt/trace.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>
37 typedef struct _BackgroundRequest
{
38 LttvAttributeName module_name
; /* Hook path in global attributes,
39 where all standard hooks under computation/.
41 LttvTrace
*trace
; /* trace concerned */
44 typedef struct _BackgroundNotify
{
46 LttvTrace
*trace
; /* trace */
48 LttvTracesetContextPosition
*notify_position
;
49 LttvHooks
*notify
; /* Hook to call when the notify is
50 passed, or at the end of trace */
55 /* Get a trace by its path name.
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
62 LttvTrace
*lttvwindowtraces_get_trace_by_name(gchar
*path
)
64 LttvAttribute
*attribute
= lttv_global_attributes();
67 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
68 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
72 g_assert(trace_v
!= NULL
);
74 trace
= lttv_trace(trace_v
);
75 g_assert(trace
!= NULL
);
76 name
= ltt_trace_name(trace
);
78 if(strcmp(name
, path
) == 0) {
87 /* Get a trace by its number identifier */
89 LttvTrace
*lttvwindowtraces_get_trace(guint num
)
91 LttvAttribute
*g_attribute
= lttv_global_attributes();
92 LttvAttribute
*attribute
;
93 LttvAttributeType type
;
94 LttvAttributeName name
;
95 LttvAttributeValue value
;
98 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
101 type
= lttv_iattribute_get(LTTV_IATTRIBUTE(attribute
), num
, &name
, &value
);
103 if(type
== LTTV_POINTER
) {
104 return (LttvTrace
*)*(value
.v_pointer
);
110 /* Total number of traces */
112 guint
lttvwindowtraces_get_number()
114 LttvAttribute
*g_attribute
= lttv_global_attributes();
115 LttvAttribute
*attribute
;
116 LttvAttributeValue value
;
119 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
122 return ( lttv_iattribute_get_number(LTTV_IATTRIBUTE(attribute
)) );
125 /* Add a trace to the global attributes */
127 void lttvwindowtraces_add_trace(LttvTrace
*trace
)
129 LttvAttribute
*g_attribute
= lttv_global_attributes();
130 LttvAttribute
*attribute
;
131 LttvAttributeValue value
;
134 gchar attribute_path
[PATH_MAX
];
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
)));
142 snprintf(attribute_path
, PATH_MAX
, "%lu:%lu", buf
.st_dev
, buf
.st_ino
) >= 0);
145 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
148 value
= lttv_attribute_add(attribute
,
149 g_quark_from_string(attribute_path
),
152 *(value
.v_pointer
) = (gpointer
)trace
;
155 /* Remove a trace from the global attributes */
157 void lttvwindowtraces_remove_trace(LttvTrace
*trace
)
159 LttvAttribute
*g_attribute
= lttv_global_attributes();
160 LttvAttribute
*attribute
;
161 LttvAttributeValue value
;
165 LTTV_ATTRIBUTE(lttv_iattribute_find_subdir(LTTV_IATTRIBUTE(g_attribute
),
168 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
169 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
171 g_assert(trace_v
!= NULL
);
173 if(trace_v
== trace
) {
175 lttv_attribute_remove(attribute
, i
);
183 * Function to request data from a specific trace
185 * The memory allocated for the request will be managed by the API.
187 * @param trace the trace to compute
188 * @param module_name the name of the module which registered global computation
192 void lttvwindowtraces_background_request_queue
193 (LttvTrace
*trace
, gchar
*module_name
)
195 BackgroundRequest
*bg_req
;
196 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
197 LttvAttributeValue value
;
201 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
205 slist
= (GSList
**)(value
.v_pointer
);
207 bg_req
= g_new(BackgroundRequest
,1);
208 bg_req
->module_name
= g_quark_from_string(module_name
);
209 bg_req
->trace
= trace
;
211 *slist
= g_slist_append(*slist
, bg_req
);
215 * Remove a background request from a trace.
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.
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.
226 * @param trace the trace to compute
227 * @param module_name the name of the module which registered global computation
231 void lttvwindowtraces_background_request_remove
232 (LttvTrace
*trace
, gchar
*module_name
)
234 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
235 LttvAttributeValue value
;
239 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
243 slist
= (GSList
**)(value
.v_pointer
);
245 for(iter
=*slist
;iter
!=NULL
;) {
246 BackgroundRequest
*bg_req
=
247 (BackgroundRequest
*)iter
->data
;
249 if(bg_req
->module_name
== g_quark_from_string(module_name
)) {
250 GSList
*rem_iter
= iter
;
251 iter
=g_slist_next(iter
);
253 *slist
= g_slist_delete_link(*slist
, rem_iter
);
255 iter
=g_slist_next(iter
);
262 * Register a callback to be called when requested data is passed in the next
263 * queued background processing.
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
272 void lttvwindowtraces_background_notify_queue
276 const LttvTracesetContextPosition
*notify_position
,
277 const LttvHooks
*notify
)
279 BackgroundNotify
*bg_notify
;
280 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
281 LttvAttributeValue value
;
284 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
288 slist
= (GSList
**)(value
.v_pointer
);
291 bg_notify
= g_new(BackgroundNotify
,1);
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
,
299 bg_notify
->notify
= lttv_hooks_new();
300 lttv_hooks_add_list(bg_notify
->notify
, notify
);
302 *slist
= g_slist_append(*slist
, bg_notify
);
306 * Register a callback to be called when requested data is passed in the current
307 * background processing.
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
316 void lttvwindowtraces_background_notify_current
320 const LttvTracesetContextPosition
*notify_position
,
321 const LttvHooks
*notify
)
323 BackgroundNotify
*bg_notify
;
324 LttvAttribute
*attribute
= lttv_trace_attribute(trace
);
325 LttvAttributeValue value
;
328 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
332 slist
= (GSList
**)(value
.v_pointer
);
334 bg_notify
= g_new(BackgroundNotify
,1);
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
,
342 bg_notify
->notify
= lttv_hooks_new();
343 lttv_hooks_add_list(bg_notify
->notify
, notify
);
345 *slist
= g_slist_append(*slist
, bg_notify
);
349 * Removes all the notifications requests from a specific viewer.
351 * @param owner owner of the background notification
354 void lttvwindowtraces_background_notify_remove(gpointer owner
)
358 for(i
=0;i
<lttvwindowtraces_get_number();i
++) {
359 LttvAttribute
*attribute
;
360 LttvAttributeValue value
;
361 LttvTrace
*trace_v
= lttvwindowtraces_get_trace(i
);
365 g_assert(trace_v
!= NULL
);
367 LttvAttribute
*t_a
= lttv_trace_attribute(trace_v
);
369 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
373 slist
= (GSList
**)(value
.v_pointer
);
375 for(iter
=*slist
;iter
!=NULL
;) {
377 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
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
);
386 g_slist_remove_link(*slist
, rem_iter
);
388 iter
=g_slist_next(iter
);
392 g_assert(lttv_iattribute_find(LTTV_IATTRIBUTE(attribute
),
396 slist
= (GSList
**)(value
.v_pointer
);
398 for(iter
=*slist
;iter
!=NULL
;) {
400 BackgroundNotify
*bg_notify
= (BackgroundNotify
*)iter
->data
;
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
);
409 g_slist_remove_link(*slist
, rem_iter
);
411 iter
=g_slist_next(iter
);