cp_annotate.cc (10470:2c6a72e919f6) cp_annotate.cc (10905:a6ca6831e775)
1/*
2 * Copyright (c) 2006-2009 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Ali Saidi
29 */
30
31#include "arch/generic/linux/threadinfo.hh"
32#include "arch/utility.hh"
33#include "base/loader/object_file.hh"
34#include "base/callback.hh"
35#include "base/cp_annotate.hh"
36#include "base/output.hh"
37#include "base/trace.hh"
38#include "config/the_isa.hh"
39#include "cpu/thread_context.hh"
40#include "debug/Annotate.hh"
41#include "debug/AnnotateVerbose.hh"
42#include "sim/arguments.hh"
43#include "sim/core.hh"
44#include "sim/sim_exit.hh"
45#include "sim/system.hh"
46
47struct CPAIgnoreSymbol
48{
49 const char *symbol;
50 size_t len;
51};
52#define CPA_IGNORE_SYMBOL(sym) { #sym, sizeof(#sym) }
53
54CPAIgnoreSymbol ignoreSymbols[] = {
55 CPA_IGNORE_SYMBOL("m5a_"),
56 CPA_IGNORE_SYMBOL("ret_from_sys_call"),
57 CPA_IGNORE_SYMBOL("ret_from_reschedule"),
58 CPA_IGNORE_SYMBOL("_spin_"),
59 CPA_IGNORE_SYMBOL("local_bh_"),
60 CPA_IGNORE_SYMBOL("restore_all"),
61 CPA_IGNORE_SYMBOL("Call_Pal_"),
62 CPA_IGNORE_SYMBOL("pal_post_interrupt"),
63 CPA_IGNORE_SYMBOL("rti_to_"),
64 CPA_IGNORE_SYMBOL("sys_int_2"),
65 CPA_IGNORE_SYMBOL("sys_interrupt"),
66 CPA_IGNORE_SYMBOL("normal_int"),
67 CPA_IGNORE_SYMBOL("TRAP_INTERRUPT_10_"),
68 CPA_IGNORE_SYMBOL("Trap_Interrupt"),
69 CPA_IGNORE_SYMBOL("do_entInt"),
70 CPA_IGNORE_SYMBOL("__do_softirq"),
71 CPA_IGNORE_SYMBOL("_end"),
72 CPA_IGNORE_SYMBOL("entInt"),
73 CPA_IGNORE_SYMBOL("entSys"),
74 {0,0}
75};
76#undef CPA_IGNORE_SYMBOL
77
78using namespace std;
79using namespace TheISA;
80
81bool CPA::exists;
82CPA *CPA::_cpa;
83
84class AnnotateDumpCallback : public Callback
85{
86
87 private:
88 CPA *cpa;
89 public:
90 virtual void process();
91 AnnotateDumpCallback(CPA *_cpa)
92 : cpa(_cpa)
93 {}
94};
95
96void
97AnnotateDumpCallback::process()
98{
99 cpa->dump(true);
100 cpa->dumpKey();
101}
102
103
104CPA::CPA(Params *p)
105 : SimObject(p), numSm(0), numSmt(0), numSys(0), numQs(0), conId(0)
106{
107 if (exists)
108 fatal("Multiple annotation objects found in system");
109 exists = true;
110
111 _enabled = p->enabled;
112 _cpa = this;
113
114 vector<string>::iterator i;
115 i = p->user_apps.begin();
116
117 while (i != p->user_apps.end()) {
118 ObjectFile *of = createObjectFile(*i);
119 string sf;
120 if (!of)
121 fatal("Couldn't load symbols from file: %s\n", *i);
122 sf = *i;
123 sf.erase(0, sf.rfind('/') + 1);;
124 DPRINTFN("file %s short: %s\n", *i, sf);
125 userApp[sf] = new SymbolTable;
126 bool result1 = of->loadGlobalSymbols(userApp[sf]);
127 bool result2 = of->loadLocalSymbols(userApp[sf]);
128 if (!result1 || !result2)
129 panic("blah");
130 assert(result1 && result2);
131 i++;
132 }
133}
134
135void
136CPA::startup()
137{
138 osbin = simout.create("annotate.bin", true);
139 // MAGIC version number 'M''5''A'N' + version/capabilities
140 ah.version = 0x4D35414E00000101ULL;
141 ah.num_recs = 0;
142 ah.key_off = 0;
143 osbin->write((char*)&ah, sizeof(AnnotateHeader));
144
145 registerExitCallback(new AnnotateDumpCallback(this));
146}
147
148uint64_t
149CPA::getFrame(ThreadContext *tc)
150{
151 // This code is ISA specific and will need to be changed
152 // if the annotation code is used for something other than Alpha
153 return (tc->readMiscRegNoEffect(TheISA::IPR_PALtemp23) &
154 ~ULL(0x3FFF));
155
156}
157
158void
159CPA::swSmBegin(ThreadContext *tc)
160{
161 if (!enabled())
162 return;
163
164 Arguments args(tc);
165 std::string st;
166 Addr junk;
167 char sm[50];
168 if (!TheISA::inUserMode(tc))
169 debugSymbolTable->findNearestSymbol(
170 tc->readIntReg(ReturnAddressReg), st, junk);
171
172 CopyStringOut(tc, sm, args[0], 50);
173 System *sys = tc->getSystemPtr();
174 StringWrap name(sys->name());
175
176 if (!sm[0])
177 warn("Got null SM at tick %d\n", curTick());
178
179 int sysi = getSys(sys);
180 int smi = getSm(sysi, sm, args[1]);
181 DPRINTF(Annotate, "Starting machine: %s(%d) sysi: %d id: %#x\n", sm,
182 smi, sysi, args[1]);
183 DPRINTF(Annotate, "smMap[%d] = %d, %s, %#x\n", smi,
184 smMap[smi-1].first, smMap[smi-1].second.first,
185 smMap[smi-1].second.second);
186
187 uint64_t frame = getFrame(tc);
188 StackId sid = StackId(sysi, frame);
189
190 // check if we need to link to the previous state machine
191 int flags = args[2];
192 if (flags & FL_LINK) {
193 if (smStack[sid].size()) {
194 int prev_smi = smStack[sid].back();
195 DPRINTF(Annotate, "Linking from %d to state machine %s(%d) [%#x]\n",
196 prev_smi, sm, smi, args[1]);
197
198 if (lnMap[smi])
199 DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n",
200 smi, lnMap[smi]);
201 assert(lnMap[smi] == 0);
202 lnMap[smi] = prev_smi;
203
204 add(OP_LINK, FL_NONE, tc->contextId(), prev_smi, smi);
205 } else {
206 DPRINTF(Annotate, "Not Linking to state machine %s(%d) [%#x]\n",
207 sm, smi, args[1]);
208 }
209 }
210
211
212 smStack[sid].push_back(smi);
213
214 DPRINTF(Annotate, "Stack Now (%#X):\n", frame);
215 for (int x = smStack[sid].size()-1; x >= 0; x--)
216 DPRINTF(Annotate, "-- %d\n", smStack[sid][x]);
217
218 // reset the sw state exculsion to false
219 if (swExpl[sid])
220 swExpl[sid] = false;
221
222
223 Id id = Id(sm, frame);
224 if (scLinks[sysi-1][id]) {
225 AnnDataPtr an = scLinks[sysi-1][id];
226 scLinks[sysi-1].erase(id);
227 an->stq = smi;
228 an->dump = true;
229 DPRINTF(Annotate,
230 "Found prev unknown linking from %d to state machine %s(%d)\n",
231 an->sm, sm, smi);
232
233 if (lnMap[smi])
234 DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n",
235 smi, lnMap[smi]);
236 assert(lnMap[smi] == 0);
237 lnMap[smi] = an->sm;
238 }
239
240 // add a new begin ifwe have that info
241 if (st != "") {
242 DPRINTF(Annotate, "st: %s smi: %d stCache.size %d\n", st,
243 smi, stCache.size());
244 int sti = getSt(sm, st);
245 lastState[smi] = sti;
246 add(OP_BEGIN, FL_NONE, tc->contextId(), smi, sti);
247 }
248}
249
250void
251CPA::swSmEnd(ThreadContext *tc)
252{
253 if (!enabled())
254 return;
255
256 Arguments args(tc);
257 char sm[50];
258 CopyStringOut(tc, sm, args[0], 50);
259 System *sys = tc->getSystemPtr();
260 doSwSmEnd(sys, tc->contextId(), sm, getFrame(tc));
261}
262
263void
264CPA::doSwSmEnd(System *sys, int cpuid, string sm, uint64_t frame)
265{
266 int sysi = getSys(sys);
267 StackId sid = StackId(sysi, frame);
268
269
270 // reset the sw state exculsion to false
271 if (swExpl[sid])
272 swExpl[sid] = false;
273
274
275 int smib = smStack[sid].back();
276 StringWrap name(sys->name());
277 DPRINTF(Annotate, "Ending machine: %s[%d, %#x] (%d?)\n", sm, sysi,
278 frame, smib);
279
280 if (!smStack[sid].size() || smMap[smib-1].second.first != sm) {
281 DPRINTF(Annotate, "State Machine not unwinding correctly. sid: %d, %#x"
282 " top of stack: %s Current Stack:\n",
283 sysi, frame, smMap[smib-1].second.first);
284 for (int x = smStack[sid].size()-1; x >= 0; x--)
285 DPRINTF(Annotate, "-- %d\n", smStack[sid][x]);
286 DPRINTF(Annotate, "Ending machine: %s; end stack: %s\n", sm,
287 smMap[smib-1].second.first);
288
289 warn("State machine stack not unwinding correctly at %d\n", curTick());
290 } else {
291 DPRINTF(Annotate,
292 "State machine ending:%s sysi:%d id:%#x back:%d getSm:%d\n",
293 sm, sysi, smMap[smib-1].second.second, smStack[sid].back(),
294 getSm(sysi, sm, smMap[smib-1].second.second));
295 assert(getSm(sysi, sm, smMap[smib-1].second.second) ==
296 smStack[sid].back());
297
298 int smi = smStack[sid].back();
299 smStack[sid].pop_back();
300
301 if (lnMap[smi]) {
302 DPRINTF(Annotate, "Linking %d back to %d\n", smi, lnMap[smi]);
303 add(OP_LINK, FL_NONE, cpuid, smi, lnMap[smi]);
304 lnMap.erase(smi);
305 }
306
307 if (smStack[sid].size()) {
308 add(OP_BEGIN, FL_NONE, cpuid, smi, lastState[smi]);
309 }
310
311 DPRINTF(Annotate, "Stack Now:\n");
312 for (int x = smStack[sid].size()-1; x >= 0; x--)
313 DPRINTF(Annotate, "-- %d\n", smStack[sid][x]);
314 }
315}
316
317
318void
319CPA::swExplictBegin(ThreadContext *tc)
320{
321 if (!enabled())
322 return;
323
324 Arguments args(tc);
325 char st[50];
326 CopyStringOut(tc, st, args[1], 50);
327
328 StringWrap name(tc->getSystemPtr()->name());
329 DPRINTF(Annotate, "Explict begin of state %s\n", st);
330 uint32_t flags = args[0];
331 if (flags & FL_BAD)
332 warn("BAD state encountered: at cycle %d: %s\n", curTick(), st);
333 swBegin(tc->getSystemPtr(), tc->contextId(), st, getFrame(tc), true, args[0]);
334}
335
336void
337CPA::swAutoBegin(ThreadContext *tc, Addr next_pc)
338{
339 if (!enabled())
340 return;
341
342 string sym;
343 Addr sym_addr = 0;
344
345 if (!TheISA::inUserMode(tc)) {
346 debugSymbolTable->findNearestSymbol(next_pc, sym, sym_addr);
347 } else {
348 Linux::ThreadInfo ti(tc);
349 string app = ti.curTaskName();
350 if (userApp.count(app))
351 userApp[app]->findNearestSymbol(next_pc, sym, sym_addr);
352 }
353
354 if (sym_addr)
355 swBegin(tc->getSystemPtr(), tc->contextId(), sym, getFrame(tc));
356}
357
358void
359CPA::swBegin(System *sys, int cpuid, std::string st, uint64_t frame, bool expl,
360 int flags)
361{
362 int x = 0;
363 int len;
364 while (ignoreSymbols[x].len)
365 {
366 len = ignoreSymbols[x].len;
367 if (!st.compare(0,len, ignoreSymbols[x].symbol, len))
368 return;
369 x++;
370 }
371
372 int sysi = getSys(sys);
373 StackId sid = StackId(sysi, frame);
374 // if expl is true suspend symbol table based states
375 if (!smStack[sid].size())
376 return;
377 if (!expl && swExpl[sid])
378 return;
379 if (expl)
380 swExpl[sid] = true;
381 DPRINTFS(AnnotateVerbose, sys, "SwBegin: %s sysi: %d\n", st, sysi);
382 int smi = smStack[sid].back();
383 int sti = getSt(smMap[smi-1].second.first, st);
384 if (lastState[smi] != sti) {
385 lastState[smi] = sti;
386 add(OP_BEGIN, flags, cpuid, smi, sti);
387 }
388}
389
390void
391CPA::swEnd(ThreadContext *tc)
392{
393 if (!enabled())
394 return;
395
396 std::string st;
397 Addr junk;
398 if (!TheISA::inUserMode(tc))
399 debugSymbolTable->findNearestSymbol(
400 tc->readIntReg(ReturnAddressReg), st, junk);
401 System *sys = tc->getSystemPtr();
402 StringWrap name(sys->name());
403
404 int sysi = getSys(sys);
405 StackId sid = StackId(sysi, getFrame(tc));
406 if (!smStack[sid].size()) {
407 DPRINTF(Annotate, "Explict end of State: %s IGNORED\n", st);
408 return;
409 }
410 DPRINTF(Annotate, "Explict end of State: %s\n", st);
411 // return back to symbol table based states
412 swExpl[sid] = false;
413 int smi = smStack[sid].back();
414 if (st != "") {
415 int sti = getSt(smMap[smi-1].second.first, st);
416 lastState[smi] = sti;
417 add(OP_BEGIN, FL_NONE, tc->contextId(), smi, sti);
418 }
419}
420
421void
422CPA::swQ(ThreadContext *tc)
423{
424 if (!enabled())
425 return;
426
427 char q[50];
428 Arguments args(tc);
429 uint64_t id = args[0];
430 CopyStringOut(tc, q, args[1], 50);
431 int32_t count = args[2];
432 System *sys = tc->getSystemPtr();
433
434 int sysi = getSys(sys);
435 StackId sid = StackId(sysi, getFrame(tc));
436 if (!smStack[sid].size())
437 return;
438 int smi = smStack[sid].back();
439 if (swExpl[sid])
440 swExpl[sid] = false;
441 int qi = getQ(sysi, q, id);
442 if (count == 0) {
443 //warn("Tried to queue 0 bytes in %s, ignoring\n", q);
444 return;
445 }
446 DPRINTFS(AnnotateQ, sys,
447 "swQ: %s[%#x] cur size %d %d bytes: %d adding: %d\n",
448 q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
449 doQ(sys, FL_NONE, tc->contextId(), smi, q, qi, count);
450}
451
452void
453CPA::swDq(ThreadContext *tc)
454{
455 if (!enabled())
456 return;
457
458 char q[50];
459 Arguments args(tc);
460 uint64_t id = args[0];
461 CopyStringOut(tc, q, args[1], 50);
462 int32_t count = args[2];
463 System *sys = tc->getSystemPtr();
464
465 int sysi = getSys(sys);
466 StackId sid = StackId(sysi, getFrame(tc));
467 if (!smStack[sid].size())
468 return;
469 int smi = smStack[sid].back();
470 int qi = getQ(sysi, q, id);
471 if (swExpl[sid])
472 swExpl[sid] = false;
473 DPRINTFS(AnnotateQ, sys,
474 "swDq: %s[%#x] cur size %d %d bytes: %d removing: %d\n",
475 q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
476 assert(count != 0);
477
478 doDq(sys, FL_NONE, tc->contextId(), smi, q, qi, count);
479}
480
481void
482CPA::swPq(ThreadContext *tc)
483{
484 if (!enabled())
485 return;
486
487 char q[50];
488 Arguments args(tc);
489 uint64_t id = args[0];
490 CopyStringOut(tc, q, args[1], 50);
491 System *sys = tc->getSystemPtr();
492 int32_t count = args[2];
493
494 int sysi = getSys(sys);
495 StackId sid = StackId(sysi, getFrame(tc));
496 if (!smStack[sid].size())
497 return;
498 int smi = smStack[sid].back();
499 int qi = getQ(sysi, q, id);
500 if (swExpl[sid])
501 swExpl[sid] = false;
502 DPRINTFS(AnnotateQ, sys,
503 "swPq: %s [%#x] cur size %d %d bytes: %d peeking: %d\n",
504 q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
505
506 assert(count != 0);
507 if (qBytes[qi-1] < count) {
508 dump(true);
509 dumpKey();
510 fatal("Queue %s peeking with not enough bytes available in queue!\n", q);
511 }
512
513 add(OP_PEEK, FL_NONE, tc->contextId(), smi, qi, count);
514}
515
516void
517CPA::swRq(ThreadContext *tc)
518{
519 if (!enabled())
520 return;
521
522 char q[50];
523 Arguments args(tc);
524 uint64_t id = args[0];
525 CopyStringOut(tc, q, args[1], 50);
526 System *sys = tc->getSystemPtr();
527 int32_t count = args[2];
528
529 int sysi = getSys(sys);
530 StackId sid = StackId(sysi, getFrame(tc));
531 if (!smStack[sid].size())
532 return;
533 int smi = smStack[sid].back();
534 int qi = getQ(sysi, q, id);
535 if (swExpl[sid])
536 swExpl[sid] = false;
537 DPRINTFS(AnnotateQ, sys,
538 "swRq: %s [%#x] cur size %d %d bytes: %d reserve: %d\n",
539 q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
540
541 assert(count != 0);
542
543 add(OP_RESERVE, FL_NONE, tc->contextId(), smi, qi, count);
544}
545
546
547void
548CPA::swWf(ThreadContext *tc)
549{
550 if (!enabled())
551 return;
552
553 char q[50];
554 Arguments args(tc);
555 uint64_t id = args[0];
556 CopyStringOut(tc, q, args[1], 50);
557 System *sys = tc->getSystemPtr();
558 int32_t count = args[3];
559
560 int sysi = getSys(sys);
561 StackId sid = StackId(sysi, getFrame(tc));
562 if (!smStack[sid].size())
563 return;
564 int smi = smStack[sid].back();
565 int qi = getQ(sysi, q, id);
566 add(OP_WAIT_FULL, FL_NONE, tc->contextId(), smi, qi, count);
567
568 if (!!args[2]) {
569 char sm[50];
570 CopyStringOut(tc, sm, args[2], 50);
571 doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
572 }
573}
574
575void
576CPA::swWe(ThreadContext *tc)
577{
578 if (!enabled())
579 return;
580
581 char q[50];
582 Arguments args(tc);
583 uint64_t id = args[0];
584 CopyStringOut(tc, q, args[1], 50);
585 System *sys = tc->getSystemPtr();
586 int32_t count = args[3];
587
588 int sysi = getSys(sys);
589 StackId sid = StackId(sysi, getFrame(tc));
590 if (!smStack[sid].size())
591 return;
592 int smi = smStack[sid].back();
593 int qi = getQ(sysi, q, id);
594 add(OP_WAIT_EMPTY, FL_NONE, tc->contextId(), smi, qi, count);
595
596 if (!!args[2]) {
597 char sm[50];
598 CopyStringOut(tc, sm, args[2], 50);
599 doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
600 }
601}
602
603void
604CPA::swSq(ThreadContext *tc)
605{
606 if (!enabled())
607 return;
608
609 char q[50];
610 Arguments args(tc);
611 uint64_t id = args[0];
612 CopyStringOut(tc, q, args[1], 50);
613 System *sys = tc->getSystemPtr();
614 StringWrap name(sys->name());
615 int32_t size = args[2];
616 int flags = args[3];
617
618 int sysi = getSys(sys);
619 StackId sid = StackId(sysi, getFrame(tc));
620 if (!smStack[sid].size())
621 return;
622 int smi = smStack[sid].back();
623 int qi = getQ(sysi, q, id);
624 DPRINTF(AnnotateQ, "swSq: %s [%#x] cur size: %d bytes: %d, new size: %d\n",
625 q, id, qSize[qi-1], qBytes[qi-1], size);
626
627 if (FL_RESET & flags) {
628 DPRINTF(AnnotateQ, "Resetting Queue %s\n", q);
629 add(OP_SIZE_QUEUE, FL_NONE, tc->contextId(), smi, qi, 0);
630 qData[qi-1].clear();
631 qSize[qi-1] = 0;
632 qBytes[qi-1] = 0;
633 }
634
635 if (qBytes[qi-1] < size)
636 doQ(sys, FL_NONE, tc->contextId(), smi, q, qi, size - qBytes[qi-1]);
637 else if (qBytes[qi-1] > size) {
638 DPRINTF(AnnotateQ, "removing for resize of queue %s\n", q);
639 add(OP_SIZE_QUEUE, FL_NONE, tc->contextId(), smi, qi, size);
640 if (size <= 0) {
641 qData[qi-1].clear();
642 qSize[qi-1] = 0;
643 qBytes[qi-1] = 0;
644 return;
645 }
646 int need = qBytes[qi-1] - size;
647 qBytes[qi-1] = size;
648 while (need > 0) {
649 int32_t tail_bytes = qData[qi-1].back()->data;
650 if (qSize[qi-1] <= 0 || qBytes[qi-1] < 0) {
651 dump(true);
652 dumpKey();
653 fatal("Queue %s had inconsistancy when doing size queue!\n", q);
654 }
655 if (tail_bytes > need) {
656 qData[qi-1].back()->data -= need;
657 need = 0;
658 } else if (tail_bytes == need) {
659 qData[qi-1].pop_back();
660 qSize[qi-1]--;
661 need = 0;
662 } else {
663 qData[qi-1].pop_back();
664 qSize[qi-1]--;
665 need -= tail_bytes;
666 }
667 }
668 }
669}
670
671void
672CPA::swAq(ThreadContext *tc)
673{
674 if (!enabled())
675 return;
676
677 char q[50];
678 Arguments args(tc);
679 uint64_t id = args[0];
680 CopyStringOut(tc, q, args[1], 50);
681 System *sys = tc->getSystemPtr();
682 StringWrap name(sys->name());
683 int32_t size = args[2];
684
685 int sysi = getSys(sys);
686 int qi = getQ(sysi, q, id);
687 if (qBytes[qi-1] != size) {
688 DPRINTF(AnnotateQ, "Queue %s [%#x] has inconsintant size\n", q, id);
689 //dump(true);
690 //dumpKey();
691 std::list<AnnDataPtr>::iterator ai = qData[qi-1].begin();
692 int x = 0;
693 while (ai != qData[qi-1].end()) {
694 DPRINTF(AnnotateQ, "--Element %d size %d\n", x, (*ai)->data);
695 ai++;
696 x++;
697 }
698
699 warn("%d: Queue Assert: SW said there should be %d byte(s) in %s,"
700 "however there are %d byte(s)\n",
701 curTick(), size, q, qBytes[qi-1]);
702 DPRINTF(AnnotateQ, "%d: Queue Assert: SW said there should be %d"
703 " byte(s) in %s, however there are %d byte(s)\n",
704 curTick(), size, q, qBytes[qi-1]);
705 }
706}
707
708void
709CPA::swLink(ThreadContext *tc)
710{
711 if (!enabled())
712 return;
713
714 char lsm[50];
715 Arguments args(tc);
716 CopyStringOut(tc, lsm, args[0], 50);
717 System *sys = tc->getSystemPtr();
718 StringWrap name(sys->name());
719
720 int sysi = getSys(sys);
721 StackId sid = StackId(sysi, getFrame(tc));
722 if (!smStack[sid].size())
723 return;
724 int smi = smStack[sid].back();
725 int lsmi = getSm(sysi, lsm, args[1]);
726
727 DPRINTF(Annotate, "Linking from %d to state machine %s(%d) [%#x]\n",
728 smi, lsm, lsmi, args[1]);
729
730 if (lnMap[lsmi])
731 DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n",
732 lsmi, lnMap[lsmi]);
733 assert(lnMap[lsmi] == 0);
734 lnMap[lsmi] = smi;
735
736 add(OP_LINK, FL_NONE, tc->contextId(), smi, lsmi);
737
738 if (!!args[2]) {
739 char sm[50];
740 CopyStringOut(tc, sm, args[2], 50);
741 doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
742 }
743}
744
745void
746CPA::swIdentify(ThreadContext *tc)
747{
748 if (!enabled())
749 return;
750
751 Arguments args(tc);
752 int sysi = getSys(tc->getSystemPtr());
753 StackId sid = StackId(sysi, getFrame(tc));
754 if (!smStack[sid].size())
755 return;
756 int smi = smStack[sid].back();
757
758 DPRINTFS(Annotate, tc->getSystemPtr(), "swIdentify: id %#X\n", args[0]);
759
760 add(OP_IDENT, FL_NONE, tc->contextId(), smi, 0, args[0]);
761}
762
763uint64_t
764CPA::swGetId(ThreadContext *tc)
765{
766 if (!enabled())
767 return 0;
768
769 uint64_t id = ++conId;
770 int sysi = getSys(tc->getSystemPtr());
771 StackId sid = StackId(sysi, getFrame(tc));
772 if (!smStack[sid].size())
773 panic("swGetId called without a state machine stack!");
774 int smi = smStack[sid].back();
775
776 DPRINTFS(Annotate, tc->getSystemPtr(), "swGetId: id %#X\n", id);
777
778 add(OP_IDENT, FL_NONE, tc->contextId(), smi, 0, id);
779 return id;
780}
781
782
783void
784CPA::swSyscallLink(ThreadContext *tc)
785{
786 if (!enabled())
787 return;
788
789 char lsm[50];
790 Arguments args(tc);
791 CopyStringOut(tc, lsm, args[0], 50);
792 System *sys = tc->getSystemPtr();
793 StringWrap name(sys->name());
794 int sysi = getSys(sys);
795
796 Id id = Id(lsm, getFrame(tc));
797 StackId sid = StackId(sysi, getFrame(tc));
798
799 if (!smStack[sid].size())
800 return;
801
802 int smi = smStack[sid].back();
803
804 DPRINTF(Annotate, "Linking from %d to state machine %s(UNKNOWN)\n",
805 smi, lsm);
806
807 if (scLinks[sysi-1][id])
808 DPRINTF(Annotate,
809 "scLinks already contains entry for system %d %s[%x] of %d\n",
810 sysi, lsm, getFrame(tc), scLinks[sysi-1][id]);
811 assert(scLinks[sysi-1][id] == 0);
812 scLinks[sysi-1][id] = add(OP_LINK, FL_NONE, tc->contextId(), smi, 0xFFFF);
813 scLinks[sysi-1][id]->dump = false;
814
815 if (!!args[1]) {
816 char sm[50];
817 CopyStringOut(tc, sm, args[1], 50);
818 doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
819 }
820}
821
822CPA::AnnDataPtr
823CPA::add(int t, int f, int c, int sm, int stq, int32_t d)
824{
825 AnnDataPtr an = std::make_shared<AnnotateData>();
826 an->time = curTick();
827 an->data = d;
828 an->orig_data = d;
829 an->op = t;
830 an->flag = f;
831 an->sm = sm;
832 an->stq = stq;
833 an->cpu = c;
834 an->dump = true;
835
836 data.push_back(an);
837
838 DPRINTF(AnnotateVerbose, "Annotate: op: %d flags: 0x%x sm: %d state: %d time: %d, data: %d\n",
839 an->op, an->flag, an->sm, an->stq, an->time, an->data);
840
841 // Don't dump Links because we might be setting no-dump on it
842 if (an->op != OP_LINK)
843 dump(false);
844
845 return an;
846}
847
848void
849CPA::dumpKey()
850{
851 std::streampos curpos = osbin->tellp();
852 ah.key_off = curpos;
853
854 // Output the various state machines and their corresponding states
855 *osbin << "# Automatically generated state machine descriptor file" << endl;
856
857 *osbin << "sms = {}" << endl << endl;
858 vector<string> state_machines;
859 state_machines.resize(numSmt+1);
860
861 // State machines, id -> states
862 SCache::iterator i = smtCache.begin();
863 while (i != smtCache.end()) {
864 state_machines[i->second] = i->first;
865 i++;
866 }
867
868 for (int x = 1; x < state_machines.size(); x++) {
869 vector<string> states;
870 states.resize(numSt[x-1]+1);
871 assert(x-1 < stCache.size());
872 SCache::iterator i = stCache[x-1].begin();
873 while (i != stCache[x-1].end()) {
874 states[i->second] = i->first;
875 i++;
876 }
877 *osbin << "sms[\"" << state_machines[x] << "\"] = [\"NULL\"";
878 for (int y = 1; y < states.size(); y++)
879 *osbin << ", \"" << states[y] << "\"";
880 *osbin << "]" << endl;
881 }
882
883 *osbin << endl << endl << endl;
884
885 // state machine number -> system, name, id
886 *osbin << "smNum = [\"NULL\"";
887 for (int x = 0; x < smMap.size(); x++)
888 *osbin << ", (" << smMap[x].first << ", \"" << smMap[x].second.first <<
889 "\", " << smMap[x].second.second << ")";
890 *osbin << "]" << endl;
891
892 *osbin << endl << endl << endl;
893
894 // Output the systems
895 vector<string> systems;
896 systems.resize(numSys+1);
897 NameCache::iterator i2 = nameCache.begin();
898 while (i2 != nameCache.end()) {
899 systems[i2->second.second] = i2->second.first;
900 i2++;
901 }
902
903 *osbin << "sysNum = [\"NULL\"";
904 for (int x = 1; x < systems.size(); x++) {
905 *osbin << ", \"" << systems[x] << "\"";
906 }
907 *osbin << "]" << endl;
908
909 // queue number -> system, qname, qid
910 *osbin << "queues = [\"NULL\"";
911 for (int x = 0; x < qMap.size(); x++)
912 *osbin << ", (" << qMap[x].first << ", \"" << qMap[x].second.first <<
913 "\", " << qMap[x].second.second << ")";
914 *osbin << "]" << endl;
915
916 *osbin << "smComb = [s for s in [(i,r) for i in xrange(1,len(sysNum)) "
917 << "for r in xrange (1,len(smNum))]]" << endl;
918 ah.key_len = osbin->tellp() - curpos;
919
920 // output index
921 curpos = osbin->tellp();
922 ah.idx_off = curpos;
923
924 for (int x = 0; x < annotateIdx.size(); x++)
925 osbin->write((char*)&annotateIdx[x], sizeof(uint64_t));
926 ah.idx_len = osbin->tellp() - curpos;
927
928 osbin->seekp(0);
929 osbin->write((char*)&ah, sizeof(AnnotateHeader));
930 osbin->flush();
931
932}
933
934void
935CPA::dump(bool all)
936{
937
938 list<AnnDataPtr>::iterator i;
939
940 i = data.begin();
941
942 if (i == data.end())
943 return;
944
945 // Dump the data every
946 if (!all && data.size() < 10000)
947 return;
948
949 DPRINTF(Annotate, "Writing %d\n", data.size());
950 while (i != data.end()) {
951 AnnDataPtr an = *i;
952
953 // If we can't dump this record, hold here
954 if (!an->dump && !all)
955 break;
956
957 ah.num_recs++;
958 if (ah.num_recs % 100000 == 0)
959 annotateIdx.push_back(osbin->tellp());
960
961
962 osbin->write((char*)&(an->time), sizeof(an->time));
963 osbin->write((char*)&(an->orig_data), sizeof(an->orig_data));
964 osbin->write((char*)&(an->sm), sizeof(an->sm));
965 osbin->write((char*)&(an->stq), sizeof(an->stq));
966 osbin->write((char*)&(an->op), sizeof(an->op));
967 osbin->write((char*)&(an->flag), sizeof(an->flag));
968 osbin->write((char*)&(an->cpu), sizeof(an->cpu));
969 i++;
970 }
971 if (data.begin() != i)
972 data.erase(data.begin(), i);
973
974 if (all)
975 osbin->flush();
976}
977
978void
979CPA::doQ(System *sys, int flags, int cpuid, int sm,
980 string q, int qi, int count)
981{
982 qSize[qi-1]++;
983 qBytes[qi-1] += count;
984 if (qSize[qi-1] > 2501 || qBytes[qi-1] > 2000000000)
985 warn("Queue %s is %d elements/%d bytes, "
986 "maybe things aren't being removed?\n",
987 q, qSize[qi-1], qBytes[qi-1]);
988 if (flags & FL_QOPP)
989 qData[qi-1].push_front(add(OP_QUEUE, flags, cpuid, sm, qi, count));
990 else
991 qData[qi-1].push_back(add(OP_QUEUE, flags, cpuid, sm, qi, count));
992 DPRINTFS(AnnotateQ, sys, "Queing in queue %s size now %d/%d\n",
993 q, qSize[qi-1], qBytes[qi-1]);
994 assert(qSize[qi-1] >= 0);
995 assert(qBytes[qi-1] >= 0);
996}
997
998
999void
1000CPA::doDq(System *sys, int flags, int cpuid, int sm,
1001 string q, int qi, int count)
1002{
1003
1004 StringWrap name(sys->name());
1005 if (count == -1) {
1006 add(OP_DEQUEUE, flags, cpuid, sm, qi, count);
1007 qData[qi-1].clear();
1008 qSize[qi-1] = 0;
1009 qBytes[qi-1] = 0;
1010 DPRINTF(AnnotateQ, "Dequeing all data in queue %s size now %d/%d\n",
1011 q, qSize[qi-1], qBytes[qi-1]);
1012 return;
1013 }
1014
1015 assert(count > 0);
1016 if (qSize[qi-1] <= 0 || qBytes[qi-1] <= 0 || !qData[qi-1].size()) {
1017 dump(true);
1018 dumpKey();
1019 fatal("Queue %s dequing with no data available in queue!\n",
1020 q);
1021 }
1022 assert(qSize[qi-1] >= 0);
1023 assert(qBytes[qi-1] >= 0);
1024 assert(qData[qi-1].size());
1025
1026 int32_t need = count;
1027 qBytes[qi-1] -= count;
1028 if (qBytes[qi-1] < 0) {
1029 dump(true);
1030 dumpKey();
1031 fatal("Queue %s dequing with no bytes available in queue!\n",
1032 q);
1033 }
1034
1035 while (need > 0) {
1036 int32_t head_bytes = qData[qi-1].front()->data;
1037 if (qSize[qi-1] <= 0 || qBytes[qi-1] < 0) {
1038 dump(true);
1039 dumpKey();
1040 fatal("Queue %s dequing with nothing in queue!\n",
1041 q);
1042 }
1043
1044 if (head_bytes > need) {
1045 qData[qi-1].front()->data -= need;
1046 need = 0;
1047 } else if (head_bytes == need) {
1048 qData[qi-1].pop_front();
1049 qSize[qi-1]--;
1050 need = 0;
1051 } else {
1052 qData[qi-1].pop_front();
1053 qSize[qi-1]--;
1054 need -= head_bytes;
1055 }
1056 }
1057
1058 add(OP_DEQUEUE, flags, cpuid, sm, qi, count);
1059 DPRINTF(AnnotateQ, "Dequeing in queue %s size now %d/%d\n",
1060 q, qSize[qi-1], qBytes[qi-1]);
1061}
1062
1063
1064
1065void
1/*
2 * Copyright (c) 2006-2009 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Ali Saidi
29 */
30
31#include "arch/generic/linux/threadinfo.hh"
32#include "arch/utility.hh"
33#include "base/loader/object_file.hh"
34#include "base/callback.hh"
35#include "base/cp_annotate.hh"
36#include "base/output.hh"
37#include "base/trace.hh"
38#include "config/the_isa.hh"
39#include "cpu/thread_context.hh"
40#include "debug/Annotate.hh"
41#include "debug/AnnotateVerbose.hh"
42#include "sim/arguments.hh"
43#include "sim/core.hh"
44#include "sim/sim_exit.hh"
45#include "sim/system.hh"
46
47struct CPAIgnoreSymbol
48{
49 const char *symbol;
50 size_t len;
51};
52#define CPA_IGNORE_SYMBOL(sym) { #sym, sizeof(#sym) }
53
54CPAIgnoreSymbol ignoreSymbols[] = {
55 CPA_IGNORE_SYMBOL("m5a_"),
56 CPA_IGNORE_SYMBOL("ret_from_sys_call"),
57 CPA_IGNORE_SYMBOL("ret_from_reschedule"),
58 CPA_IGNORE_SYMBOL("_spin_"),
59 CPA_IGNORE_SYMBOL("local_bh_"),
60 CPA_IGNORE_SYMBOL("restore_all"),
61 CPA_IGNORE_SYMBOL("Call_Pal_"),
62 CPA_IGNORE_SYMBOL("pal_post_interrupt"),
63 CPA_IGNORE_SYMBOL("rti_to_"),
64 CPA_IGNORE_SYMBOL("sys_int_2"),
65 CPA_IGNORE_SYMBOL("sys_interrupt"),
66 CPA_IGNORE_SYMBOL("normal_int"),
67 CPA_IGNORE_SYMBOL("TRAP_INTERRUPT_10_"),
68 CPA_IGNORE_SYMBOL("Trap_Interrupt"),
69 CPA_IGNORE_SYMBOL("do_entInt"),
70 CPA_IGNORE_SYMBOL("__do_softirq"),
71 CPA_IGNORE_SYMBOL("_end"),
72 CPA_IGNORE_SYMBOL("entInt"),
73 CPA_IGNORE_SYMBOL("entSys"),
74 {0,0}
75};
76#undef CPA_IGNORE_SYMBOL
77
78using namespace std;
79using namespace TheISA;
80
81bool CPA::exists;
82CPA *CPA::_cpa;
83
84class AnnotateDumpCallback : public Callback
85{
86
87 private:
88 CPA *cpa;
89 public:
90 virtual void process();
91 AnnotateDumpCallback(CPA *_cpa)
92 : cpa(_cpa)
93 {}
94};
95
96void
97AnnotateDumpCallback::process()
98{
99 cpa->dump(true);
100 cpa->dumpKey();
101}
102
103
104CPA::CPA(Params *p)
105 : SimObject(p), numSm(0), numSmt(0), numSys(0), numQs(0), conId(0)
106{
107 if (exists)
108 fatal("Multiple annotation objects found in system");
109 exists = true;
110
111 _enabled = p->enabled;
112 _cpa = this;
113
114 vector<string>::iterator i;
115 i = p->user_apps.begin();
116
117 while (i != p->user_apps.end()) {
118 ObjectFile *of = createObjectFile(*i);
119 string sf;
120 if (!of)
121 fatal("Couldn't load symbols from file: %s\n", *i);
122 sf = *i;
123 sf.erase(0, sf.rfind('/') + 1);;
124 DPRINTFN("file %s short: %s\n", *i, sf);
125 userApp[sf] = new SymbolTable;
126 bool result1 = of->loadGlobalSymbols(userApp[sf]);
127 bool result2 = of->loadLocalSymbols(userApp[sf]);
128 if (!result1 || !result2)
129 panic("blah");
130 assert(result1 && result2);
131 i++;
132 }
133}
134
135void
136CPA::startup()
137{
138 osbin = simout.create("annotate.bin", true);
139 // MAGIC version number 'M''5''A'N' + version/capabilities
140 ah.version = 0x4D35414E00000101ULL;
141 ah.num_recs = 0;
142 ah.key_off = 0;
143 osbin->write((char*)&ah, sizeof(AnnotateHeader));
144
145 registerExitCallback(new AnnotateDumpCallback(this));
146}
147
148uint64_t
149CPA::getFrame(ThreadContext *tc)
150{
151 // This code is ISA specific and will need to be changed
152 // if the annotation code is used for something other than Alpha
153 return (tc->readMiscRegNoEffect(TheISA::IPR_PALtemp23) &
154 ~ULL(0x3FFF));
155
156}
157
158void
159CPA::swSmBegin(ThreadContext *tc)
160{
161 if (!enabled())
162 return;
163
164 Arguments args(tc);
165 std::string st;
166 Addr junk;
167 char sm[50];
168 if (!TheISA::inUserMode(tc))
169 debugSymbolTable->findNearestSymbol(
170 tc->readIntReg(ReturnAddressReg), st, junk);
171
172 CopyStringOut(tc, sm, args[0], 50);
173 System *sys = tc->getSystemPtr();
174 StringWrap name(sys->name());
175
176 if (!sm[0])
177 warn("Got null SM at tick %d\n", curTick());
178
179 int sysi = getSys(sys);
180 int smi = getSm(sysi, sm, args[1]);
181 DPRINTF(Annotate, "Starting machine: %s(%d) sysi: %d id: %#x\n", sm,
182 smi, sysi, args[1]);
183 DPRINTF(Annotate, "smMap[%d] = %d, %s, %#x\n", smi,
184 smMap[smi-1].first, smMap[smi-1].second.first,
185 smMap[smi-1].second.second);
186
187 uint64_t frame = getFrame(tc);
188 StackId sid = StackId(sysi, frame);
189
190 // check if we need to link to the previous state machine
191 int flags = args[2];
192 if (flags & FL_LINK) {
193 if (smStack[sid].size()) {
194 int prev_smi = smStack[sid].back();
195 DPRINTF(Annotate, "Linking from %d to state machine %s(%d) [%#x]\n",
196 prev_smi, sm, smi, args[1]);
197
198 if (lnMap[smi])
199 DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n",
200 smi, lnMap[smi]);
201 assert(lnMap[smi] == 0);
202 lnMap[smi] = prev_smi;
203
204 add(OP_LINK, FL_NONE, tc->contextId(), prev_smi, smi);
205 } else {
206 DPRINTF(Annotate, "Not Linking to state machine %s(%d) [%#x]\n",
207 sm, smi, args[1]);
208 }
209 }
210
211
212 smStack[sid].push_back(smi);
213
214 DPRINTF(Annotate, "Stack Now (%#X):\n", frame);
215 for (int x = smStack[sid].size()-1; x >= 0; x--)
216 DPRINTF(Annotate, "-- %d\n", smStack[sid][x]);
217
218 // reset the sw state exculsion to false
219 if (swExpl[sid])
220 swExpl[sid] = false;
221
222
223 Id id = Id(sm, frame);
224 if (scLinks[sysi-1][id]) {
225 AnnDataPtr an = scLinks[sysi-1][id];
226 scLinks[sysi-1].erase(id);
227 an->stq = smi;
228 an->dump = true;
229 DPRINTF(Annotate,
230 "Found prev unknown linking from %d to state machine %s(%d)\n",
231 an->sm, sm, smi);
232
233 if (lnMap[smi])
234 DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n",
235 smi, lnMap[smi]);
236 assert(lnMap[smi] == 0);
237 lnMap[smi] = an->sm;
238 }
239
240 // add a new begin ifwe have that info
241 if (st != "") {
242 DPRINTF(Annotate, "st: %s smi: %d stCache.size %d\n", st,
243 smi, stCache.size());
244 int sti = getSt(sm, st);
245 lastState[smi] = sti;
246 add(OP_BEGIN, FL_NONE, tc->contextId(), smi, sti);
247 }
248}
249
250void
251CPA::swSmEnd(ThreadContext *tc)
252{
253 if (!enabled())
254 return;
255
256 Arguments args(tc);
257 char sm[50];
258 CopyStringOut(tc, sm, args[0], 50);
259 System *sys = tc->getSystemPtr();
260 doSwSmEnd(sys, tc->contextId(), sm, getFrame(tc));
261}
262
263void
264CPA::doSwSmEnd(System *sys, int cpuid, string sm, uint64_t frame)
265{
266 int sysi = getSys(sys);
267 StackId sid = StackId(sysi, frame);
268
269
270 // reset the sw state exculsion to false
271 if (swExpl[sid])
272 swExpl[sid] = false;
273
274
275 int smib = smStack[sid].back();
276 StringWrap name(sys->name());
277 DPRINTF(Annotate, "Ending machine: %s[%d, %#x] (%d?)\n", sm, sysi,
278 frame, smib);
279
280 if (!smStack[sid].size() || smMap[smib-1].second.first != sm) {
281 DPRINTF(Annotate, "State Machine not unwinding correctly. sid: %d, %#x"
282 " top of stack: %s Current Stack:\n",
283 sysi, frame, smMap[smib-1].second.first);
284 for (int x = smStack[sid].size()-1; x >= 0; x--)
285 DPRINTF(Annotate, "-- %d\n", smStack[sid][x]);
286 DPRINTF(Annotate, "Ending machine: %s; end stack: %s\n", sm,
287 smMap[smib-1].second.first);
288
289 warn("State machine stack not unwinding correctly at %d\n", curTick());
290 } else {
291 DPRINTF(Annotate,
292 "State machine ending:%s sysi:%d id:%#x back:%d getSm:%d\n",
293 sm, sysi, smMap[smib-1].second.second, smStack[sid].back(),
294 getSm(sysi, sm, smMap[smib-1].second.second));
295 assert(getSm(sysi, sm, smMap[smib-1].second.second) ==
296 smStack[sid].back());
297
298 int smi = smStack[sid].back();
299 smStack[sid].pop_back();
300
301 if (lnMap[smi]) {
302 DPRINTF(Annotate, "Linking %d back to %d\n", smi, lnMap[smi]);
303 add(OP_LINK, FL_NONE, cpuid, smi, lnMap[smi]);
304 lnMap.erase(smi);
305 }
306
307 if (smStack[sid].size()) {
308 add(OP_BEGIN, FL_NONE, cpuid, smi, lastState[smi]);
309 }
310
311 DPRINTF(Annotate, "Stack Now:\n");
312 for (int x = smStack[sid].size()-1; x >= 0; x--)
313 DPRINTF(Annotate, "-- %d\n", smStack[sid][x]);
314 }
315}
316
317
318void
319CPA::swExplictBegin(ThreadContext *tc)
320{
321 if (!enabled())
322 return;
323
324 Arguments args(tc);
325 char st[50];
326 CopyStringOut(tc, st, args[1], 50);
327
328 StringWrap name(tc->getSystemPtr()->name());
329 DPRINTF(Annotate, "Explict begin of state %s\n", st);
330 uint32_t flags = args[0];
331 if (flags & FL_BAD)
332 warn("BAD state encountered: at cycle %d: %s\n", curTick(), st);
333 swBegin(tc->getSystemPtr(), tc->contextId(), st, getFrame(tc), true, args[0]);
334}
335
336void
337CPA::swAutoBegin(ThreadContext *tc, Addr next_pc)
338{
339 if (!enabled())
340 return;
341
342 string sym;
343 Addr sym_addr = 0;
344
345 if (!TheISA::inUserMode(tc)) {
346 debugSymbolTable->findNearestSymbol(next_pc, sym, sym_addr);
347 } else {
348 Linux::ThreadInfo ti(tc);
349 string app = ti.curTaskName();
350 if (userApp.count(app))
351 userApp[app]->findNearestSymbol(next_pc, sym, sym_addr);
352 }
353
354 if (sym_addr)
355 swBegin(tc->getSystemPtr(), tc->contextId(), sym, getFrame(tc));
356}
357
358void
359CPA::swBegin(System *sys, int cpuid, std::string st, uint64_t frame, bool expl,
360 int flags)
361{
362 int x = 0;
363 int len;
364 while (ignoreSymbols[x].len)
365 {
366 len = ignoreSymbols[x].len;
367 if (!st.compare(0,len, ignoreSymbols[x].symbol, len))
368 return;
369 x++;
370 }
371
372 int sysi = getSys(sys);
373 StackId sid = StackId(sysi, frame);
374 // if expl is true suspend symbol table based states
375 if (!smStack[sid].size())
376 return;
377 if (!expl && swExpl[sid])
378 return;
379 if (expl)
380 swExpl[sid] = true;
381 DPRINTFS(AnnotateVerbose, sys, "SwBegin: %s sysi: %d\n", st, sysi);
382 int smi = smStack[sid].back();
383 int sti = getSt(smMap[smi-1].second.first, st);
384 if (lastState[smi] != sti) {
385 lastState[smi] = sti;
386 add(OP_BEGIN, flags, cpuid, smi, sti);
387 }
388}
389
390void
391CPA::swEnd(ThreadContext *tc)
392{
393 if (!enabled())
394 return;
395
396 std::string st;
397 Addr junk;
398 if (!TheISA::inUserMode(tc))
399 debugSymbolTable->findNearestSymbol(
400 tc->readIntReg(ReturnAddressReg), st, junk);
401 System *sys = tc->getSystemPtr();
402 StringWrap name(sys->name());
403
404 int sysi = getSys(sys);
405 StackId sid = StackId(sysi, getFrame(tc));
406 if (!smStack[sid].size()) {
407 DPRINTF(Annotate, "Explict end of State: %s IGNORED\n", st);
408 return;
409 }
410 DPRINTF(Annotate, "Explict end of State: %s\n", st);
411 // return back to symbol table based states
412 swExpl[sid] = false;
413 int smi = smStack[sid].back();
414 if (st != "") {
415 int sti = getSt(smMap[smi-1].second.first, st);
416 lastState[smi] = sti;
417 add(OP_BEGIN, FL_NONE, tc->contextId(), smi, sti);
418 }
419}
420
421void
422CPA::swQ(ThreadContext *tc)
423{
424 if (!enabled())
425 return;
426
427 char q[50];
428 Arguments args(tc);
429 uint64_t id = args[0];
430 CopyStringOut(tc, q, args[1], 50);
431 int32_t count = args[2];
432 System *sys = tc->getSystemPtr();
433
434 int sysi = getSys(sys);
435 StackId sid = StackId(sysi, getFrame(tc));
436 if (!smStack[sid].size())
437 return;
438 int smi = smStack[sid].back();
439 if (swExpl[sid])
440 swExpl[sid] = false;
441 int qi = getQ(sysi, q, id);
442 if (count == 0) {
443 //warn("Tried to queue 0 bytes in %s, ignoring\n", q);
444 return;
445 }
446 DPRINTFS(AnnotateQ, sys,
447 "swQ: %s[%#x] cur size %d %d bytes: %d adding: %d\n",
448 q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
449 doQ(sys, FL_NONE, tc->contextId(), smi, q, qi, count);
450}
451
452void
453CPA::swDq(ThreadContext *tc)
454{
455 if (!enabled())
456 return;
457
458 char q[50];
459 Arguments args(tc);
460 uint64_t id = args[0];
461 CopyStringOut(tc, q, args[1], 50);
462 int32_t count = args[2];
463 System *sys = tc->getSystemPtr();
464
465 int sysi = getSys(sys);
466 StackId sid = StackId(sysi, getFrame(tc));
467 if (!smStack[sid].size())
468 return;
469 int smi = smStack[sid].back();
470 int qi = getQ(sysi, q, id);
471 if (swExpl[sid])
472 swExpl[sid] = false;
473 DPRINTFS(AnnotateQ, sys,
474 "swDq: %s[%#x] cur size %d %d bytes: %d removing: %d\n",
475 q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
476 assert(count != 0);
477
478 doDq(sys, FL_NONE, tc->contextId(), smi, q, qi, count);
479}
480
481void
482CPA::swPq(ThreadContext *tc)
483{
484 if (!enabled())
485 return;
486
487 char q[50];
488 Arguments args(tc);
489 uint64_t id = args[0];
490 CopyStringOut(tc, q, args[1], 50);
491 System *sys = tc->getSystemPtr();
492 int32_t count = args[2];
493
494 int sysi = getSys(sys);
495 StackId sid = StackId(sysi, getFrame(tc));
496 if (!smStack[sid].size())
497 return;
498 int smi = smStack[sid].back();
499 int qi = getQ(sysi, q, id);
500 if (swExpl[sid])
501 swExpl[sid] = false;
502 DPRINTFS(AnnotateQ, sys,
503 "swPq: %s [%#x] cur size %d %d bytes: %d peeking: %d\n",
504 q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
505
506 assert(count != 0);
507 if (qBytes[qi-1] < count) {
508 dump(true);
509 dumpKey();
510 fatal("Queue %s peeking with not enough bytes available in queue!\n", q);
511 }
512
513 add(OP_PEEK, FL_NONE, tc->contextId(), smi, qi, count);
514}
515
516void
517CPA::swRq(ThreadContext *tc)
518{
519 if (!enabled())
520 return;
521
522 char q[50];
523 Arguments args(tc);
524 uint64_t id = args[0];
525 CopyStringOut(tc, q, args[1], 50);
526 System *sys = tc->getSystemPtr();
527 int32_t count = args[2];
528
529 int sysi = getSys(sys);
530 StackId sid = StackId(sysi, getFrame(tc));
531 if (!smStack[sid].size())
532 return;
533 int smi = smStack[sid].back();
534 int qi = getQ(sysi, q, id);
535 if (swExpl[sid])
536 swExpl[sid] = false;
537 DPRINTFS(AnnotateQ, sys,
538 "swRq: %s [%#x] cur size %d %d bytes: %d reserve: %d\n",
539 q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
540
541 assert(count != 0);
542
543 add(OP_RESERVE, FL_NONE, tc->contextId(), smi, qi, count);
544}
545
546
547void
548CPA::swWf(ThreadContext *tc)
549{
550 if (!enabled())
551 return;
552
553 char q[50];
554 Arguments args(tc);
555 uint64_t id = args[0];
556 CopyStringOut(tc, q, args[1], 50);
557 System *sys = tc->getSystemPtr();
558 int32_t count = args[3];
559
560 int sysi = getSys(sys);
561 StackId sid = StackId(sysi, getFrame(tc));
562 if (!smStack[sid].size())
563 return;
564 int smi = smStack[sid].back();
565 int qi = getQ(sysi, q, id);
566 add(OP_WAIT_FULL, FL_NONE, tc->contextId(), smi, qi, count);
567
568 if (!!args[2]) {
569 char sm[50];
570 CopyStringOut(tc, sm, args[2], 50);
571 doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
572 }
573}
574
575void
576CPA::swWe(ThreadContext *tc)
577{
578 if (!enabled())
579 return;
580
581 char q[50];
582 Arguments args(tc);
583 uint64_t id = args[0];
584 CopyStringOut(tc, q, args[1], 50);
585 System *sys = tc->getSystemPtr();
586 int32_t count = args[3];
587
588 int sysi = getSys(sys);
589 StackId sid = StackId(sysi, getFrame(tc));
590 if (!smStack[sid].size())
591 return;
592 int smi = smStack[sid].back();
593 int qi = getQ(sysi, q, id);
594 add(OP_WAIT_EMPTY, FL_NONE, tc->contextId(), smi, qi, count);
595
596 if (!!args[2]) {
597 char sm[50];
598 CopyStringOut(tc, sm, args[2], 50);
599 doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
600 }
601}
602
603void
604CPA::swSq(ThreadContext *tc)
605{
606 if (!enabled())
607 return;
608
609 char q[50];
610 Arguments args(tc);
611 uint64_t id = args[0];
612 CopyStringOut(tc, q, args[1], 50);
613 System *sys = tc->getSystemPtr();
614 StringWrap name(sys->name());
615 int32_t size = args[2];
616 int flags = args[3];
617
618 int sysi = getSys(sys);
619 StackId sid = StackId(sysi, getFrame(tc));
620 if (!smStack[sid].size())
621 return;
622 int smi = smStack[sid].back();
623 int qi = getQ(sysi, q, id);
624 DPRINTF(AnnotateQ, "swSq: %s [%#x] cur size: %d bytes: %d, new size: %d\n",
625 q, id, qSize[qi-1], qBytes[qi-1], size);
626
627 if (FL_RESET & flags) {
628 DPRINTF(AnnotateQ, "Resetting Queue %s\n", q);
629 add(OP_SIZE_QUEUE, FL_NONE, tc->contextId(), smi, qi, 0);
630 qData[qi-1].clear();
631 qSize[qi-1] = 0;
632 qBytes[qi-1] = 0;
633 }
634
635 if (qBytes[qi-1] < size)
636 doQ(sys, FL_NONE, tc->contextId(), smi, q, qi, size - qBytes[qi-1]);
637 else if (qBytes[qi-1] > size) {
638 DPRINTF(AnnotateQ, "removing for resize of queue %s\n", q);
639 add(OP_SIZE_QUEUE, FL_NONE, tc->contextId(), smi, qi, size);
640 if (size <= 0) {
641 qData[qi-1].clear();
642 qSize[qi-1] = 0;
643 qBytes[qi-1] = 0;
644 return;
645 }
646 int need = qBytes[qi-1] - size;
647 qBytes[qi-1] = size;
648 while (need > 0) {
649 int32_t tail_bytes = qData[qi-1].back()->data;
650 if (qSize[qi-1] <= 0 || qBytes[qi-1] < 0) {
651 dump(true);
652 dumpKey();
653 fatal("Queue %s had inconsistancy when doing size queue!\n", q);
654 }
655 if (tail_bytes > need) {
656 qData[qi-1].back()->data -= need;
657 need = 0;
658 } else if (tail_bytes == need) {
659 qData[qi-1].pop_back();
660 qSize[qi-1]--;
661 need = 0;
662 } else {
663 qData[qi-1].pop_back();
664 qSize[qi-1]--;
665 need -= tail_bytes;
666 }
667 }
668 }
669}
670
671void
672CPA::swAq(ThreadContext *tc)
673{
674 if (!enabled())
675 return;
676
677 char q[50];
678 Arguments args(tc);
679 uint64_t id = args[0];
680 CopyStringOut(tc, q, args[1], 50);
681 System *sys = tc->getSystemPtr();
682 StringWrap name(sys->name());
683 int32_t size = args[2];
684
685 int sysi = getSys(sys);
686 int qi = getQ(sysi, q, id);
687 if (qBytes[qi-1] != size) {
688 DPRINTF(AnnotateQ, "Queue %s [%#x] has inconsintant size\n", q, id);
689 //dump(true);
690 //dumpKey();
691 std::list<AnnDataPtr>::iterator ai = qData[qi-1].begin();
692 int x = 0;
693 while (ai != qData[qi-1].end()) {
694 DPRINTF(AnnotateQ, "--Element %d size %d\n", x, (*ai)->data);
695 ai++;
696 x++;
697 }
698
699 warn("%d: Queue Assert: SW said there should be %d byte(s) in %s,"
700 "however there are %d byte(s)\n",
701 curTick(), size, q, qBytes[qi-1]);
702 DPRINTF(AnnotateQ, "%d: Queue Assert: SW said there should be %d"
703 " byte(s) in %s, however there are %d byte(s)\n",
704 curTick(), size, q, qBytes[qi-1]);
705 }
706}
707
708void
709CPA::swLink(ThreadContext *tc)
710{
711 if (!enabled())
712 return;
713
714 char lsm[50];
715 Arguments args(tc);
716 CopyStringOut(tc, lsm, args[0], 50);
717 System *sys = tc->getSystemPtr();
718 StringWrap name(sys->name());
719
720 int sysi = getSys(sys);
721 StackId sid = StackId(sysi, getFrame(tc));
722 if (!smStack[sid].size())
723 return;
724 int smi = smStack[sid].back();
725 int lsmi = getSm(sysi, lsm, args[1]);
726
727 DPRINTF(Annotate, "Linking from %d to state machine %s(%d) [%#x]\n",
728 smi, lsm, lsmi, args[1]);
729
730 if (lnMap[lsmi])
731 DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n",
732 lsmi, lnMap[lsmi]);
733 assert(lnMap[lsmi] == 0);
734 lnMap[lsmi] = smi;
735
736 add(OP_LINK, FL_NONE, tc->contextId(), smi, lsmi);
737
738 if (!!args[2]) {
739 char sm[50];
740 CopyStringOut(tc, sm, args[2], 50);
741 doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
742 }
743}
744
745void
746CPA::swIdentify(ThreadContext *tc)
747{
748 if (!enabled())
749 return;
750
751 Arguments args(tc);
752 int sysi = getSys(tc->getSystemPtr());
753 StackId sid = StackId(sysi, getFrame(tc));
754 if (!smStack[sid].size())
755 return;
756 int smi = smStack[sid].back();
757
758 DPRINTFS(Annotate, tc->getSystemPtr(), "swIdentify: id %#X\n", args[0]);
759
760 add(OP_IDENT, FL_NONE, tc->contextId(), smi, 0, args[0]);
761}
762
763uint64_t
764CPA::swGetId(ThreadContext *tc)
765{
766 if (!enabled())
767 return 0;
768
769 uint64_t id = ++conId;
770 int sysi = getSys(tc->getSystemPtr());
771 StackId sid = StackId(sysi, getFrame(tc));
772 if (!smStack[sid].size())
773 panic("swGetId called without a state machine stack!");
774 int smi = smStack[sid].back();
775
776 DPRINTFS(Annotate, tc->getSystemPtr(), "swGetId: id %#X\n", id);
777
778 add(OP_IDENT, FL_NONE, tc->contextId(), smi, 0, id);
779 return id;
780}
781
782
783void
784CPA::swSyscallLink(ThreadContext *tc)
785{
786 if (!enabled())
787 return;
788
789 char lsm[50];
790 Arguments args(tc);
791 CopyStringOut(tc, lsm, args[0], 50);
792 System *sys = tc->getSystemPtr();
793 StringWrap name(sys->name());
794 int sysi = getSys(sys);
795
796 Id id = Id(lsm, getFrame(tc));
797 StackId sid = StackId(sysi, getFrame(tc));
798
799 if (!smStack[sid].size())
800 return;
801
802 int smi = smStack[sid].back();
803
804 DPRINTF(Annotate, "Linking from %d to state machine %s(UNKNOWN)\n",
805 smi, lsm);
806
807 if (scLinks[sysi-1][id])
808 DPRINTF(Annotate,
809 "scLinks already contains entry for system %d %s[%x] of %d\n",
810 sysi, lsm, getFrame(tc), scLinks[sysi-1][id]);
811 assert(scLinks[sysi-1][id] == 0);
812 scLinks[sysi-1][id] = add(OP_LINK, FL_NONE, tc->contextId(), smi, 0xFFFF);
813 scLinks[sysi-1][id]->dump = false;
814
815 if (!!args[1]) {
816 char sm[50];
817 CopyStringOut(tc, sm, args[1], 50);
818 doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
819 }
820}
821
822CPA::AnnDataPtr
823CPA::add(int t, int f, int c, int sm, int stq, int32_t d)
824{
825 AnnDataPtr an = std::make_shared<AnnotateData>();
826 an->time = curTick();
827 an->data = d;
828 an->orig_data = d;
829 an->op = t;
830 an->flag = f;
831 an->sm = sm;
832 an->stq = stq;
833 an->cpu = c;
834 an->dump = true;
835
836 data.push_back(an);
837
838 DPRINTF(AnnotateVerbose, "Annotate: op: %d flags: 0x%x sm: %d state: %d time: %d, data: %d\n",
839 an->op, an->flag, an->sm, an->stq, an->time, an->data);
840
841 // Don't dump Links because we might be setting no-dump on it
842 if (an->op != OP_LINK)
843 dump(false);
844
845 return an;
846}
847
848void
849CPA::dumpKey()
850{
851 std::streampos curpos = osbin->tellp();
852 ah.key_off = curpos;
853
854 // Output the various state machines and their corresponding states
855 *osbin << "# Automatically generated state machine descriptor file" << endl;
856
857 *osbin << "sms = {}" << endl << endl;
858 vector<string> state_machines;
859 state_machines.resize(numSmt+1);
860
861 // State machines, id -> states
862 SCache::iterator i = smtCache.begin();
863 while (i != smtCache.end()) {
864 state_machines[i->second] = i->first;
865 i++;
866 }
867
868 for (int x = 1; x < state_machines.size(); x++) {
869 vector<string> states;
870 states.resize(numSt[x-1]+1);
871 assert(x-1 < stCache.size());
872 SCache::iterator i = stCache[x-1].begin();
873 while (i != stCache[x-1].end()) {
874 states[i->second] = i->first;
875 i++;
876 }
877 *osbin << "sms[\"" << state_machines[x] << "\"] = [\"NULL\"";
878 for (int y = 1; y < states.size(); y++)
879 *osbin << ", \"" << states[y] << "\"";
880 *osbin << "]" << endl;
881 }
882
883 *osbin << endl << endl << endl;
884
885 // state machine number -> system, name, id
886 *osbin << "smNum = [\"NULL\"";
887 for (int x = 0; x < smMap.size(); x++)
888 *osbin << ", (" << smMap[x].first << ", \"" << smMap[x].second.first <<
889 "\", " << smMap[x].second.second << ")";
890 *osbin << "]" << endl;
891
892 *osbin << endl << endl << endl;
893
894 // Output the systems
895 vector<string> systems;
896 systems.resize(numSys+1);
897 NameCache::iterator i2 = nameCache.begin();
898 while (i2 != nameCache.end()) {
899 systems[i2->second.second] = i2->second.first;
900 i2++;
901 }
902
903 *osbin << "sysNum = [\"NULL\"";
904 for (int x = 1; x < systems.size(); x++) {
905 *osbin << ", \"" << systems[x] << "\"";
906 }
907 *osbin << "]" << endl;
908
909 // queue number -> system, qname, qid
910 *osbin << "queues = [\"NULL\"";
911 for (int x = 0; x < qMap.size(); x++)
912 *osbin << ", (" << qMap[x].first << ", \"" << qMap[x].second.first <<
913 "\", " << qMap[x].second.second << ")";
914 *osbin << "]" << endl;
915
916 *osbin << "smComb = [s for s in [(i,r) for i in xrange(1,len(sysNum)) "
917 << "for r in xrange (1,len(smNum))]]" << endl;
918 ah.key_len = osbin->tellp() - curpos;
919
920 // output index
921 curpos = osbin->tellp();
922 ah.idx_off = curpos;
923
924 for (int x = 0; x < annotateIdx.size(); x++)
925 osbin->write((char*)&annotateIdx[x], sizeof(uint64_t));
926 ah.idx_len = osbin->tellp() - curpos;
927
928 osbin->seekp(0);
929 osbin->write((char*)&ah, sizeof(AnnotateHeader));
930 osbin->flush();
931
932}
933
934void
935CPA::dump(bool all)
936{
937
938 list<AnnDataPtr>::iterator i;
939
940 i = data.begin();
941
942 if (i == data.end())
943 return;
944
945 // Dump the data every
946 if (!all && data.size() < 10000)
947 return;
948
949 DPRINTF(Annotate, "Writing %d\n", data.size());
950 while (i != data.end()) {
951 AnnDataPtr an = *i;
952
953 // If we can't dump this record, hold here
954 if (!an->dump && !all)
955 break;
956
957 ah.num_recs++;
958 if (ah.num_recs % 100000 == 0)
959 annotateIdx.push_back(osbin->tellp());
960
961
962 osbin->write((char*)&(an->time), sizeof(an->time));
963 osbin->write((char*)&(an->orig_data), sizeof(an->orig_data));
964 osbin->write((char*)&(an->sm), sizeof(an->sm));
965 osbin->write((char*)&(an->stq), sizeof(an->stq));
966 osbin->write((char*)&(an->op), sizeof(an->op));
967 osbin->write((char*)&(an->flag), sizeof(an->flag));
968 osbin->write((char*)&(an->cpu), sizeof(an->cpu));
969 i++;
970 }
971 if (data.begin() != i)
972 data.erase(data.begin(), i);
973
974 if (all)
975 osbin->flush();
976}
977
978void
979CPA::doQ(System *sys, int flags, int cpuid, int sm,
980 string q, int qi, int count)
981{
982 qSize[qi-1]++;
983 qBytes[qi-1] += count;
984 if (qSize[qi-1] > 2501 || qBytes[qi-1] > 2000000000)
985 warn("Queue %s is %d elements/%d bytes, "
986 "maybe things aren't being removed?\n",
987 q, qSize[qi-1], qBytes[qi-1]);
988 if (flags & FL_QOPP)
989 qData[qi-1].push_front(add(OP_QUEUE, flags, cpuid, sm, qi, count));
990 else
991 qData[qi-1].push_back(add(OP_QUEUE, flags, cpuid, sm, qi, count));
992 DPRINTFS(AnnotateQ, sys, "Queing in queue %s size now %d/%d\n",
993 q, qSize[qi-1], qBytes[qi-1]);
994 assert(qSize[qi-1] >= 0);
995 assert(qBytes[qi-1] >= 0);
996}
997
998
999void
1000CPA::doDq(System *sys, int flags, int cpuid, int sm,
1001 string q, int qi, int count)
1002{
1003
1004 StringWrap name(sys->name());
1005 if (count == -1) {
1006 add(OP_DEQUEUE, flags, cpuid, sm, qi, count);
1007 qData[qi-1].clear();
1008 qSize[qi-1] = 0;
1009 qBytes[qi-1] = 0;
1010 DPRINTF(AnnotateQ, "Dequeing all data in queue %s size now %d/%d\n",
1011 q, qSize[qi-1], qBytes[qi-1]);
1012 return;
1013 }
1014
1015 assert(count > 0);
1016 if (qSize[qi-1] <= 0 || qBytes[qi-1] <= 0 || !qData[qi-1].size()) {
1017 dump(true);
1018 dumpKey();
1019 fatal("Queue %s dequing with no data available in queue!\n",
1020 q);
1021 }
1022 assert(qSize[qi-1] >= 0);
1023 assert(qBytes[qi-1] >= 0);
1024 assert(qData[qi-1].size());
1025
1026 int32_t need = count;
1027 qBytes[qi-1] -= count;
1028 if (qBytes[qi-1] < 0) {
1029 dump(true);
1030 dumpKey();
1031 fatal("Queue %s dequing with no bytes available in queue!\n",
1032 q);
1033 }
1034
1035 while (need > 0) {
1036 int32_t head_bytes = qData[qi-1].front()->data;
1037 if (qSize[qi-1] <= 0 || qBytes[qi-1] < 0) {
1038 dump(true);
1039 dumpKey();
1040 fatal("Queue %s dequing with nothing in queue!\n",
1041 q);
1042 }
1043
1044 if (head_bytes > need) {
1045 qData[qi-1].front()->data -= need;
1046 need = 0;
1047 } else if (head_bytes == need) {
1048 qData[qi-1].pop_front();
1049 qSize[qi-1]--;
1050 need = 0;
1051 } else {
1052 qData[qi-1].pop_front();
1053 qSize[qi-1]--;
1054 need -= head_bytes;
1055 }
1056 }
1057
1058 add(OP_DEQUEUE, flags, cpuid, sm, qi, count);
1059 DPRINTF(AnnotateQ, "Dequeing in queue %s size now %d/%d\n",
1060 q, qSize[qi-1], qBytes[qi-1]);
1061}
1062
1063
1064
1065void
1066CPA::serialize(std::ostream &os)
1066CPA::serialize(CheckpointOut &cp) const
1067{
1068
1069 SERIALIZE_SCALAR(numSm);
1070 SERIALIZE_SCALAR(numSmt);
1071 arrayParamOut(os, "numSt", numSt);
1072 arrayParamOut(os, "numQ", numQ);
1073 SERIALIZE_SCALAR(numSys);
1074 SERIALIZE_SCALAR(numQs);
1075 SERIALIZE_SCALAR(conId);
1076 arrayParamOut(os, "qSize", qSize);
1077 arrayParamOut(os, "qSize", qSize);
1078 arrayParamOut(os, "qBytes", qBytes);
1079
1067{
1068
1069 SERIALIZE_SCALAR(numSm);
1070 SERIALIZE_SCALAR(numSmt);
1071 arrayParamOut(os, "numSt", numSt);
1072 arrayParamOut(os, "numQ", numQ);
1073 SERIALIZE_SCALAR(numSys);
1074 SERIALIZE_SCALAR(numQs);
1075 SERIALIZE_SCALAR(conId);
1076 arrayParamOut(os, "qSize", qSize);
1077 arrayParamOut(os, "qSize", qSize);
1078 arrayParamOut(os, "qBytes", qBytes);
1079
1080 std::list<AnnDataPtr>::iterator ai;
1081
1082 SCache::iterator i;
1083 int x = 0, y = 0;
1084
1085 // smtCache (SCache)
1086 x = 0;
1087 y = 0;
1088 i = smtCache.begin();
1089 while (i != smtCache.end()) {
1090 paramOut(os, csprintf("smtCache%d.str", x), i->first);
1091 paramOut(os, csprintf("smtCache%d.int", x), i->second);
1092 x++; i++;
1093 }
1094
1095 // stCache (StCache)
1096 for (x = 0; x < stCache.size(); x++) {
1097 i = stCache[x].begin();
1098 y = 0;
1099 while (i != stCache[x].end()) {
1100 paramOut(os, csprintf("stCache%d_%d.str", x, y), i->first);
1101 paramOut(os, csprintf("stCache%d_%d.int", x, y), i->second);
1102 y++; i++;
1103 }
1104 }
1105
1106 // qCache (IdCache)
1107 IdHCache::iterator idi;
1108 for (x = 0; x < qCache.size(); x++) {
1109 idi = qCache[x].begin();
1110 y = 0;
1111 while (idi != qCache[x].end()) {
1112 paramOut(os, csprintf("qCache%d_%d.str", x, y), idi->first.first);
1113 paramOut(os, csprintf("qCache%d_%d.id", x, y), idi->first.second);
1114 paramOut(os, csprintf("qCache%d_%d.int", x, y), idi->second);
1115 y++; idi++;
1116 }
1117 }
1118
1119 // smCache (IdCache)
1120 for (x = 0; x < smCache.size(); x++) {
1121 idi = smCache[x].begin();
1122 y = 0;
1123 paramOut(os, csprintf("smCache%d", x), smCache[x].size());
1124 while (idi != smCache[x].end()) {
1125 paramOut(os, csprintf("smCache%d_%d.str", x, y), idi->first.first);
1126 paramOut(os, csprintf("smCache%d_%d.id", x, y), idi->first.second);
1127 paramOut(os, csprintf("smCache%d_%d.int", x, y), idi->second);
1128 y++; idi++;
1129 }
1130 }
1131
1132 // scLinks (ScCache) -- data not serialize
1133
1134
1135 // namecache (NameCache)
1136 NameCache::iterator ni;
1137
1138 ni = nameCache.begin();
1139 x = 0;
1140 while (ni != nameCache.end()) {
1141 paramOut(os, csprintf("nameCache%d.name", x), ni->first->name());
1142 paramOut(os, csprintf("nameCache%d.str", x), ni->second.first);
1143 paramOut(os, csprintf("nameCache%d.int", x), ni->second.second);
1144 x++; ni++;
1145 }
1146
1147 // smStack (SmStack)
1148 SmStack::iterator si;
1149 si = smStack.begin();
1150 x = 0;
1151 paramOut(os, "smStackIdCount", smStack.size());
1152 while (si != smStack.end()) {
1153 paramOut(os, csprintf("smStackId%d.sys", x), si->first.first);
1154 paramOut(os, csprintf("smStackId%d.frame", x), si->first.second);
1155 paramOut(os, csprintf("smStackId%d.count", x), si->second.size());
1156 for (y = 0; y < si->second.size(); y++)
1157 paramOut(os, csprintf("smStackId%d_%d", x, y), si->second[y]);
1158 x++; si++;
1159 }
1160
1161 // lnMap (LinkMap)
1162 x = 0;
1163 LinkMap::iterator li;
1164 li = lnMap.begin();
1165 paramOut(os, "lnMapSize", lnMap.size());
1166 while (li != lnMap.end()) {
1167 paramOut(os, csprintf("lnMap%d.smi", x), li->first);
1168 paramOut(os, csprintf("lnMap%d.lsmi", x), li->second);
1169 x++; li++;
1170 }
1171
1172 // swExpl (vector)
1173 SwExpl::iterator swexpli;
1174 swexpli = swExpl.begin();
1175 x = 0;
1176 paramOut(os, "swExplCount", swExpl.size());
1177 while (swexpli != swExpl.end()) {
1178 paramOut(os, csprintf("swExpl%d.sys", x), swexpli->first.first);
1179 paramOut(os, csprintf("swExpl%d.frame", x), swexpli->first.second);
1180 paramOut(os, csprintf("swExpl%d.swexpl", x), swexpli->second);
1181 x++; swexpli++;
1182 }
1183
1184 // lastState (IMap)
1185 x = 0;
1186 IMap::iterator ii;
1187 ii = lastState.begin();
1188 paramOut(os, "lastStateSize", lastState.size());
1189 while (ii != lastState.end()) {
1190 paramOut(os, csprintf("lastState%d.smi", x), ii->first);
1191 paramOut(os, csprintf("lastState%d.sti", x), ii->second);
1192 x++; ii++;
1193 }
1194
1195 // smMap (IdMap)
1196 for (x = 0; x < smMap.size(); x++) {
1197 paramOut(os, csprintf("smMap%d.sys", x), smMap[x].first);
1198 paramOut(os, csprintf("smMap%d.smname", x), smMap[x].second.first);
1199 paramOut(os, csprintf("smMap%d.id", x), smMap[x].second.second);
1200 }
1201
1202 // qMap (IdMap)
1203 for (x = 0; x < qMap.size(); x++) {
1204 paramOut(os, csprintf("qMap%d.sys", x), qMap[x].first);
1205 paramOut(os, csprintf("qMap%d.qname", x), qMap[x].second.first);
1206 paramOut(os, csprintf("qMap%d.id", x), qMap[x].second.second);
1207 }
1208
1209 // qData (vector<AnnotateList>)
1210 for(x = 0; x < qData.size(); x++) {
1211 if (!qData[x].size())
1212 continue;
1213 y = 0;
1080 SCache::iterator i;
1081 int x = 0, y = 0;
1082
1083 // smtCache (SCache)
1084 x = 0;
1085 y = 0;
1086 i = smtCache.begin();
1087 while (i != smtCache.end()) {
1088 paramOut(os, csprintf("smtCache%d.str", x), i->first);
1089 paramOut(os, csprintf("smtCache%d.int", x), i->second);
1090 x++; i++;
1091 }
1092
1093 // stCache (StCache)
1094 for (x = 0; x < stCache.size(); x++) {
1095 i = stCache[x].begin();
1096 y = 0;
1097 while (i != stCache[x].end()) {
1098 paramOut(os, csprintf("stCache%d_%d.str", x, y), i->first);
1099 paramOut(os, csprintf("stCache%d_%d.int", x, y), i->second);
1100 y++; i++;
1101 }
1102 }
1103
1104 // qCache (IdCache)
1105 IdHCache::iterator idi;
1106 for (x = 0; x < qCache.size(); x++) {
1107 idi = qCache[x].begin();
1108 y = 0;
1109 while (idi != qCache[x].end()) {
1110 paramOut(os, csprintf("qCache%d_%d.str", x, y), idi->first.first);
1111 paramOut(os, csprintf("qCache%d_%d.id", x, y), idi->first.second);
1112 paramOut(os, csprintf("qCache%d_%d.int", x, y), idi->second);
1113 y++; idi++;
1114 }
1115 }
1116
1117 // smCache (IdCache)
1118 for (x = 0; x < smCache.size(); x++) {
1119 idi = smCache[x].begin();
1120 y = 0;
1121 paramOut(os, csprintf("smCache%d", x), smCache[x].size());
1122 while (idi != smCache[x].end()) {
1123 paramOut(os, csprintf("smCache%d_%d.str", x, y), idi->first.first);
1124 paramOut(os, csprintf("smCache%d_%d.id", x, y), idi->first.second);
1125 paramOut(os, csprintf("smCache%d_%d.int", x, y), idi->second);
1126 y++; idi++;
1127 }
1128 }
1129
1130 // scLinks (ScCache) -- data not serialize
1131
1132
1133 // namecache (NameCache)
1134 NameCache::iterator ni;
1135
1136 ni = nameCache.begin();
1137 x = 0;
1138 while (ni != nameCache.end()) {
1139 paramOut(os, csprintf("nameCache%d.name", x), ni->first->name());
1140 paramOut(os, csprintf("nameCache%d.str", x), ni->second.first);
1141 paramOut(os, csprintf("nameCache%d.int", x), ni->second.second);
1142 x++; ni++;
1143 }
1144
1145 // smStack (SmStack)
1146 SmStack::iterator si;
1147 si = smStack.begin();
1148 x = 0;
1149 paramOut(os, "smStackIdCount", smStack.size());
1150 while (si != smStack.end()) {
1151 paramOut(os, csprintf("smStackId%d.sys", x), si->first.first);
1152 paramOut(os, csprintf("smStackId%d.frame", x), si->first.second);
1153 paramOut(os, csprintf("smStackId%d.count", x), si->second.size());
1154 for (y = 0; y < si->second.size(); y++)
1155 paramOut(os, csprintf("smStackId%d_%d", x, y), si->second[y]);
1156 x++; si++;
1157 }
1158
1159 // lnMap (LinkMap)
1160 x = 0;
1161 LinkMap::iterator li;
1162 li = lnMap.begin();
1163 paramOut(os, "lnMapSize", lnMap.size());
1164 while (li != lnMap.end()) {
1165 paramOut(os, csprintf("lnMap%d.smi", x), li->first);
1166 paramOut(os, csprintf("lnMap%d.lsmi", x), li->second);
1167 x++; li++;
1168 }
1169
1170 // swExpl (vector)
1171 SwExpl::iterator swexpli;
1172 swexpli = swExpl.begin();
1173 x = 0;
1174 paramOut(os, "swExplCount", swExpl.size());
1175 while (swexpli != swExpl.end()) {
1176 paramOut(os, csprintf("swExpl%d.sys", x), swexpli->first.first);
1177 paramOut(os, csprintf("swExpl%d.frame", x), swexpli->first.second);
1178 paramOut(os, csprintf("swExpl%d.swexpl", x), swexpli->second);
1179 x++; swexpli++;
1180 }
1181
1182 // lastState (IMap)
1183 x = 0;
1184 IMap::iterator ii;
1185 ii = lastState.begin();
1186 paramOut(os, "lastStateSize", lastState.size());
1187 while (ii != lastState.end()) {
1188 paramOut(os, csprintf("lastState%d.smi", x), ii->first);
1189 paramOut(os, csprintf("lastState%d.sti", x), ii->second);
1190 x++; ii++;
1191 }
1192
1193 // smMap (IdMap)
1194 for (x = 0; x < smMap.size(); x++) {
1195 paramOut(os, csprintf("smMap%d.sys", x), smMap[x].first);
1196 paramOut(os, csprintf("smMap%d.smname", x), smMap[x].second.first);
1197 paramOut(os, csprintf("smMap%d.id", x), smMap[x].second.second);
1198 }
1199
1200 // qMap (IdMap)
1201 for (x = 0; x < qMap.size(); x++) {
1202 paramOut(os, csprintf("qMap%d.sys", x), qMap[x].first);
1203 paramOut(os, csprintf("qMap%d.qname", x), qMap[x].second.first);
1204 paramOut(os, csprintf("qMap%d.id", x), qMap[x].second.second);
1205 }
1206
1207 // qData (vector<AnnotateList>)
1208 for(x = 0; x < qData.size(); x++) {
1209 if (!qData[x].size())
1210 continue;
1211 y = 0;
1214 ai = qData[x].begin();
1215 while (ai != qData[x].end()) {
1216 nameOut(os, csprintf("%s.Q%d_%d", name(), x, y));
1217 (*ai)->serialize(os);
1218 ai++;
1212 for (auto &ann : qData[x]) {
1213 ann->serializeSection(os, csprintf("Q%d_%d", x, y));
1219 y++;
1220 }
1221 }
1222}
1223
1224void
1214 y++;
1215 }
1216 }
1217}
1218
1219void
1225CPA::unserialize(Checkpoint *cp, const std::string &section)
1220CPA::unserialize(CheckpointIn &cp)
1226{
1227 UNSERIALIZE_SCALAR(numSm);
1228 UNSERIALIZE_SCALAR(numSmt);
1221{
1222 UNSERIALIZE_SCALAR(numSm);
1223 UNSERIALIZE_SCALAR(numSmt);
1229 arrayParamIn(cp, section, "numSt", numSt);
1230 arrayParamIn(cp, section, "numQ", numQ);
1224 UNSERIALIZE_CONTAINER(numSt);
1225 UNSERIALIZE_CONTAINER(numQ);
1231 UNSERIALIZE_SCALAR(numSys);
1232 UNSERIALIZE_SCALAR(numQs);
1233 UNSERIALIZE_SCALAR(conId);
1226 UNSERIALIZE_SCALAR(numSys);
1227 UNSERIALIZE_SCALAR(numQs);
1228 UNSERIALIZE_SCALAR(conId);
1234 arrayParamIn(cp, section, "qSize", qSize);
1235 arrayParamIn(cp, section, "qBytes", qBytes);
1229 UNSERIALIZE_CONTAINER(qSize);
1230 UNSERIALIZE_CONTAINER(qBytes);
1236
1237
1238 // smtCache (SCache
1239 string str;
1240 int smi;
1241 for (int x = 0; x < numSmt; x++) {
1231
1232
1233 // smtCache (SCache
1234 string str;
1235 int smi;
1236 for (int x = 0; x < numSmt; x++) {
1242 paramIn(cp, section, csprintf("smtCache%d.str", x), str);
1243 paramIn(cp, section, csprintf("smtCache%d.int", x), smi);
1237 paramIn(cp, csprintf("smtCache%d.str", x), str);
1238 paramIn(cp, csprintf("smtCache%d.int", x), smi);
1244 smtCache[str] = smi;
1245 }
1246
1247 // stCache (StCache)
1248 stCache.resize(numSmt);
1249 for (int x = 0; x < numSmt; x++) {
1250 for (int y = 0; y < numSt[x]; y++) {
1239 smtCache[str] = smi;
1240 }
1241
1242 // stCache (StCache)
1243 stCache.resize(numSmt);
1244 for (int x = 0; x < numSmt; x++) {
1245 for (int y = 0; y < numSt[x]; y++) {
1251 paramIn(cp, section, csprintf("stCache%d_%d.str", x,y), str);
1252 paramIn(cp, section, csprintf("stCache%d_%d.int", x,y), smi);
1246 paramIn(cp, csprintf("stCache%d_%d.str", x,y), str);
1247 paramIn(cp, csprintf("stCache%d_%d.int", x,y), smi);
1253 stCache[x][str] = smi;
1254 }
1255 }
1256
1257 // qCache (IdCache)
1258 uint64_t id;
1259 qCache.resize(numSys);
1260 for (int x = 0; x < numSys; x++) {
1261 for (int y = 0; y < numQ[x]; y++) {
1248 stCache[x][str] = smi;
1249 }
1250 }
1251
1252 // qCache (IdCache)
1253 uint64_t id;
1254 qCache.resize(numSys);
1255 for (int x = 0; x < numSys; x++) {
1256 for (int y = 0; y < numQ[x]; y++) {
1262 paramIn(cp, section, csprintf("qCache%d_%d.str", x,y), str);
1263 paramIn(cp, section, csprintf("qCache%d_%d.id", x,y), id);
1264 paramIn(cp, section, csprintf("qCache%d_%d.int", x,y), smi);
1257 paramIn(cp, csprintf("qCache%d_%d.str", x,y), str);
1258 paramIn(cp, csprintf("qCache%d_%d.id", x,y), id);
1259 paramIn(cp, csprintf("qCache%d_%d.int", x,y), smi);
1265 qCache[x][Id(str,id)] = smi;
1266 }
1267 }
1268
1269 // smCache (IdCache)
1270 smCache.resize(numSys);
1271 for (int x = 0; x < numSys; x++) {
1272 int size;
1260 qCache[x][Id(str,id)] = smi;
1261 }
1262 }
1263
1264 // smCache (IdCache)
1265 smCache.resize(numSys);
1266 for (int x = 0; x < numSys; x++) {
1267 int size;
1273 paramIn(cp, section, csprintf("smCache%d", x), size);
1268 paramIn(cp, csprintf("smCache%d", x), size);
1274 for (int y = 0; y < size; y++) {
1269 for (int y = 0; y < size; y++) {
1275 paramIn(cp, section, csprintf("smCache%d_%d.str", x,y), str);
1276 paramIn(cp, section, csprintf("smCache%d_%d.id", x,y), id);
1277 paramIn(cp, section, csprintf("smCache%d_%d.int", x,y), smi);
1270 paramIn(cp, csprintf("smCache%d_%d.str", x,y), str);
1271 paramIn(cp, csprintf("smCache%d_%d.id", x,y), id);
1272 paramIn(cp, csprintf("smCache%d_%d.int", x,y), smi);
1278 smCache[x][Id(str,id)] = smi;
1279 }
1280 }
1281
1282 // scLinks (ScCache) -- data not serialized, just creating one per sys
1283 for (int x = 0; x < numSys; x++)
1284 scLinks.push_back(ScHCache());
1285
1286 // nameCache (NameCache)
1287 for (int x = 0; x < numSys; x++) {
1288 System *sys;
1289 SimObject *sptr;
1290 string str;
1291 int sysi;
1292
1273 smCache[x][Id(str,id)] = smi;
1274 }
1275 }
1276
1277 // scLinks (ScCache) -- data not serialized, just creating one per sys
1278 for (int x = 0; x < numSys; x++)
1279 scLinks.push_back(ScHCache());
1280
1281 // nameCache (NameCache)
1282 for (int x = 0; x < numSys; x++) {
1283 System *sys;
1284 SimObject *sptr;
1285 string str;
1286 int sysi;
1287
1293 objParamIn(cp, section, csprintf("nameCache%d.name", x), sptr);
1288 objParamIn(cp, csprintf("nameCache%d.name", x), sptr);
1294 sys = dynamic_cast<System*>(sptr);
1295
1289 sys = dynamic_cast<System*>(sptr);
1290
1296 paramIn(cp, section, csprintf("nameCache%d.str", x), str);
1297 paramIn(cp, section, csprintf("nameCache%d.int", x), sysi);
1291 paramIn(cp, csprintf("nameCache%d.str", x), str);
1292 paramIn(cp, csprintf("nameCache%d.int", x), sysi);
1298 nameCache[sys] = std::make_pair(str, sysi);
1299 }
1300
1301 //smStack (SmStack)
1302 int smStack_size;
1293 nameCache[sys] = std::make_pair(str, sysi);
1294 }
1295
1296 //smStack (SmStack)
1297 int smStack_size;
1303 paramIn(cp, section, "smStackIdCount", smStack_size);
1298 paramIn(cp, "smStackIdCount", smStack_size);
1304 for (int x = 0; x < smStack_size; x++) {
1305 int sysi;
1306 uint64_t frame;
1307 int count;
1299 for (int x = 0; x < smStack_size; x++) {
1300 int sysi;
1301 uint64_t frame;
1302 int count;
1308 paramIn(cp, section, csprintf("smStackId%d.sys", x), sysi);
1309 paramIn(cp, section, csprintf("smStackId%d.frame", x), frame);
1310 paramIn(cp, section, csprintf("smStackId%d.count", x), count);
1303 paramIn(cp, csprintf("smStackId%d.sys", x), sysi);
1304 paramIn(cp, csprintf("smStackId%d.frame", x), frame);
1305 paramIn(cp, csprintf("smStackId%d.count", x), count);
1311 StackId sid = StackId(sysi, frame);
1312 for (int y = 0; y < count; y++) {
1306 StackId sid = StackId(sysi, frame);
1307 for (int y = 0; y < count; y++) {
1313 paramIn(cp, section, csprintf("smStackId%d_%d", x, y), smi);
1308 paramIn(cp, csprintf("smStackId%d_%d", x, y), smi);
1314 smStack[sid].push_back(smi);
1315 }
1316 }
1317
1318 // lnMap (LinkMap)
1319 int lsmi;
1320 int lnMap_size;
1309 smStack[sid].push_back(smi);
1310 }
1311 }
1312
1313 // lnMap (LinkMap)
1314 int lsmi;
1315 int lnMap_size;
1321 paramIn(cp, section, "lnMapSize", lnMap_size);
1316 paramIn(cp, "lnMapSize", lnMap_size);
1322 for (int x = 0; x < lnMap_size; x++) {
1317 for (int x = 0; x < lnMap_size; x++) {
1323 paramIn(cp, section, csprintf("lnMap%d.smi", x), smi);
1324 paramIn(cp, section, csprintf("lnMap%d.lsmi", x), lsmi);
1318 paramIn(cp, csprintf("lnMap%d.smi", x), smi);
1319 paramIn(cp, csprintf("lnMap%d.lsmi", x), lsmi);
1325 lnMap[smi] = lsmi;
1326 }
1327
1328 // swExpl (vector)
1329 int swExpl_size;
1320 lnMap[smi] = lsmi;
1321 }
1322
1323 // swExpl (vector)
1324 int swExpl_size;
1330 paramIn(cp, section, "swExplCount", swExpl_size);
1325 paramIn(cp, "swExplCount", swExpl_size);
1331 for (int x = 0; x < swExpl_size; x++) {
1332 int sysi;
1333 uint64_t frame;
1334 bool b;
1326 for (int x = 0; x < swExpl_size; x++) {
1327 int sysi;
1328 uint64_t frame;
1329 bool b;
1335 paramIn(cp, section, csprintf("swExpl%d.sys", x), sysi);
1336 paramIn(cp, section, csprintf("swExpl%d.frame", x), frame);
1337 paramIn(cp, section, csprintf("swExpl%d.swexpl", x), b);
1330 paramIn(cp, csprintf("swExpl%d.sys", x), sysi);
1331 paramIn(cp, csprintf("swExpl%d.frame", x), frame);
1332 paramIn(cp, csprintf("swExpl%d.swexpl", x), b);
1338 StackId sid = StackId(sysi, frame);
1339 swExpl[sid] = b;
1340 }
1341
1342 // lastState (IMap)
1343 int sti;
1344 int lastState_size;
1333 StackId sid = StackId(sysi, frame);
1334 swExpl[sid] = b;
1335 }
1336
1337 // lastState (IMap)
1338 int sti;
1339 int lastState_size;
1345 paramIn(cp, section, "lastStateSize", lastState_size);
1340 paramIn(cp, "lastStateSize", lastState_size);
1346 for (int x = 0; x < lastState_size; x++) {
1341 for (int x = 0; x < lastState_size; x++) {
1347 paramIn(cp, section, csprintf("lastState%d.smi", x), smi);
1348 paramIn(cp, section, csprintf("lastState%d.sti", x), sti);
1342 paramIn(cp, csprintf("lastState%d.smi", x), smi);
1343 paramIn(cp, csprintf("lastState%d.sti", x), sti);
1349 lastState[smi] = sti;
1350 }
1351
1352
1353 //smMap (IdMap)
1354 smMap.resize(numSm);
1355 for (int x = 0; x < smMap.size(); x++) {
1344 lastState[smi] = sti;
1345 }
1346
1347
1348 //smMap (IdMap)
1349 smMap.resize(numSm);
1350 for (int x = 0; x < smMap.size(); x++) {
1356 paramIn(cp, section, csprintf("smMap%d.sys", x), smMap[x].first);
1357 paramIn(cp, section, csprintf("smMap%d.smname", x), smMap[x].second.first);
1358 paramIn(cp, section, csprintf("smMap%d.id", x), smMap[x].second.second);
1351 paramIn(cp, csprintf("smMap%d.sys", x), smMap[x].first);
1352 paramIn(cp, csprintf("smMap%d.smname", x), smMap[x].second.first);
1353 paramIn(cp, csprintf("smMap%d.id", x), smMap[x].second.second);
1359 }
1360
1361 //qMap (IdMap)
1362 qMap.resize(numQs);
1363 for (int x = 0; x < qMap.size(); x++) {
1354 }
1355
1356 //qMap (IdMap)
1357 qMap.resize(numQs);
1358 for (int x = 0; x < qMap.size(); x++) {
1364 paramIn(cp, section, csprintf("qMap%d.sys", x), qMap[x].first);
1365 paramIn(cp, section, csprintf("qMap%d.qname", x), qMap[x].second.first);
1366 paramIn(cp, section, csprintf("qMap%d.id", x), qMap[x].second.second);
1359 paramIn(cp, csprintf("qMap%d.sys", x), qMap[x].first);
1360 paramIn(cp, csprintf("qMap%d.qname", x), qMap[x].second.first);
1361 paramIn(cp, csprintf("qMap%d.id", x), qMap[x].second.second);
1367 }
1368
1369
1370 // qData (vector<AnnotateList>)
1371 qData.resize(qSize.size());
1372 for (int x = 0; x < qSize.size(); x++) {
1373 if (!qSize[x])
1374 continue;
1375 for (int y = 0; y < qSize[x]; y++) {
1376 AnnDataPtr a = std::make_shared<AnnotateData>();
1362 }
1363
1364
1365 // qData (vector<AnnotateList>)
1366 qData.resize(qSize.size());
1367 for (int x = 0; x < qSize.size(); x++) {
1368 if (!qSize[x])
1369 continue;
1370 for (int y = 0; y < qSize[x]; y++) {
1371 AnnDataPtr a = std::make_shared<AnnotateData>();
1377 a->unserialize(cp, csprintf("%s.Q%d_%d", section, x, y));
1372 a->unserializeSection(cp, csprintf("Q%d_%d", x, y));
1378 data.push_back(a);
1379 qData[x].push_back(a);
1380 }
1381 }
1382}
1383
1384void
1373 data.push_back(a);
1374 qData[x].push_back(a);
1375 }
1376 }
1377}
1378
1379void
1385CPA::AnnotateData::serialize(std::ostream &os)
1380CPA::AnnotateData::serialize(CheckpointOut &cp) const
1386{
1387 SERIALIZE_SCALAR(time);
1388 SERIALIZE_SCALAR(data);
1389 SERIALIZE_SCALAR(sm);
1390 SERIALIZE_SCALAR(stq);
1391 SERIALIZE_SCALAR(op);
1392 SERIALIZE_SCALAR(flag);
1393 SERIALIZE_SCALAR(cpu);
1394}
1395
1396void
1381{
1382 SERIALIZE_SCALAR(time);
1383 SERIALIZE_SCALAR(data);
1384 SERIALIZE_SCALAR(sm);
1385 SERIALIZE_SCALAR(stq);
1386 SERIALIZE_SCALAR(op);
1387 SERIALIZE_SCALAR(flag);
1388 SERIALIZE_SCALAR(cpu);
1389}
1390
1391void
1397CPA::AnnotateData::unserialize(Checkpoint *cp, const std::string &section)
1392CPA::AnnotateData::unserialize(CheckpointIn &cp)
1398{
1399 UNSERIALIZE_SCALAR(time);
1400 UNSERIALIZE_SCALAR(data);
1401 orig_data = data;
1402 UNSERIALIZE_SCALAR(sm);
1403 UNSERIALIZE_SCALAR(stq);
1404 UNSERIALIZE_SCALAR(op);
1405 UNSERIALIZE_SCALAR(flag);
1406 UNSERIALIZE_SCALAR(cpu);
1407 dump = true;
1408}
1409
1410CPA*
1411CPAParams::create()
1412{
1413 return new CPA(this);
1414}
1415
1393{
1394 UNSERIALIZE_SCALAR(time);
1395 UNSERIALIZE_SCALAR(data);
1396 orig_data = data;
1397 UNSERIALIZE_SCALAR(sm);
1398 UNSERIALIZE_SCALAR(stq);
1399 UNSERIALIZE_SCALAR(op);
1400 UNSERIALIZE_SCALAR(flag);
1401 UNSERIALIZE_SCALAR(cpu);
1402 dump = true;
1403}
1404
1405CPA*
1406CPAParams::create()
1407{
1408 return new CPA(this);
1409}
1410