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