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