This was initially added in 2003 and only supported in the simple CPUs.
It's oddly specific since there are no other similar event queues for,
for instance, stores, branches, system calls, etc.
Given that this seems like a historical oddity which is only partially
supported and would be very hard to support on more diverse CPU types
like KVM or fast model which don't generally have hooks for counts of
specific instruction types.
Change-Id: I29209b7ffcf896cf424b71545c9c7546f439e2b9
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21780
Reviewed-by: Brandon Potter <Brandon.Potter@amd.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
PyBindMethod("flushTLBs"),
PyBindMethod("totalInsts"),
PyBindMethod("scheduleInstStop"),
- PyBindMethod("scheduleLoadStop"),
PyBindMethod("getCurrentInstCount"),
]
"terminate when any thread reaches this inst count")
simpoint_start_insts = VectorParam.Counter([],
"starting instruction counts of simpoints")
- max_loads_all_threads = Param.Counter(0,
- "terminate when all threads have reached this load count")
- max_loads_any_thread = Param.Counter(0,
- "terminate when any thread reaches this load count")
progress_interval = Param.Frequency('0Hz',
"frequency to print out the progress message")
}
}
- // allocate per-thread load-based event queues
- comLoadEventQueue = new EventQueue *[numThreads];
- for (ThreadID tid = 0; tid < numThreads; ++tid)
- comLoadEventQueue[tid] = new EventQueue("load-based event queue");
-
//
// set up instruction-count-based termination events, if any
//
- if (p->max_loads_any_thread != 0) {
- const char *cause = "a thread reached the max load count";
- for (ThreadID tid = 0; tid < numThreads; ++tid)
- scheduleLoadStop(tid, p->max_loads_any_thread, cause);
- }
-
- if (p->max_loads_all_threads != 0) {
- const char *cause = "all threads reached the max load count";
- // allocate & initialize shared downcounter: each event will
- // decrement this when triggered; simulation will terminate
- // when counter reaches 0
- int *counter = new int;
- *counter = numThreads;
- for (ThreadID tid = 0; tid < numThreads; ++tid) {
- Event *event = new CountedExitEvent(cause, *counter);
- comLoadEventQueue[tid]->schedule(event, p->max_loads_all_threads);
- }
- }
functionTracingEnabled = false;
if (p->function_trace) {
BaseCPU::~BaseCPU()
{
delete profileEvent;
- delete[] comLoadEventQueue;
delete[] comInstEventQueue;
}
return false;
}
-void
-BaseCPU::scheduleLoadStop(ThreadID tid, Counter loads, const char *cause)
-{
- const Tick now(comLoadEventQueue[tid]->getCurTick());
- Event *event(new LocalSimLoopExitEvent(cause, 0));
-
- comLoadEventQueue[tid]->schedule(event, now + loads);
-}
-
void
BaseCPU::traceFunctionsInternal(Addr pc)
*/
EventQueue **comInstEventQueue;
- /**
- * Vector of per-thread load-based event queues. Used for
- * scheduling events based on number of loads committed by
- *a particular thread.
- */
- EventQueue **comLoadEventQueue;
-
System *system;
/**
*/
void scheduleInstStop(ThreadID tid, Counter insts, const char *cause);
- /**
- * Schedule an event that exits the simulation loops after a
- * predefined number of load operations.
- *
- * This method is usually called from the configuration script to
- * get an exit event some time in the future. It is typically used
- * when the script wants to simulate for a specific number of
- * loads rather than ticks.
- *
- * @param tid Thread monitor.
- * @param loads Number of load instructions into the future.
- * @param cause Cause to signal in the exit event.
- */
- void scheduleLoadStop(ThreadID tid, Counter loads, const char *cause);
-
/**
* Get the number of instructions executed by the specified thread
* on this CPU. Used by Python to control simulation.
// cpu and therefore any parameters for early exit don't make much
// sense.
fatal_if(max_insts_any_thread || max_insts_all_threads ||
- max_loads_any_thread || max_loads_all_threads ||
progress_interval, "Invalid checker parameters");
return new DummyChecker(this);
// cpu and therefore any parameters for early exit don't make much
// sense.
fatal_if(max_insts_any_thread || max_insts_all_threads ||
- max_loads_any_thread || max_loads_all_threads ||
progress_interval, "Invalid checker parameters");
return new O3Checker(this);
if (curStaticInst->isLoad()) {
++t_info.numLoad;
- comLoadEventQueue[curThread]->serviceEvents(t_info.numLoad);
}
if (CPA::available()) {