gst-indent run on core
[platform/upstream/gstreamer.git] / gst / gsttrace.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *
5  * gsttrace.c: Tracing functions (depracated)
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #include <string.h>
30
31 #include "gst_private.h"
32
33 #include "gstlog.h"
34 #include "gsttrace.h"
35
36 static
37 #ifdef __inline__
38   __inline__
39 #endif
40     void
41 read_tsc (gint64 * dst)
42 {
43 #ifdef HAVE_RDTSC
44   guint64 tsc;
45   __asm__ __volatile__ ("rdtsc":"=A" (tsc));
46
47   *dst = tsc;
48 #else
49   *dst = 0;
50 #endif
51 }
52
53 void
54 gst_trace_read_tsc (gint64 * dst)
55 {
56   read_tsc (dst);
57 }
58
59 GstTrace *_gst_trace_default = NULL;
60 gint _gst_trace_on = 1;
61
62 GstTrace *
63 gst_trace_new (gchar * filename, gint size)
64 {
65   GstTrace *trace = g_malloc (sizeof (GstTrace));
66
67   g_return_val_if_fail (trace != NULL, NULL);
68   trace->filename = g_strdup (filename);
69   g_print ("opening '%s'\n", trace->filename);
70   trace->fd =
71       open (trace->filename, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
72   perror ("opening trace file");
73   g_return_val_if_fail (trace->fd > 0, NULL);
74   trace->buf = g_malloc (size * sizeof (GstTraceEntry));
75   g_return_val_if_fail (trace->buf != NULL, NULL);
76   trace->bufsize = size;
77   trace->bufoffset = 0;
78
79   return trace;
80 }
81
82 void
83 gst_trace_destroy (GstTrace * trace)
84 {
85   g_return_if_fail (trace != NULL);
86   g_return_if_fail (trace->buf != NULL);
87
88   if (gst_trace_get_remaining (trace) > 0)
89     gst_trace_flush (trace);
90   close (trace->fd);
91   g_free (trace->buf);
92   g_free (trace);
93 }
94
95 void
96 gst_trace_flush (GstTrace * trace)
97 {
98   if (!trace) {
99     trace = _gst_trace_default;
100     if (!trace)
101       return;
102   }
103
104   write (trace->fd, trace->buf, trace->bufoffset * sizeof (GstTraceEntry));
105   trace->bufoffset = 0;
106 }
107
108 void
109 gst_trace_text_flush (GstTrace * trace)
110 {
111   int i;
112
113 #define STRSIZE (20 + 1 + 10 + 1 + 10 + 1 + 112 + 1 + 1)
114   char str[STRSIZE];
115
116   if (!trace) {
117     trace = _gst_trace_default;
118     if (!trace)
119       return;
120   }
121
122   for (i = 0; i < trace->bufoffset; i++) {
123     snprintf (str, STRSIZE, "%20" G_GINT64_FORMAT " %10d %10d %s\n",
124         trace->buf[i].timestamp,
125         trace->buf[i].sequence, trace->buf[i].data, trace->buf[i].message);
126     write (trace->fd, str, strlen (str));
127   }
128   trace->bufoffset = 0;
129 #undef STRSIZE
130 }
131
132 void
133 gst_trace_set_default (GstTrace * trace)
134 {
135   g_return_if_fail (trace != NULL);
136   _gst_trace_default = trace;
137 }
138
139 void
140 _gst_trace_add_entry (GstTrace * trace, guint32 seq, guint32 data, gchar * msg)
141 {
142   GstTraceEntry *entry;
143
144   if (!trace) {
145     trace = _gst_trace_default;
146     if (!trace)
147       return;
148   }
149
150   entry = trace->buf + trace->bufoffset;
151   read_tsc (&(entry->timestamp));
152   entry->sequence = seq;
153   entry->data = data;
154   strncpy (entry->message, msg, 112);
155   trace->bufoffset++;
156
157   gst_trace_flush (trace);
158 }
159
160
161 /* global flags */
162 static GstAllocTraceFlags _gst_trace_flags = 0;
163
164 /* list of registered tracers */
165 static GList *_gst_alloc_tracers = NULL;
166
167 /**
168  * gst_alloc_trace_available:
169  *
170  * Check if alloc tracing was commiled into the core
171  *
172  * Returns: TRUE if the core was compiled with alloc
173  * tracing enabled.
174  */
175 gboolean
176 gst_alloc_trace_available (void)
177 {
178 #ifdef GST_DISABLE_ALLOC_TRACE
179   return FALSE;
180 #else
181   return TRUE;
182 #endif
183 }
184
185 /**
186  * _gst_alloc_trace_register:
187  * @name: the name of the new alloc trace object.
188  *
189  * Register an get a handle to a GstAllocTrace object that
190  * can be used to trace memory allocations.
191  *
192  * Returns: A handle to a GstAllocTrace.
193  */
194 GstAllocTrace *
195 _gst_alloc_trace_register (const gchar * name)
196 {
197   GstAllocTrace *trace;
198
199   g_return_val_if_fail (name, NULL);
200
201   trace = g_new0 (GstAllocTrace, 1);
202   trace->name = g_strdup (name);
203   trace->live = 0;
204   trace->mem_live = NULL;
205   trace->flags = _gst_trace_flags;
206
207   _gst_alloc_tracers = g_list_prepend (_gst_alloc_tracers, trace);
208
209   return trace;
210 }
211
212 /**
213  * gst_alloc_trace_list:
214  *
215  * Get a list of all registered alloc trace objects.
216  *
217  * Returns: a GList of GstAllocTrace objects.
218  */
219 const GList *
220 gst_alloc_trace_list (void)
221 {
222   return _gst_alloc_tracers;
223 }
224
225 /**
226  * gst_alloc_trace_live_all:
227  *
228  * Returns the total number of live registered alloc trace objects.
229  */
230 int
231 gst_alloc_trace_live_all (void)
232 {
233   GList *walk = _gst_alloc_tracers;
234   int num = 0;
235
236   while (walk) {
237     GstAllocTrace *trace = (GstAllocTrace *) walk->data;
238
239     num += trace->live;
240
241     walk = g_list_next (walk);
242   }
243
244   return num;
245 }
246
247 /**
248  * gst_alloc_trace_print_all:
249  *
250  * Print the status of all registered alloc trace objectes.
251  */
252 void
253 gst_alloc_trace_print_all (void)
254 {
255   GList *walk = _gst_alloc_tracers;
256
257   while (walk) {
258     GstAllocTrace *trace = (GstAllocTrace *) walk->data;
259
260     gst_alloc_trace_print (trace);
261
262     walk = g_list_next (walk);
263   }
264 }
265
266 /**
267  * gst_alloc_trace_set_flags_all:
268  * @flags: the options to enable
269  *
270  * Enable the specified options on all registered alloc trace
271  * objects.
272  */
273 void
274 gst_alloc_trace_set_flags_all (GstAllocTraceFlags flags)
275 {
276   GList *walk = _gst_alloc_tracers;
277
278   while (walk) {
279     GstAllocTrace *trace = (GstAllocTrace *) walk->data;
280
281     g_print ("set flags on %p\n", trace);
282     gst_alloc_trace_set_flags (trace, flags);
283
284     walk = g_list_next (walk);
285   }
286   _gst_trace_flags = flags;
287 }
288
289 /**
290  * gst_alloc_trace_get:
291  * @name: the name of the alloc trace object
292  *
293  * Get the named alloc trace object.
294  *
295  * Returns: a GstAllocTrace with the given name or NULL when
296  * no alloc tracer was registered with that name.
297  */
298 GstAllocTrace *
299 gst_alloc_trace_get (const gchar * name)
300 {
301   GList *walk = _gst_alloc_tracers;
302
303   g_return_val_if_fail (name, NULL);
304
305   while (walk) {
306     GstAllocTrace *trace = (GstAllocTrace *) walk->data;
307
308     if (!strcmp (trace->name, name))
309       return trace;
310
311     walk = g_list_next (walk);
312   }
313   return NULL;
314 }
315
316 /**
317  * gst_alloc_trace_print:
318  * @trace: the GstAllocTrace to print
319  *
320  * Print the status of the given GstAllocTrace.
321  */
322 void
323 gst_alloc_trace_print (const GstAllocTrace * trace)
324 {
325   GSList *mem_live;
326
327   g_return_if_fail (trace != NULL);
328
329   g_print ("%s (%p): flags %d", trace->name, trace, trace->flags);
330
331   if (trace->flags & GST_ALLOC_TRACE_LIVE) {
332     g_print (", live %d", trace->live);
333   }
334   if (trace->flags & GST_ALLOC_TRACE_MEM_LIVE) {
335     mem_live = trace->mem_live;
336
337     if (!mem_live) {
338       g_print (", no live memory");
339     } else {
340       g_print (", dumping live memory: ");
341
342       while (mem_live) {
343         g_print ("%p ", mem_live->data);
344         mem_live = g_slist_next (mem_live);
345       }
346       g_print ("\ntotal %d", g_slist_length (trace->mem_live));
347     }
348   }
349   g_print ("\n");
350 }
351
352 /**
353  * gst_alloc_trace_set_flags:
354  * @trace: the GstAllocTrace 
355  * @flags: flags to set 
356  *
357  * Enable the given features on the given GstAllocTrace object.
358  */
359 void
360 gst_alloc_trace_set_flags (GstAllocTrace * trace, GstAllocTraceFlags flags)
361 {
362   g_return_if_fail (trace != NULL);
363
364   trace->flags = flags;
365 }