blob: af5c568ffd8a3aaa146950cac971fab09d2ef8c5 [file] [log] [blame]
weidendoa17f2a32006-03-20 10:27:30 +00001/*--------------------------------------------------------------------*/
2/*--- Callgrind ---*/
3/*--- events.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Callgrind, a Valgrind tool for call tracing.
8
sewardj03f8d3f2012-08-05 15:46:46 +00009 Copyright (C) 2002-2012, Josef Weidendorfer (Josef.Weidendorfer@gmx.de)
weidendoa17f2a32006-03-20 10:27:30 +000010
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
weidendo5bba5252010-06-09 22:32:53 +000031/* This should be 2**MAX_EVENTGROUP_COUNT */
32#define MAX_EVENTSET_COUNT 1024
weidendoa17f2a32006-03-20 10:27:30 +000033
weidendo5bba5252010-06-09 22:32:53 +000034static EventGroup* eventGroup[MAX_EVENTGROUP_COUNT];
35static EventSet* eventSetTable[MAX_EVENTSET_COUNT];
36static Bool eventSets_initialized = 0;
weidendoa17f2a32006-03-20 10:27:30 +000037
weidendo5bba5252010-06-09 22:32:53 +000038static
39void initialize_event_sets(void)
weidendoa17f2a32006-03-20 10:27:30 +000040{
weidendo5bba5252010-06-09 22:32:53 +000041 Int i;
weidendoa17f2a32006-03-20 10:27:30 +000042
weidendo5bba5252010-06-09 22:32:53 +000043 if (eventSets_initialized) return;
weidendoa17f2a32006-03-20 10:27:30 +000044
weidendo5bba5252010-06-09 22:32:53 +000045 for(i=0; i< MAX_EVENTGROUP_COUNT; i++)
46 eventGroup[i] = 0;
weidendoa17f2a32006-03-20 10:27:30 +000047
weidendo5bba5252010-06-09 22:32:53 +000048 for(i=0; i< MAX_EVENTSET_COUNT; i++)
49 eventSetTable[i] = 0;
weidendoa17f2a32006-03-20 10:27:30 +000050
weidendo5bba5252010-06-09 22:32:53 +000051 eventSets_initialized = 1;
52 }
53
54static
55EventGroup* new_event_group(int id, int n)
56{
57 EventGroup* eg;
58
59 initialize_event_sets();
60
61 CLG_ASSERT(id>=0 && id<MAX_EVENTGROUP_COUNT);
62 CLG_ASSERT(eventGroup[id]==0);
63
64 eg = (EventGroup*) CLG_MALLOC("cl.events.group.1",
65 sizeof(EventGroup) + n * sizeof(Char*));
66 eg->size = n;
67 eventGroup[id] = eg;
68 return eg;
69}
70
71EventGroup* CLG_(register_event_group) (int id, Char* n1)
72{
73 EventGroup* eg = new_event_group(id, 1);
74 eg->name[0] = n1;
75
76 return eg;
77}
78
79EventGroup* CLG_(register_event_group2)(int id, Char* n1, Char* n2)
80{
81 EventGroup* eg = new_event_group(id, 2);
82 eg->name[0] = n1;
83 eg->name[1] = n2;
84
85 return eg;
86}
87
88EventGroup* CLG_(register_event_group3)(int id, Char* n1, Char* n2, Char* n3)
89{
90 EventGroup* eg = new_event_group(id, 3);
91 eg->name[0] = n1;
92 eg->name[1] = n2;
93 eg->name[2] = n3;
94
95 return eg;
96}
97
98EventGroup* CLG_(register_event_group4)(int id,
99 Char* n1, Char* n2, Char* n3, Char* n4)
100{
101 EventGroup* eg = new_event_group(id, 4);
102 eg->name[0] = n1;
103 eg->name[1] = n2;
104 eg->name[2] = n3;
105 eg->name[3] = n4;
106
107 return eg;
108}
109
110EventGroup* CLG_(get_event_group)(int id)
111{
112 CLG_ASSERT(id>=0 && id<MAX_EVENTGROUP_COUNT);
113
114 return eventGroup[id];
weidendoa17f2a32006-03-20 10:27:30 +0000115}
116
117
weidendo5bba5252010-06-09 22:32:53 +0000118static
119EventSet* eventset_from_mask(UInt mask)
weidendoa17f2a32006-03-20 10:27:30 +0000120{
weidendo5bba5252010-06-09 22:32:53 +0000121 EventSet* es;
122 Int i, count, offset;
weidendoa17f2a32006-03-20 10:27:30 +0000123
weidendo5bba5252010-06-09 22:32:53 +0000124 if (mask >= MAX_EVENTSET_COUNT) return 0;
125
126 initialize_event_sets();
127 if (eventSetTable[mask]) return eventSetTable[mask];
128
129 es = (EventSet*) CLG_MALLOC("cl.events.eventset.1", sizeof(EventSet));
130 es->mask = mask;
131
132 offset = 0;
133 count = 0;
134 for(i=0;i<MAX_EVENTGROUP_COUNT;i++) {
135 es->offset[i] = offset;
136 if ( ((mask & (1u<<i))==0) || (eventGroup[i]==0))
137 continue;
138
139 offset += eventGroup[i]->size;
140 count++;
141 }
142 es->size = offset;
143 es->count = count;
144
145 eventSetTable[mask] = es;
146 return es;
weidendoa17f2a32006-03-20 10:27:30 +0000147}
148
weidendo5bba5252010-06-09 22:32:53 +0000149EventSet* CLG_(get_event_set)(Int id)
weidendoa17f2a32006-03-20 10:27:30 +0000150{
weidendo5bba5252010-06-09 22:32:53 +0000151 CLG_ASSERT(id>=0 && id<MAX_EVENTGROUP_COUNT);
152 return eventset_from_mask(1u << id);
weidendoa17f2a32006-03-20 10:27:30 +0000153}
154
weidendo5bba5252010-06-09 22:32:53 +0000155EventSet* CLG_(get_event_set2)(Int id1, Int id2)
weidendoa17f2a32006-03-20 10:27:30 +0000156{
weidendo5bba5252010-06-09 22:32:53 +0000157 CLG_ASSERT(id1>=0 && id1<MAX_EVENTGROUP_COUNT);
158 CLG_ASSERT(id2>=0 && id2<MAX_EVENTGROUP_COUNT);
159 return eventset_from_mask((1u << id1) | (1u << id2));
weidendoa17f2a32006-03-20 10:27:30 +0000160}
161
weidendo5bba5252010-06-09 22:32:53 +0000162EventSet* CLG_(get_event_set3)(Int id1, Int id2, Int id3)
weidendoa17f2a32006-03-20 10:27:30 +0000163{
weidendo5bba5252010-06-09 22:32:53 +0000164 CLG_ASSERT(id1>=0 && id1<MAX_EVENTGROUP_COUNT);
165 CLG_ASSERT(id2>=0 && id2<MAX_EVENTGROUP_COUNT);
166 CLG_ASSERT(id3>=0 && id3<MAX_EVENTGROUP_COUNT);
167 return eventset_from_mask((1u << id1) | (1u << id2) | (1u << id3));
weidendoa17f2a32006-03-20 10:27:30 +0000168}
169
weidendo5bba5252010-06-09 22:32:53 +0000170EventSet* CLG_(add_event_group)(EventSet* es, Int id)
weidendoa17f2a32006-03-20 10:27:30 +0000171{
weidendo5bba5252010-06-09 22:32:53 +0000172 CLG_ASSERT(id>=0 && id<MAX_EVENTGROUP_COUNT);
173 if (!es) es = eventset_from_mask(0);
174 return eventset_from_mask(es->mask | (1u << id));
weidendoa17f2a32006-03-20 10:27:30 +0000175}
176
weidendo5bba5252010-06-09 22:32:53 +0000177EventSet* CLG_(add_event_group2)(EventSet* es, Int id1, Int id2)
weidendoa17f2a32006-03-20 10:27:30 +0000178{
weidendo5bba5252010-06-09 22:32:53 +0000179 CLG_ASSERT(id1>=0 && id1<MAX_EVENTGROUP_COUNT);
180 CLG_ASSERT(id2>=0 && id2<MAX_EVENTGROUP_COUNT);
181 if (!es) es = eventset_from_mask(0);
182 return eventset_from_mask(es->mask | (1u << id1) | (1u << id2));
weidendoa17f2a32006-03-20 10:27:30 +0000183}
184
weidendo5bba5252010-06-09 22:32:53 +0000185EventSet* CLG_(add_event_set)(EventSet* es1, EventSet* es2)
weidendoa17f2a32006-03-20 10:27:30 +0000186{
weidendo5bba5252010-06-09 22:32:53 +0000187 if (!es1) es1 = eventset_from_mask(0);
188 if (!es2) es2 = eventset_from_mask(0);
189 return eventset_from_mask(es1->mask | es2->mask);
weidendoa17f2a32006-03-20 10:27:30 +0000190}
191
weidendoa17f2a32006-03-20 10:27:30 +0000192Int CLG_(sprint_eventset)(Char* buf, EventSet* es)
193{
weidendo5bba5252010-06-09 22:32:53 +0000194 Int i, j, pos;
195 UInt mask;
196 EventGroup* eg;
weidendoa17f2a32006-03-20 10:27:30 +0000197
weidendoa17f2a32006-03-20 10:27:30 +0000198
weidendo5bba5252010-06-09 22:32:53 +0000199 CLG_ASSERT(es->size >0);
200 pos = 0;
201 for(i=0, mask=1; i<MAX_EVENTGROUP_COUNT; i++, mask=mask<<1) {
202 if ((es->mask & mask)==0) continue;
203 if (eventGroup[i] ==0) continue;
204
205 eg = eventGroup[i];
206 for(j=0; j<eg->size; j++) {
207 if (pos>0) buf[pos++] = ' ';
208 pos += VG_(sprintf)(buf + pos, "%s", eg->name[j]);
209 }
210 }
211 buf[pos] = 0;
212
213 return pos;
weidendoa17f2a32006-03-20 10:27:30 +0000214}
215
weidendo5bba5252010-06-09 22:32:53 +0000216
weidendoa17f2a32006-03-20 10:27:30 +0000217/* Get cost array for an event set */
218ULong* CLG_(get_eventset_cost)(EventSet* es)
219{
weidendo5bba5252010-06-09 22:32:53 +0000220 return CLG_(get_costarray)(es->size);
weidendoa17f2a32006-03-20 10:27:30 +0000221}
222
223/* Set all costs of an event set to zero */
224void CLG_(init_cost)(EventSet* es, ULong* cost)
225{
weidendo5bba5252010-06-09 22:32:53 +0000226 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000227
weidendo5bba5252010-06-09 22:32:53 +0000228 if (!cost) return;
weidendoa17f2a32006-03-20 10:27:30 +0000229
weidendo5bba5252010-06-09 22:32:53 +0000230 for(i=0; i<es->size; i++)
231 cost[i] = 0;
weidendoa17f2a32006-03-20 10:27:30 +0000232}
233
234/* Set all costs of an event set to zero */
235void CLG_(init_cost_lz)(EventSet* es, ULong** cost)
236{
weidendo5bba5252010-06-09 22:32:53 +0000237 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000238
weidendo5bba5252010-06-09 22:32:53 +0000239 CLG_ASSERT(cost != 0);
240 if (!(*cost))
241 *cost = CLG_(get_eventset_cost)(es);
weidendoa17f2a32006-03-20 10:27:30 +0000242
weidendo5bba5252010-06-09 22:32:53 +0000243 for(i=0; i<es->size; i++)
244 (*cost)[i] = 0;
weidendoa17f2a32006-03-20 10:27:30 +0000245}
246
247void CLG_(zero_cost)(EventSet* es, ULong* cost)
248{
weidendo5bba5252010-06-09 22:32:53 +0000249 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000250
weidendo5bba5252010-06-09 22:32:53 +0000251 if (!cost) return;
weidendoa17f2a32006-03-20 10:27:30 +0000252
weidendo5bba5252010-06-09 22:32:53 +0000253 for(i=0;i<es->size;i++)
254 cost[i] = 0;
weidendoa17f2a32006-03-20 10:27:30 +0000255}
256
257Bool CLG_(is_zero_cost)(EventSet* es, ULong* cost)
258{
weidendo5bba5252010-06-09 22:32:53 +0000259 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000260
weidendo5bba5252010-06-09 22:32:53 +0000261 if (!cost) return True;
weidendoa17f2a32006-03-20 10:27:30 +0000262
weidendo5bba5252010-06-09 22:32:53 +0000263 for(i=0; i<es->size; i++)
264 if (cost[i] != 0) return False;
265
266 return True;
weidendoa17f2a32006-03-20 10:27:30 +0000267}
268
269Bool CLG_(is_equal_cost)(EventSet* es, ULong* c1, ULong* c2)
270{
weidendo5bba5252010-06-09 22:32:53 +0000271 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000272
weidendo5bba5252010-06-09 22:32:53 +0000273 if (!c1) return CLG_(is_zero_cost)(es, c2);
274 if (!c2) return CLG_(is_zero_cost)(es, c1);
weidendoa17f2a32006-03-20 10:27:30 +0000275
weidendo5bba5252010-06-09 22:32:53 +0000276 for(i=0; i<es->size; i++)
277 if (c1[i] != c2[i]) return False;
278
279 return True;
weidendoa17f2a32006-03-20 10:27:30 +0000280}
281
282void CLG_(copy_cost)(EventSet* es, ULong* dst, ULong* src)
283{
weidendo5bba5252010-06-09 22:32:53 +0000284 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000285
weidendo5bba5252010-06-09 22:32:53 +0000286 if (!src) {
287 CLG_(zero_cost)(es, dst);
288 return;
289 }
290 CLG_ASSERT(dst != 0);
weidendoa17f2a32006-03-20 10:27:30 +0000291
weidendo5bba5252010-06-09 22:32:53 +0000292 for(i=0;i<es->size;i++)
293 dst[i] = src[i];
weidendoa17f2a32006-03-20 10:27:30 +0000294}
295
296void CLG_(copy_cost_lz)(EventSet* es, ULong** pdst, ULong* src)
297{
weidendo5bba5252010-06-09 22:32:53 +0000298 Int i;
299 ULong* dst;
weidendoa17f2a32006-03-20 10:27:30 +0000300
weidendo5bba5252010-06-09 22:32:53 +0000301 CLG_ASSERT(pdst != 0);
weidendoa17f2a32006-03-20 10:27:30 +0000302
weidendo5bba5252010-06-09 22:32:53 +0000303 if (!src) {
304 CLG_(zero_cost)(es, *pdst);
305 return;
306 }
307 dst = *pdst;
308 if (!dst)
309 dst = *pdst = CLG_(get_eventset_cost)(es);
weidendoa17f2a32006-03-20 10:27:30 +0000310
weidendo5bba5252010-06-09 22:32:53 +0000311 for(i=0;i<es->size;i++)
312 dst[i] = src[i];
weidendoa17f2a32006-03-20 10:27:30 +0000313}
314
315void CLG_(add_cost)(EventSet* es, ULong* dst, ULong* src)
316{
weidendo5bba5252010-06-09 22:32:53 +0000317 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000318
weidendo5bba5252010-06-09 22:32:53 +0000319 if (!src) return;
320 CLG_ASSERT(dst != 0);
weidendoa17f2a32006-03-20 10:27:30 +0000321
weidendo5bba5252010-06-09 22:32:53 +0000322 for(i=0; i<es->size; i++)
323 dst[i] += src[i];
weidendoa17f2a32006-03-20 10:27:30 +0000324}
325
326void CLG_(add_cost_lz)(EventSet* es, ULong** pdst, ULong* src)
327{
weidendo5bba5252010-06-09 22:32:53 +0000328 Int i;
329 ULong* dst;
weidendoa17f2a32006-03-20 10:27:30 +0000330
weidendo5bba5252010-06-09 22:32:53 +0000331 if (!src) return;
332 CLG_ASSERT(pdst != 0);
weidendoa17f2a32006-03-20 10:27:30 +0000333
weidendo5bba5252010-06-09 22:32:53 +0000334 dst = *pdst;
335 if (!dst) {
336 dst = *pdst = CLG_(get_eventset_cost)(es);
337 CLG_(copy_cost)(es, dst, src);
338 return;
weidendoa17f2a32006-03-20 10:27:30 +0000339 }
weidendo5bba5252010-06-09 22:32:53 +0000340
341 for(i=0; i<es->size; i++)
342 dst[i] += src[i];
weidendoa17f2a32006-03-20 10:27:30 +0000343}
344
345/* Adds src to dst and zeros src. Returns false if nothing changed */
346Bool CLG_(add_and_zero_cost)(EventSet* es, ULong* dst, ULong* src)
347{
weidendo5bba5252010-06-09 22:32:53 +0000348 Int i;
349 Bool is_nonzero = False;
weidendoa17f2a32006-03-20 10:27:30 +0000350
weidendo5bba5252010-06-09 22:32:53 +0000351 CLG_ASSERT((es != 0) && (dst != 0));
352 if (!src) return False;
weidendoa17f2a32006-03-20 10:27:30 +0000353
weidendo5bba5252010-06-09 22:32:53 +0000354 for(i=0; i<es->size; i++) {
355 if (src[i]==0) continue;
356 dst[i] += src[i];
357 src[i] = 0;
358 is_nonzero = True;
weidendoa17f2a32006-03-20 10:27:30 +0000359 }
weidendoa17f2a32006-03-20 10:27:30 +0000360
weidendo5bba5252010-06-09 22:32:53 +0000361 return is_nonzero;
weidendoa17f2a32006-03-20 10:27:30 +0000362}
363
364/* Adds src to dst and zeros src. Returns false if nothing changed */
weidendo5bba5252010-06-09 22:32:53 +0000365Bool CLG_(add_and_zero_cost2)(EventSet* esDst, ULong* dst,
366 EventSet* esSrc, ULong* src)
weidendoa17f2a32006-03-20 10:27:30 +0000367{
weidendo5bba5252010-06-09 22:32:53 +0000368 Int i,j;
369 Bool is_nonzero = False;
370 UInt mask;
371 EventGroup *eg;
372 ULong *egDst, *egSrc;
weidendoa17f2a32006-03-20 10:27:30 +0000373
weidendo5bba5252010-06-09 22:32:53 +0000374 CLG_ASSERT((esDst != 0) && (dst != 0) && (esSrc != 0));
375 if (!src) return False;
weidendoa17f2a32006-03-20 10:27:30 +0000376
weidendo5bba5252010-06-09 22:32:53 +0000377 for(i=0, mask=1; i<MAX_EVENTGROUP_COUNT; i++, mask=mask<<1) {
378 if ((esSrc->mask & mask)==0) continue;
379 if (eventGroup[i] ==0) continue;
weidendoa17f2a32006-03-20 10:27:30 +0000380
weidendo5bba5252010-06-09 22:32:53 +0000381 /* if src has a subset, dst must have, too */
382 CLG_ASSERT((esDst->mask & mask)>0);
383 eg = eventGroup[i];
384 egSrc = src + esSrc->offset[i];
385 egDst = dst + esDst->offset[i];
386 for(j=0; j<eg->size; j++) {
387 if (egSrc[j]==0) continue;
388 egDst[j] += egSrc[j];
389 egSrc[j] = 0;
390 is_nonzero = True;
391 }
weidendoa17f2a32006-03-20 10:27:30 +0000392 }
weidendoa17f2a32006-03-20 10:27:30 +0000393
weidendo5bba5252010-06-09 22:32:53 +0000394 return is_nonzero;
weidendoa17f2a32006-03-20 10:27:30 +0000395}
396
weidendo5bba5252010-06-09 22:32:53 +0000397
398
weidendoa17f2a32006-03-20 10:27:30 +0000399/* Adds difference of new and old to dst, and set old to new.
400 * Returns false if nothing changed */
weidendo0b23d6e2009-06-15 00:16:32 +0000401Bool CLG_(add_diff_cost)(EventSet* es, ULong* dst, ULong* old, ULong* new_cost)
weidendoa17f2a32006-03-20 10:27:30 +0000402{
weidendo5bba5252010-06-09 22:32:53 +0000403 Int i;
404 Bool is_nonzero = False;
weidendoa17f2a32006-03-20 10:27:30 +0000405
weidendo5bba5252010-06-09 22:32:53 +0000406 CLG_ASSERT((es != 0) && (dst != 0));
407 CLG_ASSERT(old && new_cost);
408
409 for(i=0; i<es->size; i++) {
410 if (new_cost[i] == old[i]) continue;
411 dst[i] += new_cost[i] - old[i];
412 old[i] = new_cost[i];
413 is_nonzero = True;
weidendoa17f2a32006-03-20 10:27:30 +0000414 }
weidendoa17f2a32006-03-20 10:27:30 +0000415
weidendo5bba5252010-06-09 22:32:53 +0000416 return is_nonzero;
weidendoa17f2a32006-03-20 10:27:30 +0000417}
418
weidendo5bba5252010-06-09 22:32:53 +0000419Bool CLG_(add_diff_cost_lz)(EventSet* es, ULong** pdst, ULong* old, ULong* new_cost)
weidendoa17f2a32006-03-20 10:27:30 +0000420{
weidendo5bba5252010-06-09 22:32:53 +0000421 Int i;
422 ULong* dst;
423 Bool is_nonzero = False;
weidendoa17f2a32006-03-20 10:27:30 +0000424
weidendo5bba5252010-06-09 22:32:53 +0000425 CLG_ASSERT((es != 0) && (pdst != 0));
426 CLG_ASSERT(old && new_cost);
weidendoa17f2a32006-03-20 10:27:30 +0000427
weidendo5bba5252010-06-09 22:32:53 +0000428 dst = *pdst;
429 if (!dst) {
430 dst = *pdst = CLG_(get_eventset_cost)(es);
431 CLG_(zero_cost)(es, dst);
weidendoa17f2a32006-03-20 10:27:30 +0000432 }
weidendoa17f2a32006-03-20 10:27:30 +0000433
weidendo5bba5252010-06-09 22:32:53 +0000434 for(i=0; i<es->size; i++) {
435 if (new_cost[i] == old[i]) continue;
436 dst[i] += new_cost[i] - old[i];
437 old[i] = new_cost[i];
438 is_nonzero = True;
439 }
440
441 return is_nonzero;
weidendoa17f2a32006-03-20 10:27:30 +0000442}
443
weidendo5bba5252010-06-09 22:32:53 +0000444
weidendoa17f2a32006-03-20 10:27:30 +0000445/* Returns number of characters written */
446Int CLG_(sprint_cost)(Char* buf, EventSet* es, ULong* c)
447{
weidendo5bba5252010-06-09 22:32:53 +0000448 Int i, pos, skipped = 0;
weidendoa17f2a32006-03-20 10:27:30 +0000449
weidendo5bba5252010-06-09 22:32:53 +0000450 if (!c || es->size==0) return 0;
weidendoa17f2a32006-03-20 10:27:30 +0000451
weidendo5bba5252010-06-09 22:32:53 +0000452 /* At least one entry */
453 pos = VG_(sprintf)(buf, "%llu", c[0]);
454 for(i=1; i<es->size; i++) {
455 if (c[i] == 0) {
456 skipped++;
457 continue;
458 }
459 while(skipped>0) {
460 buf[pos++] = ' ';
461 buf[pos++] = '0';
462 skipped--;
463 }
weidendoa17f2a32006-03-20 10:27:30 +0000464 buf[pos++] = ' ';
weidendo5bba5252010-06-09 22:32:53 +0000465 pos += VG_(sprintf)(buf+pos, "%llu", c[i]);
weidendoa17f2a32006-03-20 10:27:30 +0000466 }
weidendoa17f2a32006-03-20 10:27:30 +0000467
weidendo5bba5252010-06-09 22:32:53 +0000468 return pos;
weidendoa17f2a32006-03-20 10:27:30 +0000469}
470
471
472/* Allocate space for an event mapping */
473EventMapping* CLG_(get_eventmapping)(EventSet* es)
474{
weidendo5bba5252010-06-09 22:32:53 +0000475 EventMapping* em;
weidendoa17f2a32006-03-20 10:27:30 +0000476
weidendo5bba5252010-06-09 22:32:53 +0000477 CLG_ASSERT(es != 0);
weidendoa17f2a32006-03-20 10:27:30 +0000478
weidendo5bba5252010-06-09 22:32:53 +0000479 em = (EventMapping*) CLG_MALLOC("cl.events.geMapping.1",
480 sizeof(EventMapping) +
481 sizeof(struct EventMappingEntry) *
482 es->size);
483 em->capacity = es->size;
484 em->size = 0;
485 em->es = es;
weidendoa17f2a32006-03-20 10:27:30 +0000486
weidendo5bba5252010-06-09 22:32:53 +0000487 return em;
weidendoa17f2a32006-03-20 10:27:30 +0000488}
489
490void CLG_(append_event)(EventMapping* em, Char* n)
491{
weidendo5bba5252010-06-09 22:32:53 +0000492 Int i, j, offset = 0;
493 UInt mask;
494 EventGroup* eg;
weidendoa17f2a32006-03-20 10:27:30 +0000495
weidendo5bba5252010-06-09 22:32:53 +0000496 CLG_ASSERT(em != 0);
497 for(i=0, mask=1; i<MAX_EVENTGROUP_COUNT; i++, mask=mask<<1) {
498 if ((em->es->mask & mask)==0) continue;
499 if (eventGroup[i] ==0) continue;
weidendoa17f2a32006-03-20 10:27:30 +0000500
weidendo5bba5252010-06-09 22:32:53 +0000501 eg = eventGroup[i];
502 for(j=0; j<eg->size; j++, offset++) {
503 if (VG_(strcmp)(n, eg->name[j])!=0)
504 continue;
weidendoa17f2a32006-03-20 10:27:30 +0000505
weidendo5bba5252010-06-09 22:32:53 +0000506 CLG_ASSERT(em->capacity > em->size);
507 em->entry[em->size].group = i;
508 em->entry[em->size].index = j;
509 em->entry[em->size].offset = offset;
510 em->size++;
511 return;
512 }
513 }
weidendoa17f2a32006-03-20 10:27:30 +0000514}
515
516
517/* Returns number of characters written */
518Int CLG_(sprint_eventmapping)(Char* buf, EventMapping* em)
519{
weidendo5bba5252010-06-09 22:32:53 +0000520 Int i, pos = 0;
521 EventGroup* eg;
weidendoa17f2a32006-03-20 10:27:30 +0000522
weidendo5bba5252010-06-09 22:32:53 +0000523 CLG_ASSERT(em != 0);
weidendoa17f2a32006-03-20 10:27:30 +0000524
weidendo5bba5252010-06-09 22:32:53 +0000525 for(i=0; i< em->size; i++) {
526 if (pos>0) buf[pos++] = ' ';
527 eg = eventGroup[em->entry[i].group];
528 CLG_ASSERT(eg != 0);
529 pos += VG_(sprintf)(buf + pos, "%s", eg->name[em->entry[i].index]);
530 }
531 buf[pos] = 0;
weidendoa17f2a32006-03-20 10:27:30 +0000532
weidendo5bba5252010-06-09 22:32:53 +0000533 return pos;
weidendoa17f2a32006-03-20 10:27:30 +0000534}
535
536/* Returns number of characters written */
537Int CLG_(sprint_mappingcost)(Char* buf, EventMapping* em, ULong* c)
538{
weidendo5bba5252010-06-09 22:32:53 +0000539 Int i, pos, skipped = 0;
weidendoa17f2a32006-03-20 10:27:30 +0000540
weidendo5bba5252010-06-09 22:32:53 +0000541 if (!c || em->size==0) return 0;
weidendoa17f2a32006-03-20 10:27:30 +0000542
543 /* At least one entry */
weidendo5bba5252010-06-09 22:32:53 +0000544 pos = VG_(sprintf)(buf, "%llu", c[em->entry[0].offset]);
weidendoa17f2a32006-03-20 10:27:30 +0000545
weidendo5bba5252010-06-09 22:32:53 +0000546 for(i=1; i<em->size; i++) {
547 if (c[em->entry[i].offset] == 0) {
548 skipped++;
549 continue;
550 }
551 while(skipped>0) {
552 buf[pos++] = ' ';
553 buf[pos++] = '0';
554 skipped--;
555 }
weidendoa17f2a32006-03-20 10:27:30 +0000556 buf[pos++] = ' ';
weidendo5bba5252010-06-09 22:32:53 +0000557 pos += VG_(sprintf)(buf+pos, "%llu", c[em->entry[i].offset]);
weidendoa17f2a32006-03-20 10:27:30 +0000558 }
weidendoa17f2a32006-03-20 10:27:30 +0000559
weidendo5bba5252010-06-09 22:32:53 +0000560 return pos;
weidendoa17f2a32006-03-20 10:27:30 +0000561}