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