]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/callgrind/events.c
c0654143e08d999474371d015ad938cf3f3045ea
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / callgrind / events.c
1 /*--------------------------------------------------------------------*/
2 /*--- Callgrind                                                    ---*/
3 /*---                                                     events.c ---*/
4 /*--------------------------------------------------------------------*/
5
6 /*
7    This file is part of Callgrind, a Valgrind tool for call tracing.
8
9    Copyright (C) 2002-2010, Josef Weidendorfer (Josef.Weidendorfer@gmx.de)
10
11    This program is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License as
13    published by the Free Software Foundation; either version 2 of the
14    License, or (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful, but
17    WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24    02111-1307, USA.
25
26    The GNU General Public License is contained in the file COPYING.
27 */
28
29 #include "global.h"
30
31 #define MAX_EVENTTYPE 20
32
33 static EventType eventtype[MAX_EVENTTYPE];
34 static Int eventtype_count = 0;
35
36 EventType* CLG_(register_eventtype)(Char* name)
37 {
38   EventType* et;
39
40   if (eventtype_count == MAX_EVENTTYPE) {
41     VG_(printf)("\nMore than %d event types used!\n"
42                 "Increase MAX_EVENTTYPE in ct_events.c and recomile this tool!\n",
43                 MAX_EVENTTYPE);
44     VG_(tool_panic)("Too many event types requested.");
45   }
46
47   et = &(eventtype[eventtype_count]);
48   et->id = eventtype_count; 
49   et->name = (UChar*) VG_(strdup)("cl.events.re.1", name);
50   et->description = 0;
51
52   eventtype_count++;
53
54   return et;
55 }
56
57
58 EventType* CLG_(get_eventtype)(Char* name)
59 {
60   Int i;
61
62   for(i=0;i<eventtype_count;i++)
63     if (VG_(strcmp)(eventtype[i].name, name) == 0)
64       return eventtype+i;
65   return 0;
66 }
67
68 EventType* CLG_(get_eventtype_byindex)(Int id)
69 {
70   if ((id >= 0) && (id < eventtype_count))
71     return eventtype+id;
72   return 0;
73 }
74
75 /* Allocate space for an event set */
76 EventSet* CLG_(get_eventset)(Char* n, Int capacity)
77 {
78   EventSet* es;
79
80   es = (EventSet*) CLG_MALLOC("cl.events.geSet.1",
81                                sizeof(EventSet) +
82                                capacity * sizeof(EventSetEntry));
83   es->capacity = capacity;
84   es->size = 0;
85   es->name = n;
86
87   return es;
88 }
89
90 /* Incorporate a event type into a set, get start offset */
91 Int CLG_(add_eventtype)(EventSet* es, EventType* t)
92 {
93   Int offset = es->size;
94   if (es->capacity - offset < 1) return -1;
95
96   es->size++;
97   es->e[offset].type = t;
98   es->e[offset].nextTop = es->size;
99
100   return offset;
101 }
102
103 /* Incorporate one event set into another, get start offset */
104 Int CLG_(add_eventset)(EventSet* dst, EventSet* src)
105 {
106   Int offset = dst->size, i;
107   if (!src || (src->size == 0)) return offset;
108
109   if (dst->capacity - offset < src->size) return -1;
110   
111   for(i=0;i<src->size;i++) {
112     dst->e[offset+i].type = src->e[i].type;
113     dst->e[offset+i].nextTop = src->e[i].nextTop + offset;
114   }
115   dst->size += src->size;
116
117   return offset;
118 }
119
120 /* Incorporate two event types into a set, with second < first */
121 Int CLG_(add_dep_event2)(EventSet* es, EventType* e1, EventType* e2)
122 {
123   Int offset = es->size;
124
125   if (es->capacity - offset < 2) return -1;
126
127   es->size += 2;
128   es->e[offset].type = e1;
129   es->e[offset].nextTop = es->size;
130   es->e[offset+1].type = e2;
131   es->e[offset+1].nextTop = es->size;
132   
133   return offset;
134 }
135
136 /* Incorporate 3 event types into a set, with third < second < first */
137 Int CLG_(add_dep_event3)(EventSet* es,
138                         EventType* e1, EventType* e2, EventType* e3)
139 {
140   Int offset = es->size;
141
142   if (es->capacity - offset < 3) return -1;
143
144   es->size += 3;
145   es->e[offset].type = e1;
146   es->e[offset].nextTop = es->size;
147   es->e[offset+1].type = e2;
148   es->e[offset+1].nextTop = es->size;
149   es->e[offset+2].type = e3;
150   es->e[offset+2].nextTop = es->size;
151   
152   return offset;
153 }
154
155 Int CLG_(add_dep_event4)(EventSet* es,
156                         EventType* e1, EventType* e2,
157                         EventType* e3, EventType* e4)
158 {
159   Int offset = es->size;
160
161   if (es->capacity - offset < 4) return -1;
162
163   es->size += 4;
164   es->e[offset].type = e1;
165   es->e[offset].nextTop = es->size;
166   es->e[offset+1].type = e2;
167   es->e[offset+1].nextTop = es->size;
168   es->e[offset+2].type = e3;
169   es->e[offset+2].nextTop = es->size;
170   es->e[offset+3].type = e4;
171   es->e[offset+3].nextTop = es->size;
172   
173   return offset;
174 }
175
176 /* Returns number of characters written */
177 Int CLG_(sprint_eventset)(Char* buf, EventSet* es)
178 {
179   Int i, pos = 0;
180
181   for(i=0; i< es->size; i++) {
182     if (pos>0) buf[pos++] = ' ';
183     pos += VG_(sprintf)(buf + pos, "%s", es->e[i].type->name);
184   }
185   buf[pos] = 0;
186
187   return pos;
188 }
189
190 /* Get cost array for an event set */
191 ULong* CLG_(get_eventset_cost)(EventSet* es)
192 {
193   return CLG_(get_costarray)(es->capacity);
194 }
195
196 /* Set all costs of an event set to zero */
197 void CLG_(init_cost)(EventSet* es, ULong* cost)
198 {
199   Int i;
200
201   if (!cost) return;
202
203   for(i=0;i<es->capacity;i++)
204     cost[i] = 0;
205 }
206
207 /* Set all costs of an event set to zero */
208 void CLG_(init_cost_lz)(EventSet* es, ULong** cost)
209 {
210   Int i;
211
212   CLG_ASSERT(cost != 0);
213   if (!(*cost))
214     *cost = CLG_(get_eventset_cost)(es);
215
216   for(i=0;i<es->capacity;i++)
217     (*cost)[i] = 0;
218 }
219
220 void CLG_(zero_cost)(EventSet* es, ULong* cost)
221 {
222   Int i;
223
224   if (!cost) return;
225
226   for(i=0;i<es->size;i++)
227     cost[i] = 0;
228 }
229   
230 Bool CLG_(is_zero_cost)(EventSet* es, ULong* cost)
231 {
232   Int i = 0;
233
234   if (!cost) return True;
235
236   while(i<es->size) {
237     if (cost[i] != 0) return False;
238     i = es->e[i].nextTop;
239   }
240   return True;
241 }
242
243 Bool CLG_(is_equal_cost)(EventSet* es, ULong* c1, ULong* c2)
244 {
245   Int i = 0;
246
247   if (!c1) return CLG_(is_zero_cost)(es,c2);
248   if (!c2) return CLG_(is_zero_cost)(es,c1);
249
250   while(i<es->size) {
251     if (c1[i] != c2[i]) return False;
252     if (c1[i] == 0)
253       i = es->e[i].nextTop;
254     else
255       i++;
256   }
257   return True;
258 }
259
260 void CLG_(copy_cost)(EventSet* es, ULong* dst, ULong* src)
261 {
262   Int i;
263
264   if (!src) {
265     CLG_(zero_cost)(es, dst);
266     return;
267   }
268   CLG_ASSERT(dst != 0);
269   
270   for(i=0;i<es->size;i++)
271     dst[i] = src[i];
272 }
273
274 void CLG_(copy_cost_lz)(EventSet* es, ULong** pdst, ULong* src)
275 {
276   Int i;
277   ULong* dst;
278
279   CLG_ASSERT(pdst != 0);
280
281   if (!src) {
282     CLG_(zero_cost)(es, *pdst);
283     return;
284   }
285   dst = *pdst;
286   if (!dst)
287     dst = *pdst = CLG_(get_eventset_cost)(es);
288   
289   for(i=0;i<es->size;i++)
290     dst[i] = src[i];
291 }
292
293 void CLG_(add_cost)(EventSet* es, ULong* dst, ULong* src)
294 {
295   Int i = 0;
296
297   if (!src) return;
298   CLG_ASSERT(dst != 0);
299
300   while(i<es->size) {
301     if (src[i] == 0)
302       i = es->e[i].nextTop;
303     else {
304       dst[i] += src[i];
305       i++;
306     }
307   }
308 }
309
310 void CLG_(add_cost_lz)(EventSet* es, ULong** pdst, ULong* src)
311 {
312   Int i;
313   ULong* dst;
314
315   if (!src) return;
316   CLG_ASSERT(pdst != 0);
317
318   dst = *pdst;
319   if (!dst) {
320     dst = *pdst = CLG_(get_eventset_cost)(es);
321     CLG_(copy_cost)(es,dst,src);
322     return;
323   }
324
325   i = 0;
326   while(i<es->size) {
327     if (src[i] == 0)
328       i = es->e[i].nextTop;
329     else {
330       dst[i] += src[i];
331       i++;
332     }
333   }
334 }
335
336 /* Adds src to dst and zeros src. Returns false if nothing changed */
337 Bool CLG_(add_and_zero_cost)(EventSet* es, ULong* dst, ULong* src)
338 {
339   Int i = 0, j = 0;
340
341   CLG_DEBUGIF(6) {
342     CLG_DEBUG(6, "   add_and_zero_cost(%s, dst %p, src %p)\n", es->name, dst, src);
343     CLG_(print_cost)(-5, es, src);
344   }
345
346   if (!es || !src) return False;
347
348   while(i<es->size) {
349     if (src[i] == 0)
350       i = es->e[i].nextTop;
351     else {
352       dst[i] += src[i];
353       src[i] = 0;
354       i++;
355       j++;
356     }
357   }
358
359   return (j>0);
360 }
361
362 /* Adds src to dst and zeros src. Returns false if nothing changed */
363 Bool CLG_(add_and_zero_cost_lz)(EventSet* es, ULong** pdst, ULong* src)
364 {
365   Int i;
366   ULong* dst;
367
368   if (!src) return False;
369
370   i = 0;
371   while(1) {
372     if (i >= es->size) return False;
373     if (src[i] != 0) break;
374     i = es->e[i].nextTop;
375   }
376
377   CLG_ASSERT(pdst != 0);
378   dst = *pdst;
379   if (!dst) {
380     dst = *pdst = CLG_(get_eventset_cost)(es);
381     CLG_(copy_cost)(es,dst,src);
382     CLG_(zero_cost)(es,src);
383     return True;
384   }
385
386   dst[i] += src[i];
387   src[i] = 0;
388   i++;
389
390   while(i<es->size) {
391     if (src[i] == 0)
392       i = es->e[i].nextTop;
393     else {
394       dst[i] += src[i];
395       src[i] = 0;
396     }
397   }
398
399   return True;
400 }
401
402 /* Adds difference of new and old to dst, and set old to new.
403  * Returns false if nothing changed */
404 Bool CLG_(add_diff_cost)(EventSet* es, ULong* dst, ULong* old, ULong* new_cost)
405 {
406   Int i = 0, j = 0;
407
408   while(i<es->size) {
409     if (new_cost[i] == old[i])
410       i = es->e[i].nextTop;
411     else {
412       dst[i] += new_cost[i] - old[i];
413       old[i] = new_cost[i];
414       i++;
415       j++;
416     }
417   }
418
419   return (j>0);
420 }
421
422 /* Adds difference of new and old to dst, and set old to new.
423  * Returns false if nothing changed */
424 Bool CLG_(add_diff_cost_lz)(EventSet* es, ULong** pdst, 
425                             ULong* old, ULong* new_cost)
426 {
427   Int i;
428   ULong* dst;
429
430   if (!old && !new_cost) return False;
431   CLG_ASSERT(old && new_cost);
432
433   i = 0;
434   while(1) {
435     if (i >= es->size) return False;
436     if (old[i] != new_cost[i]) break;
437     i = es->e[i].nextTop;
438   }
439
440   CLG_ASSERT(pdst != 0);
441   dst = *pdst;
442   if (!dst) {
443     dst = *pdst = CLG_(get_eventset_cost)(es);
444     CLG_(zero_cost)(es,dst);
445   }
446
447   dst[i] += new_cost[i] - old[i];
448   old[i] = new_cost[i];
449   i++;
450
451   while(i<es->size) {
452     if (new_cost[i] == old[i])
453       i = es->e[i].nextTop;
454     else {
455       dst[i] += new_cost[i] - old[i];
456       old[i] = new_cost[i];
457       i++;
458     }
459   }
460
461   return True;
462 }
463
464 /* Returns number of characters written */
465 Int CLG_(sprint_cost)(Char* buf, EventSet* es, ULong* c)
466 {
467   Int i, pos, skipped = 0;
468
469   if (!c || es->size==0) return 0;
470
471   /* At least one entry */
472   pos = VG_(sprintf)(buf, "%llu", c[0]);
473   i = 1;
474
475   while(i<es->size) {
476     if (c[i] == 0) {
477       skipped  += es->e[i].nextTop - i;
478       i = es->e[i].nextTop;
479     }
480     else {
481       while(skipped>0) {
482         buf[pos++] = ' ';
483         buf[pos++] = '0';
484         skipped--;
485       }
486       buf[pos++] = ' ';
487       pos += VG_(sprintf)(buf+pos, "%llu", c[i]);
488       i++;
489     }
490   }
491
492   return pos;
493 }
494
495
496 /* Allocate space for an event mapping */
497 EventMapping* CLG_(get_eventmapping)(EventSet* es)
498 {
499   EventMapping* em;
500
501   CLG_ASSERT(es != 0);
502
503   em = (EventMapping*) CLG_MALLOC("cl.events.geMapping.1",
504                                    sizeof(EventMapping) +
505                                    es->capacity * sizeof(Int));
506   em->capacity = es->capacity;
507   em->size = 0;
508   em->set = es;
509
510   return em;
511 }
512
513 void CLG_(append_event)(EventMapping* em, Char* n)
514 {
515   Int i;
516
517   CLG_ASSERT(em != 0);
518
519   for(i=0; i<em->set->size; i++)
520     if (VG_(strcmp)(n, em->set->e[i].type->name)==0)
521       break;
522   
523   if (i == em->set->size) return;
524
525   CLG_ASSERT(em->capacity > em->size);
526
527   em->index[em->size] = i;
528   em->size++;
529 }
530
531
532 /* Returns number of characters written */
533 Int CLG_(sprint_eventmapping)(Char* buf, EventMapping* em)
534 {
535   Int i, pos = 0;
536
537   CLG_ASSERT(em != 0);
538
539   for(i=0; i< em->size; i++) {
540     if (pos>0) buf[pos++] = ' ';
541     pos += VG_(sprintf)(buf + pos, "%s", em->set->e[em->index[i]].type->name);
542   }
543   buf[pos] = 0;
544
545   return pos;
546 }
547
548 /* Returns number of characters written */
549 Int CLG_(sprint_mappingcost)(Char* buf, EventMapping* em, ULong* c)
550 {
551   Int i, pos, skipped = 0;
552
553   if (!c || em->size==0) return 0;
554
555     /* At least one entry */
556   pos = VG_(sprintf)(buf, "%llu", c[em->index[0]]);
557   i = 1;
558
559   while(i<em->size) {
560     if (c[em->index[i]] == 0) {
561       skipped++;
562       i++;
563     }
564     else {
565       while(skipped>0) {
566         buf[pos++] = ' ';
567         buf[pos++] = '0';
568         skipped--;
569       }
570       buf[pos++] = ' ';
571       pos += VG_(sprintf)(buf+pos, "%llu", c[em->index[i]]);
572       i++;
573     }
574   }
575
576   return pos;
577 }