base.cc (5536:17c0c17726ff) | base.cc (5606:6da7a58b0bc8) |
---|---|
1/* 2 * Copyright (c) 2002-2005 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; --- 46 unchanged lines hidden (view full) --- 55 56vector<BaseCPU *> BaseCPU::cpuList; 57 58// This variable reflects the max number of threads in any CPU. Be 59// careful to only use it once all the CPUs that you care about have 60// been initialized 61int maxThreadsPerCPU = 1; 62 | 1/* 2 * Copyright (c) 2002-2005 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; --- 46 unchanged lines hidden (view full) --- 55 56vector<BaseCPU *> BaseCPU::cpuList; 57 58// This variable reflects the max number of threads in any CPU. Be 59// careful to only use it once all the CPUs that you care about have 60// been initialized 61int maxThreadsPerCPU = 1; 62 |
63CPUProgressEvent::CPUProgressEvent(EventQueue *q, Tick ival, 64 BaseCPU *_cpu) 65 : Event(q, Event::Progress_Event_Pri), interval(ival), 66 lastNumInst(0), cpu(_cpu) | 63CPUProgressEvent::CPUProgressEvent(BaseCPU *_cpu, Tick ival) 64 : Event(Event::Progress_Event_Pri), interval(ival), lastNumInst(0), 65 cpu(_cpu) |
67{ 68 if (interval) | 66{ 67 if (interval) |
69 schedule(curTick + interval); | 68 cpu->schedule(this, curTick + interval); |
70} 71 72void 73CPUProgressEvent::process() 74{ 75 Counter temp = cpu->totalInstructions(); 76#ifndef NDEBUG 77 double ipc = double(temp - lastNumInst) / (interval / cpu->ticks(1)); 78 79 DPRINTFN("%s progress event, instructions committed: %lli, IPC: %0.8d\n", 80 cpu->name(), temp - lastNumInst, ipc); 81 ipc = 0.0; 82#else 83 cprintf("%lli: %s progress event, instructions committed: %lli\n", 84 curTick, cpu->name(), temp - lastNumInst); 85#endif 86 lastNumInst = temp; | 69} 70 71void 72CPUProgressEvent::process() 73{ 74 Counter temp = cpu->totalInstructions(); 75#ifndef NDEBUG 76 double ipc = double(temp - lastNumInst) / (interval / cpu->ticks(1)); 77 78 DPRINTFN("%s progress event, instructions committed: %lli, IPC: %0.8d\n", 79 cpu->name(), temp - lastNumInst, ipc); 80 ipc = 0.0; 81#else 82 cprintf("%lli: %s progress event, instructions committed: %lli\n", 83 curTick, cpu->name(), temp - lastNumInst); 84#endif 85 lastNumInst = temp; |
87 schedule(curTick + interval); | 86 cpu->schedule(this, curTick + interval); |
88} 89 90const char * 91CPUProgressEvent::description() const 92{ 93 return "CPU Progress"; 94} 95 --- 20 unchanged lines hidden (view full) --- 116 // allocate per-thread instruction-based event queues 117 comInstEventQueue = new EventQueue *[number_of_threads]; 118 for (int i = 0; i < number_of_threads; ++i) 119 comInstEventQueue[i] = new EventQueue("instruction-based event queue"); 120 121 // 122 // set up instruction-count-based termination events, if any 123 // | 87} 88 89const char * 90CPUProgressEvent::description() const 91{ 92 return "CPU Progress"; 93} 94 --- 20 unchanged lines hidden (view full) --- 115 // allocate per-thread instruction-based event queues 116 comInstEventQueue = new EventQueue *[number_of_threads]; 117 for (int i = 0; i < number_of_threads; ++i) 118 comInstEventQueue[i] = new EventQueue("instruction-based event queue"); 119 120 // 121 // set up instruction-count-based termination events, if any 122 // |
124 if (p->max_insts_any_thread != 0) 125 for (int i = 0; i < number_of_threads; ++i) 126 schedExitSimLoop("a thread reached the max instruction count", 127 p->max_insts_any_thread, 0, 128 comInstEventQueue[i]); | 123 if (p->max_insts_any_thread != 0) { 124 const char *cause = "a thread reached the max instruction count"; 125 for (int i = 0; i < number_of_threads; ++i) { 126 Event *event = new SimLoopExitEvent(cause, 0); 127 comInstEventQueue[i]->schedule(event, p->max_insts_any_thread); 128 } 129 } |
129 130 if (p->max_insts_all_threads != 0) { | 130 131 if (p->max_insts_all_threads != 0) { |
132 const char *cause = "all threads reached the max instruction count"; 133 |
|
131 // allocate & initialize shared downcounter: each event will 132 // decrement this when triggered; simulation will terminate 133 // when counter reaches 0 134 int *counter = new int; 135 *counter = number_of_threads; | 134 // allocate & initialize shared downcounter: each event will 135 // decrement this when triggered; simulation will terminate 136 // when counter reaches 0 137 int *counter = new int; 138 *counter = number_of_threads; |
136 for (int i = 0; i < number_of_threads; ++i) 137 new CountedExitEvent(comInstEventQueue[i], 138 "all threads reached the max instruction count", 139 p->max_insts_all_threads, *counter); | 139 for (int i = 0; i < number_of_threads; ++i) { 140 Event *event = new CountedExitEvent(cause, *counter); 141 comInstEventQueue[i]->schedule(event, p->max_insts_any_thread); 142 } |
140 } 141 142 // allocate per-thread load-based event queues 143 comLoadEventQueue = new EventQueue *[number_of_threads]; 144 for (int i = 0; i < number_of_threads; ++i) 145 comLoadEventQueue[i] = new EventQueue("load-based event queue"); 146 147 // 148 // set up instruction-count-based termination events, if any 149 // | 143 } 144 145 // allocate per-thread load-based event queues 146 comLoadEventQueue = new EventQueue *[number_of_threads]; 147 for (int i = 0; i < number_of_threads; ++i) 148 comLoadEventQueue[i] = new EventQueue("load-based event queue"); 149 150 // 151 // set up instruction-count-based termination events, if any 152 // |
150 if (p->max_loads_any_thread != 0) 151 for (int i = 0; i < number_of_threads; ++i) 152 schedExitSimLoop("a thread reached the max load count", 153 p->max_loads_any_thread, 0, 154 comLoadEventQueue[i]); | 153 if (p->max_loads_any_thread != 0) { 154 const char *cause = "a thread reached the max load count"; 155 for (int i = 0; i < number_of_threads; ++i) { 156 Event *event = new SimLoopExitEvent(cause, 0); 157 comLoadEventQueue[i]->schedule(event, p->max_loads_any_thread); 158 } 159 } |
155 156 if (p->max_loads_all_threads != 0) { | 160 161 if (p->max_loads_all_threads != 0) { |
162 const char *cause = "all threads reached the max load count"; |
|
157 // allocate & initialize shared downcounter: each event will 158 // decrement this when triggered; simulation will terminate 159 // when counter reaches 0 160 int *counter = new int; 161 *counter = number_of_threads; | 163 // allocate & initialize shared downcounter: each event will 164 // decrement this when triggered; simulation will terminate 165 // when counter reaches 0 166 int *counter = new int; 167 *counter = number_of_threads; |
162 for (int i = 0; i < number_of_threads; ++i) 163 new CountedExitEvent(comLoadEventQueue[i], 164 "all threads reached the max load count", 165 p->max_loads_all_threads, *counter); | 168 for (int i = 0; i < number_of_threads; ++i) { 169 Event *event = new CountedExitEvent(cause, *counter); 170 comLoadEventQueue[i]->schedule(event, p->max_loads_all_threads); 171 } |
166 } 167 168 functionTracingEnabled = false; 169 if (p->function_trace) { 170 functionTraceStream = simout.find(csprintf("ftrace.%s", name())); 171 currentFunctionStart = currentFunctionEnd = 0; 172 functionEntryTick = p->function_trace_start; 173 174 if (p->function_trace_start == 0) { 175 functionTracingEnabled = true; 176 } else { | 172 } 173 174 functionTracingEnabled = false; 175 if (p->function_trace) { 176 functionTraceStream = simout.find(csprintf("ftrace.%s", name())); 177 currentFunctionStart = currentFunctionEnd = 0; 178 functionEntryTick = p->function_trace_start; 179 180 if (p->function_trace_start == 0) { 181 functionTracingEnabled = true; 182 } else { |
177 new EventWrapper<BaseCPU, 178 &BaseCPU::enableFunctionTrace>( 179 this, p->function_trace_start, true); | 183 typedef EventWrapper<BaseCPU, &BaseCPU::enableFunctionTrace> wrap; 184 Event *event = new wrap(this, true); 185 schedule(event, p->function_trace_start); |
180 } 181 } 182#if FULL_SYSTEM 183 profileEvent = NULL; 184 if (params()->profile) 185 profileEvent = new ProfileEvent(this, params()->profile); 186#endif 187 tracer = params()->tracer; --- 16 unchanged lines hidden (view full) --- 204 registerThreadContexts(); 205} 206 207void 208BaseCPU::startup() 209{ 210#if FULL_SYSTEM 211 if (!params()->defer_registration && profileEvent) | 186 } 187 } 188#if FULL_SYSTEM 189 profileEvent = NULL; 190 if (params()->profile) 191 profileEvent = new ProfileEvent(this, params()->profile); 192#endif 193 tracer = params()->tracer; --- 16 unchanged lines hidden (view full) --- 210 registerThreadContexts(); 211} 212 213void 214BaseCPU::startup() 215{ 216#if FULL_SYSTEM 217 if (!params()->defer_registration && profileEvent) |
212 profileEvent->schedule(curTick); | 218 schedule(profileEvent, curTick); |
213#endif 214 215 if (params()->progress_interval) { | 219#endif 220 221 if (params()->progress_interval) { |
216 new CPUProgressEvent(&mainEventQueue, 217 ticks(params()->progress_interval), 218 this); | 222 Tick num_ticks = ticks(params()->progress_interval); 223 Event *event = new CPUProgressEvent(this, num_ticks); 224 schedule(event, curTick + num_ticks); |
219 } 220} 221 222 223void 224BaseCPU::regStats() 225{ 226 using namespace Stats; --- 68 unchanged lines hidden (view full) --- 295} 296 297void 298BaseCPU::switchOut() 299{ 300// panic("This CPU doesn't support sampling!"); 301#if FULL_SYSTEM 302 if (profileEvent && profileEvent->scheduled()) | 225 } 226} 227 228 229void 230BaseCPU::regStats() 231{ 232 using namespace Stats; --- 68 unchanged lines hidden (view full) --- 301} 302 303void 304BaseCPU::switchOut() 305{ 306// panic("This CPU doesn't support sampling!"); 307#if FULL_SYSTEM 308 if (profileEvent && profileEvent->scheduled()) |
303 profileEvent->deschedule(); | 309 deschedule(profileEvent); |
304#endif 305} 306 307void 308BaseCPU::takeOverFrom(BaseCPU *oldCPU, Port *ic, Port *dc) 309{ 310 assert(threadContexts.size() == oldCPU->threadContexts.size()); 311 --- 19 unchanged lines hidden (view full) --- 331 332#if FULL_SYSTEM 333 interrupts = oldCPU->interrupts; 334 335 for (int i = 0; i < threadContexts.size(); ++i) 336 threadContexts[i]->profileClear(); 337 338 if (profileEvent) | 310#endif 311} 312 313void 314BaseCPU::takeOverFrom(BaseCPU *oldCPU, Port *ic, Port *dc) 315{ 316 assert(threadContexts.size() == oldCPU->threadContexts.size()); 317 --- 19 unchanged lines hidden (view full) --- 337 338#if FULL_SYSTEM 339 interrupts = oldCPU->interrupts; 340 341 for (int i = 0; i < threadContexts.size(); ++i) 342 threadContexts[i]->profileClear(); 343 344 if (profileEvent) |
339 profileEvent->schedule(curTick); | 345 schedule(profileEvent, curTick); |
340#endif 341 342 // Connect new CPU to old CPU's memory only if new CPU isn't 343 // connected to anything. Also connect old CPU's memory to new 344 // CPU. 345 if (!ic->isConnected()) { 346 Port *peer = oldCPU->getPort("icache_port")->getPeer(); 347 ic->setPeer(peer); --- 5 unchanged lines hidden (view full) --- 353 dc->setPeer(peer); 354 peer->setPeer(dc); 355 } 356} 357 358 359#if FULL_SYSTEM 360BaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, Tick _interval) | 346#endif 347 348 // Connect new CPU to old CPU's memory only if new CPU isn't 349 // connected to anything. Also connect old CPU's memory to new 350 // CPU. 351 if (!ic->isConnected()) { 352 Port *peer = oldCPU->getPort("icache_port")->getPeer(); 353 ic->setPeer(peer); --- 5 unchanged lines hidden (view full) --- 359 dc->setPeer(peer); 360 peer->setPeer(dc); 361 } 362} 363 364 365#if FULL_SYSTEM 366BaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, Tick _interval) |
361 : Event(&mainEventQueue), cpu(_cpu), interval(_interval) | 367 : cpu(_cpu), interval(_interval) |
362{ } 363 364void 365BaseCPU::ProfileEvent::process() 366{ 367 for (int i = 0, size = cpu->threadContexts.size(); i < size; ++i) { 368 ThreadContext *tc = cpu->threadContexts[i]; 369 tc->profileSample(); 370 } 371 | 368{ } 369 370void 371BaseCPU::ProfileEvent::process() 372{ 373 for (int i = 0, size = cpu->threadContexts.size(); i < size; ++i) { 374 ThreadContext *tc = cpu->threadContexts[i]; 375 tc->profileSample(); 376 } 377 |
372 schedule(curTick + interval); | 378 cpu->schedule(this, curTick + interval); |
373} 374 375void 376BaseCPU::post_interrupt(int int_num, int index) 377{ 378 interrupts.post(int_num, index); 379} 380 --- 60 unchanged lines hidden --- | 379} 380 381void 382BaseCPU::post_interrupt(int int_num, int index) 383{ 384 interrupts.post(int_num, index); 385} 386 --- 60 unchanged lines hidden --- |