blob: b942e5d96e6c4c03a4afc2ce4317f1bac0c5565f [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
florian25f6c572012-10-21 02:55:56 +000071EventGroup* CLG_(register_event_group) (int id, const HChar* n1)
weidendo5bba5252010-06-09 22:32:53 +000072{
73 EventGroup* eg = new_event_group(id, 1);
74 eg->name[0] = n1;
75
76 return eg;
77}
78
florian25f6c572012-10-21 02:55:56 +000079EventGroup* CLG_(register_event_group2)(int id, const HChar* n1,
80 const HChar* n2)
weidendo5bba5252010-06-09 22:32:53 +000081{
82 EventGroup* eg = new_event_group(id, 2);
83 eg->name[0] = n1;
84 eg->name[1] = n2;
85
86 return eg;
87}
88
florian25f6c572012-10-21 02:55:56 +000089EventGroup* CLG_(register_event_group3)(int id, const HChar* n1,
90 const HChar* n2, const HChar* n3)
weidendo5bba5252010-06-09 22:32:53 +000091{
92 EventGroup* eg = new_event_group(id, 3);
93 eg->name[0] = n1;
94 eg->name[1] = n2;
95 eg->name[2] = n3;
96
97 return eg;
98}
99
florian25f6c572012-10-21 02:55:56 +0000100EventGroup* CLG_(register_event_group4)(int id, const HChar* n1,
101 const HChar* n2, const HChar* n3,
102 const HChar* n4)
weidendo5bba5252010-06-09 22:32:53 +0000103{
104 EventGroup* eg = new_event_group(id, 4);
105 eg->name[0] = n1;
106 eg->name[1] = n2;
107 eg->name[2] = n3;
108 eg->name[3] = n4;
109
110 return eg;
111}
112
113EventGroup* CLG_(get_event_group)(int id)
114{
115 CLG_ASSERT(id>=0 && id<MAX_EVENTGROUP_COUNT);
116
117 return eventGroup[id];
weidendoa17f2a32006-03-20 10:27:30 +0000118}
119
120
weidendo5bba5252010-06-09 22:32:53 +0000121static
122EventSet* eventset_from_mask(UInt mask)
weidendoa17f2a32006-03-20 10:27:30 +0000123{
weidendo5bba5252010-06-09 22:32:53 +0000124 EventSet* es;
125 Int i, count, offset;
weidendoa17f2a32006-03-20 10:27:30 +0000126
weidendo5bba5252010-06-09 22:32:53 +0000127 if (mask >= MAX_EVENTSET_COUNT) return 0;
128
129 initialize_event_sets();
130 if (eventSetTable[mask]) return eventSetTable[mask];
131
132 es = (EventSet*) CLG_MALLOC("cl.events.eventset.1", sizeof(EventSet));
133 es->mask = mask;
134
135 offset = 0;
136 count = 0;
137 for(i=0;i<MAX_EVENTGROUP_COUNT;i++) {
138 es->offset[i] = offset;
139 if ( ((mask & (1u<<i))==0) || (eventGroup[i]==0))
140 continue;
141
142 offset += eventGroup[i]->size;
143 count++;
144 }
145 es->size = offset;
146 es->count = count;
147
148 eventSetTable[mask] = es;
149 return es;
weidendoa17f2a32006-03-20 10:27:30 +0000150}
151
weidendo5bba5252010-06-09 22:32:53 +0000152EventSet* CLG_(get_event_set)(Int id)
weidendoa17f2a32006-03-20 10:27:30 +0000153{
weidendo5bba5252010-06-09 22:32:53 +0000154 CLG_ASSERT(id>=0 && id<MAX_EVENTGROUP_COUNT);
155 return eventset_from_mask(1u << id);
weidendoa17f2a32006-03-20 10:27:30 +0000156}
157
weidendo5bba5252010-06-09 22:32:53 +0000158EventSet* CLG_(get_event_set2)(Int id1, Int id2)
weidendoa17f2a32006-03-20 10:27:30 +0000159{
weidendo5bba5252010-06-09 22:32:53 +0000160 CLG_ASSERT(id1>=0 && id1<MAX_EVENTGROUP_COUNT);
161 CLG_ASSERT(id2>=0 && id2<MAX_EVENTGROUP_COUNT);
162 return eventset_from_mask((1u << id1) | (1u << id2));
weidendoa17f2a32006-03-20 10:27:30 +0000163}
164
weidendo5bba5252010-06-09 22:32:53 +0000165EventSet* CLG_(get_event_set3)(Int id1, Int id2, Int id3)
weidendoa17f2a32006-03-20 10:27:30 +0000166{
weidendo5bba5252010-06-09 22:32:53 +0000167 CLG_ASSERT(id1>=0 && id1<MAX_EVENTGROUP_COUNT);
168 CLG_ASSERT(id2>=0 && id2<MAX_EVENTGROUP_COUNT);
169 CLG_ASSERT(id3>=0 && id3<MAX_EVENTGROUP_COUNT);
170 return eventset_from_mask((1u << id1) | (1u << id2) | (1u << id3));
weidendoa17f2a32006-03-20 10:27:30 +0000171}
172
weidendo5bba5252010-06-09 22:32:53 +0000173EventSet* CLG_(add_event_group)(EventSet* es, Int id)
weidendoa17f2a32006-03-20 10:27:30 +0000174{
weidendo5bba5252010-06-09 22:32:53 +0000175 CLG_ASSERT(id>=0 && id<MAX_EVENTGROUP_COUNT);
176 if (!es) es = eventset_from_mask(0);
177 return eventset_from_mask(es->mask | (1u << id));
weidendoa17f2a32006-03-20 10:27:30 +0000178}
179
weidendo5bba5252010-06-09 22:32:53 +0000180EventSet* CLG_(add_event_group2)(EventSet* es, Int id1, Int id2)
weidendoa17f2a32006-03-20 10:27:30 +0000181{
weidendo5bba5252010-06-09 22:32:53 +0000182 CLG_ASSERT(id1>=0 && id1<MAX_EVENTGROUP_COUNT);
183 CLG_ASSERT(id2>=0 && id2<MAX_EVENTGROUP_COUNT);
184 if (!es) es = eventset_from_mask(0);
185 return eventset_from_mask(es->mask | (1u << id1) | (1u << id2));
weidendoa17f2a32006-03-20 10:27:30 +0000186}
187
weidendo5bba5252010-06-09 22:32:53 +0000188EventSet* CLG_(add_event_set)(EventSet* es1, EventSet* es2)
weidendoa17f2a32006-03-20 10:27:30 +0000189{
weidendo5bba5252010-06-09 22:32:53 +0000190 if (!es1) es1 = eventset_from_mask(0);
191 if (!es2) es2 = eventset_from_mask(0);
192 return eventset_from_mask(es1->mask | es2->mask);
weidendoa17f2a32006-03-20 10:27:30 +0000193}
194
weidendoa17f2a32006-03-20 10:27:30 +0000195Int CLG_(sprint_eventset)(Char* buf, EventSet* es)
196{
weidendo5bba5252010-06-09 22:32:53 +0000197 Int i, j, pos;
198 UInt mask;
199 EventGroup* eg;
weidendoa17f2a32006-03-20 10:27:30 +0000200
weidendoa17f2a32006-03-20 10:27:30 +0000201
weidendo5bba5252010-06-09 22:32:53 +0000202 CLG_ASSERT(es->size >0);
203 pos = 0;
204 for(i=0, mask=1; i<MAX_EVENTGROUP_COUNT; i++, mask=mask<<1) {
205 if ((es->mask & mask)==0) continue;
206 if (eventGroup[i] ==0) continue;
207
208 eg = eventGroup[i];
209 for(j=0; j<eg->size; j++) {
210 if (pos>0) buf[pos++] = ' ';
211 pos += VG_(sprintf)(buf + pos, "%s", eg->name[j]);
212 }
213 }
214 buf[pos] = 0;
215
216 return pos;
weidendoa17f2a32006-03-20 10:27:30 +0000217}
218
weidendo5bba5252010-06-09 22:32:53 +0000219
weidendoa17f2a32006-03-20 10:27:30 +0000220/* Get cost array for an event set */
221ULong* CLG_(get_eventset_cost)(EventSet* es)
222{
weidendo5bba5252010-06-09 22:32:53 +0000223 return CLG_(get_costarray)(es->size);
weidendoa17f2a32006-03-20 10:27:30 +0000224}
225
226/* Set all costs of an event set to zero */
227void CLG_(init_cost)(EventSet* es, ULong* cost)
228{
weidendo5bba5252010-06-09 22:32:53 +0000229 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000230
weidendo5bba5252010-06-09 22:32:53 +0000231 if (!cost) return;
weidendoa17f2a32006-03-20 10:27:30 +0000232
weidendo5bba5252010-06-09 22:32:53 +0000233 for(i=0; i<es->size; i++)
234 cost[i] = 0;
weidendoa17f2a32006-03-20 10:27:30 +0000235}
236
237/* Set all costs of an event set to zero */
238void CLG_(init_cost_lz)(EventSet* es, ULong** cost)
239{
weidendo5bba5252010-06-09 22:32:53 +0000240 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000241
weidendo5bba5252010-06-09 22:32:53 +0000242 CLG_ASSERT(cost != 0);
243 if (!(*cost))
244 *cost = CLG_(get_eventset_cost)(es);
weidendoa17f2a32006-03-20 10:27:30 +0000245
weidendo5bba5252010-06-09 22:32:53 +0000246 for(i=0; i<es->size; i++)
247 (*cost)[i] = 0;
weidendoa17f2a32006-03-20 10:27:30 +0000248}
249
250void CLG_(zero_cost)(EventSet* es, ULong* cost)
251{
weidendo5bba5252010-06-09 22:32:53 +0000252 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000253
weidendo5bba5252010-06-09 22:32:53 +0000254 if (!cost) return;
weidendoa17f2a32006-03-20 10:27:30 +0000255
weidendo5bba5252010-06-09 22:32:53 +0000256 for(i=0;i<es->size;i++)
257 cost[i] = 0;
weidendoa17f2a32006-03-20 10:27:30 +0000258}
259
260Bool CLG_(is_zero_cost)(EventSet* es, ULong* cost)
261{
weidendo5bba5252010-06-09 22:32:53 +0000262 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000263
weidendo5bba5252010-06-09 22:32:53 +0000264 if (!cost) return True;
weidendoa17f2a32006-03-20 10:27:30 +0000265
weidendo5bba5252010-06-09 22:32:53 +0000266 for(i=0; i<es->size; i++)
267 if (cost[i] != 0) return False;
268
269 return True;
weidendoa17f2a32006-03-20 10:27:30 +0000270}
271
272Bool CLG_(is_equal_cost)(EventSet* es, ULong* c1, ULong* c2)
273{
weidendo5bba5252010-06-09 22:32:53 +0000274 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000275
weidendo5bba5252010-06-09 22:32:53 +0000276 if (!c1) return CLG_(is_zero_cost)(es, c2);
277 if (!c2) return CLG_(is_zero_cost)(es, c1);
weidendoa17f2a32006-03-20 10:27:30 +0000278
weidendo5bba5252010-06-09 22:32:53 +0000279 for(i=0; i<es->size; i++)
280 if (c1[i] != c2[i]) return False;
281
282 return True;
weidendoa17f2a32006-03-20 10:27:30 +0000283}
284
285void CLG_(copy_cost)(EventSet* es, ULong* dst, ULong* src)
286{
weidendo5bba5252010-06-09 22:32:53 +0000287 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000288
weidendo5bba5252010-06-09 22:32:53 +0000289 if (!src) {
290 CLG_(zero_cost)(es, dst);
291 return;
292 }
293 CLG_ASSERT(dst != 0);
weidendoa17f2a32006-03-20 10:27:30 +0000294
weidendo5bba5252010-06-09 22:32:53 +0000295 for(i=0;i<es->size;i++)
296 dst[i] = src[i];
weidendoa17f2a32006-03-20 10:27:30 +0000297}
298
299void CLG_(copy_cost_lz)(EventSet* es, ULong** pdst, ULong* src)
300{
weidendo5bba5252010-06-09 22:32:53 +0000301 Int i;
302 ULong* dst;
weidendoa17f2a32006-03-20 10:27:30 +0000303
weidendo5bba5252010-06-09 22:32:53 +0000304 CLG_ASSERT(pdst != 0);
weidendoa17f2a32006-03-20 10:27:30 +0000305
weidendo5bba5252010-06-09 22:32:53 +0000306 if (!src) {
307 CLG_(zero_cost)(es, *pdst);
308 return;
309 }
310 dst = *pdst;
311 if (!dst)
312 dst = *pdst = CLG_(get_eventset_cost)(es);
weidendoa17f2a32006-03-20 10:27:30 +0000313
weidendo5bba5252010-06-09 22:32:53 +0000314 for(i=0;i<es->size;i++)
315 dst[i] = src[i];
weidendoa17f2a32006-03-20 10:27:30 +0000316}
317
318void CLG_(add_cost)(EventSet* es, ULong* dst, ULong* src)
319{
weidendo5bba5252010-06-09 22:32:53 +0000320 Int i;
weidendoa17f2a32006-03-20 10:27:30 +0000321
weidendo5bba5252010-06-09 22:32:53 +0000322 if (!src) return;
323 CLG_ASSERT(dst != 0);
weidendoa17f2a32006-03-20 10:27:30 +0000324
weidendo5bba5252010-06-09 22:32:53 +0000325 for(i=0; i<es->size; i++)
326 dst[i] += src[i];
weidendoa17f2a32006-03-20 10:27:30 +0000327}
328
329void CLG_(add_cost_lz)(EventSet* es, ULong** pdst, ULong* src)
330{
weidendo5bba5252010-06-09 22:32:53 +0000331 Int i;
332 ULong* dst;
weidendoa17f2a32006-03-20 10:27:30 +0000333
weidendo5bba5252010-06-09 22:32:53 +0000334 if (!src) return;
335 CLG_ASSERT(pdst != 0);
weidendoa17f2a32006-03-20 10:27:30 +0000336
weidendo5bba5252010-06-09 22:32:53 +0000337 dst = *pdst;
338 if (!dst) {
339 dst = *pdst = CLG_(get_eventset_cost)(es);
340 CLG_(copy_cost)(es, dst, src);
341 return;
weidendoa17f2a32006-03-20 10:27:30 +0000342 }
weidendo5bba5252010-06-09 22:32:53 +0000343
344 for(i=0; i<es->size; i++)
345 dst[i] += src[i];
weidendoa17f2a32006-03-20 10:27:30 +0000346}
347
348/* Adds src to dst and zeros src. Returns false if nothing changed */
349Bool CLG_(add_and_zero_cost)(EventSet* es, ULong* dst, ULong* src)
350{
weidendo5bba5252010-06-09 22:32:53 +0000351 Int i;
352 Bool is_nonzero = False;
weidendoa17f2a32006-03-20 10:27:30 +0000353
weidendo5bba5252010-06-09 22:32:53 +0000354 CLG_ASSERT((es != 0) && (dst != 0));
355 if (!src) return False;
weidendoa17f2a32006-03-20 10:27:30 +0000356
weidendo5bba5252010-06-09 22:32:53 +0000357 for(i=0; i<es->size; i++) {
358 if (src[i]==0) continue;
359 dst[i] += src[i];
360 src[i] = 0;
361 is_nonzero = True;
weidendoa17f2a32006-03-20 10:27:30 +0000362 }
weidendoa17f2a32006-03-20 10:27:30 +0000363
weidendo5bba5252010-06-09 22:32:53 +0000364 return is_nonzero;
weidendoa17f2a32006-03-20 10:27:30 +0000365}
366
367/* Adds src to dst and zeros src. Returns false if nothing changed */
weidendo5bba5252010-06-09 22:32:53 +0000368Bool CLG_(add_and_zero_cost2)(EventSet* esDst, ULong* dst,
369 EventSet* esSrc, ULong* src)
weidendoa17f2a32006-03-20 10:27:30 +0000370{
weidendo5bba5252010-06-09 22:32:53 +0000371 Int i,j;
372 Bool is_nonzero = False;
373 UInt mask;
374 EventGroup *eg;
375 ULong *egDst, *egSrc;
weidendoa17f2a32006-03-20 10:27:30 +0000376
weidendo5bba5252010-06-09 22:32:53 +0000377 CLG_ASSERT((esDst != 0) && (dst != 0) && (esSrc != 0));
378 if (!src) return False;
weidendoa17f2a32006-03-20 10:27:30 +0000379
weidendo5bba5252010-06-09 22:32:53 +0000380 for(i=0, mask=1; i<MAX_EVENTGROUP_COUNT; i++, mask=mask<<1) {
381 if ((esSrc->mask & mask)==0) continue;
382 if (eventGroup[i] ==0) continue;
weidendoa17f2a32006-03-20 10:27:30 +0000383
weidendo5bba5252010-06-09 22:32:53 +0000384 /* if src has a subset, dst must have, too */
385 CLG_ASSERT((esDst->mask & mask)>0);
386 eg = eventGroup[i];
387 egSrc = src + esSrc->offset[i];
388 egDst = dst + esDst->offset[i];
389 for(j=0; j<eg->size; j++) {
390 if (egSrc[j]==0) continue;
391 egDst[j] += egSrc[j];
392 egSrc[j] = 0;
393 is_nonzero = True;
394 }
weidendoa17f2a32006-03-20 10:27:30 +0000395 }
weidendoa17f2a32006-03-20 10:27:30 +0000396
weidendo5bba5252010-06-09 22:32:53 +0000397 return is_nonzero;
weidendoa17f2a32006-03-20 10:27:30 +0000398}
399
weidendo5bba5252010-06-09 22:32:53 +0000400
401
weidendoa17f2a32006-03-20 10:27:30 +0000402/* Adds difference of new and old to dst, and set old to new.
403 * Returns false if nothing changed */
weidendo0b23d6e2009-06-15 00:16:32 +0000404Bool CLG_(add_diff_cost)(EventSet* es, ULong* dst, ULong* old, ULong* new_cost)
weidendoa17f2a32006-03-20 10:27:30 +0000405{
weidendo5bba5252010-06-09 22:32:53 +0000406 Int i;
407 Bool is_nonzero = False;
weidendoa17f2a32006-03-20 10:27:30 +0000408
weidendo5bba5252010-06-09 22:32:53 +0000409 CLG_ASSERT((es != 0) && (dst != 0));
410 CLG_ASSERT(old && new_cost);
411
412 for(i=0; i<es->size; i++) {
413 if (new_cost[i] == old[i]) continue;
414 dst[i] += new_cost[i] - old[i];
415 old[i] = new_cost[i];
416 is_nonzero = True;
weidendoa17f2a32006-03-20 10:27:30 +0000417 }
weidendoa17f2a32006-03-20 10:27:30 +0000418
weidendo5bba5252010-06-09 22:32:53 +0000419 return is_nonzero;
weidendoa17f2a32006-03-20 10:27:30 +0000420}
421
weidendo5bba5252010-06-09 22:32:53 +0000422Bool CLG_(add_diff_cost_lz)(EventSet* es, ULong** pdst, ULong* old, ULong* new_cost)
weidendoa17f2a32006-03-20 10:27:30 +0000423{
weidendo5bba5252010-06-09 22:32:53 +0000424 Int i;
425 ULong* dst;
426 Bool is_nonzero = False;
weidendoa17f2a32006-03-20 10:27:30 +0000427
weidendo5bba5252010-06-09 22:32:53 +0000428 CLG_ASSERT((es != 0) && (pdst != 0));
429 CLG_ASSERT(old && new_cost);
weidendoa17f2a32006-03-20 10:27:30 +0000430
weidendo5bba5252010-06-09 22:32:53 +0000431 dst = *pdst;
432 if (!dst) {
433 dst = *pdst = CLG_(get_eventset_cost)(es);
434 CLG_(zero_cost)(es, dst);
weidendoa17f2a32006-03-20 10:27:30 +0000435 }
weidendoa17f2a32006-03-20 10:27:30 +0000436
weidendo5bba5252010-06-09 22:32:53 +0000437 for(i=0; i<es->size; i++) {
438 if (new_cost[i] == old[i]) continue;
439 dst[i] += new_cost[i] - old[i];
440 old[i] = new_cost[i];
441 is_nonzero = True;
442 }
443
444 return is_nonzero;
weidendoa17f2a32006-03-20 10:27:30 +0000445}
446
weidendo5bba5252010-06-09 22:32:53 +0000447
weidendoa17f2a32006-03-20 10:27:30 +0000448/* Returns number of characters written */
449Int CLG_(sprint_cost)(Char* buf, EventSet* es, ULong* c)
450{
weidendo5bba5252010-06-09 22:32:53 +0000451 Int i, pos, skipped = 0;
weidendoa17f2a32006-03-20 10:27:30 +0000452
weidendo5bba5252010-06-09 22:32:53 +0000453 if (!c || es->size==0) return 0;
weidendoa17f2a32006-03-20 10:27:30 +0000454
weidendo5bba5252010-06-09 22:32:53 +0000455 /* At least one entry */
456 pos = VG_(sprintf)(buf, "%llu", c[0]);
457 for(i=1; i<es->size; i++) {
458 if (c[i] == 0) {
459 skipped++;
460 continue;
461 }
462 while(skipped>0) {
463 buf[pos++] = ' ';
464 buf[pos++] = '0';
465 skipped--;
466 }
weidendoa17f2a32006-03-20 10:27:30 +0000467 buf[pos++] = ' ';
weidendo5bba5252010-06-09 22:32:53 +0000468 pos += VG_(sprintf)(buf+pos, "%llu", c[i]);
weidendoa17f2a32006-03-20 10:27:30 +0000469 }
weidendoa17f2a32006-03-20 10:27:30 +0000470
weidendo5bba5252010-06-09 22:32:53 +0000471 return pos;
weidendoa17f2a32006-03-20 10:27:30 +0000472}
473
474
475/* Allocate space for an event mapping */
476EventMapping* CLG_(get_eventmapping)(EventSet* es)
477{
weidendo5bba5252010-06-09 22:32:53 +0000478 EventMapping* em;
weidendoa17f2a32006-03-20 10:27:30 +0000479
weidendo5bba5252010-06-09 22:32:53 +0000480 CLG_ASSERT(es != 0);
weidendoa17f2a32006-03-20 10:27:30 +0000481
weidendo5bba5252010-06-09 22:32:53 +0000482 em = (EventMapping*) CLG_MALLOC("cl.events.geMapping.1",
483 sizeof(EventMapping) +
484 sizeof(struct EventMappingEntry) *
485 es->size);
486 em->capacity = es->size;
487 em->size = 0;
488 em->es = es;
weidendoa17f2a32006-03-20 10:27:30 +0000489
weidendo5bba5252010-06-09 22:32:53 +0000490 return em;
weidendoa17f2a32006-03-20 10:27:30 +0000491}
492
florian25f6c572012-10-21 02:55:56 +0000493void CLG_(append_event)(EventMapping* em, const HChar* n)
weidendoa17f2a32006-03-20 10:27:30 +0000494{
weidendo5bba5252010-06-09 22:32:53 +0000495 Int i, j, offset = 0;
496 UInt mask;
497 EventGroup* eg;
weidendoa17f2a32006-03-20 10:27:30 +0000498
weidendo5bba5252010-06-09 22:32:53 +0000499 CLG_ASSERT(em != 0);
500 for(i=0, mask=1; i<MAX_EVENTGROUP_COUNT; i++, mask=mask<<1) {
501 if ((em->es->mask & mask)==0) continue;
502 if (eventGroup[i] ==0) continue;
weidendoa17f2a32006-03-20 10:27:30 +0000503
weidendo5bba5252010-06-09 22:32:53 +0000504 eg = eventGroup[i];
505 for(j=0; j<eg->size; j++, offset++) {
506 if (VG_(strcmp)(n, eg->name[j])!=0)
507 continue;
weidendoa17f2a32006-03-20 10:27:30 +0000508
weidendo5bba5252010-06-09 22:32:53 +0000509 CLG_ASSERT(em->capacity > em->size);
510 em->entry[em->size].group = i;
511 em->entry[em->size].index = j;
512 em->entry[em->size].offset = offset;
513 em->size++;
514 return;
515 }
516 }
weidendoa17f2a32006-03-20 10:27:30 +0000517}
518
519
520/* Returns number of characters written */
521Int CLG_(sprint_eventmapping)(Char* buf, EventMapping* em)
522{
weidendo5bba5252010-06-09 22:32:53 +0000523 Int i, pos = 0;
524 EventGroup* eg;
weidendoa17f2a32006-03-20 10:27:30 +0000525
weidendo5bba5252010-06-09 22:32:53 +0000526 CLG_ASSERT(em != 0);
weidendoa17f2a32006-03-20 10:27:30 +0000527
weidendo5bba5252010-06-09 22:32:53 +0000528 for(i=0; i< em->size; i++) {
529 if (pos>0) buf[pos++] = ' ';
530 eg = eventGroup[em->entry[i].group];
531 CLG_ASSERT(eg != 0);
532 pos += VG_(sprintf)(buf + pos, "%s", eg->name[em->entry[i].index]);
533 }
534 buf[pos] = 0;
weidendoa17f2a32006-03-20 10:27:30 +0000535
weidendo5bba5252010-06-09 22:32:53 +0000536 return pos;
weidendoa17f2a32006-03-20 10:27:30 +0000537}
538
539/* Returns number of characters written */
540Int CLG_(sprint_mappingcost)(Char* buf, EventMapping* em, ULong* c)
541{
weidendo5bba5252010-06-09 22:32:53 +0000542 Int i, pos, skipped = 0;
weidendoa17f2a32006-03-20 10:27:30 +0000543
weidendo5bba5252010-06-09 22:32:53 +0000544 if (!c || em->size==0) return 0;
weidendoa17f2a32006-03-20 10:27:30 +0000545
546 /* At least one entry */
weidendo5bba5252010-06-09 22:32:53 +0000547 pos = VG_(sprintf)(buf, "%llu", c[em->entry[0].offset]);
weidendoa17f2a32006-03-20 10:27:30 +0000548
weidendo5bba5252010-06-09 22:32:53 +0000549 for(i=1; i<em->size; i++) {
550 if (c[em->entry[i].offset] == 0) {
551 skipped++;
552 continue;
553 }
554 while(skipped>0) {
555 buf[pos++] = ' ';
556 buf[pos++] = '0';
557 skipped--;
558 }
weidendoa17f2a32006-03-20 10:27:30 +0000559 buf[pos++] = ' ';
weidendo5bba5252010-06-09 22:32:53 +0000560 pos += VG_(sprintf)(buf+pos, "%llu", c[em->entry[i].offset]);
weidendoa17f2a32006-03-20 10:27:30 +0000561 }
weidendoa17f2a32006-03-20 10:27:30 +0000562
weidendo5bba5252010-06-09 22:32:53 +0000563 return pos;
weidendoa17f2a32006-03-20 10:27:30 +0000564}