MinorCPU::MinorCPU(MinorCPUParams *params) :
BaseCPU(params),
- pipelineStartupEvent([this]{ wakeupPipeline(); }, name()),
threadPolicy(params->threadPolicy)
{
/* This is only written for one thread at the moment */
void
MinorCPU::activateContext(ThreadID thread_id)
{
- /* Remember to wake up this thread_id by scheduling the
- * pipelineStartup event.
- * We can't wakeupFetch the thread right away because its context may
- * not have been fully initialized. For example, in the case of clone
- * syscall, this activateContext function is called in the middle of
- * the syscall and before the new thread context is initialized.
- * If we start fetching right away, the new thread will fetch from an
- * invalid address (i.e., pc is not initialized yet), which could lead
- * to a page fault. Instead, we remember which threads to wake up and
- * schedule an event to wake all them up after their contexts are
- * fully initialized */
- readyThreads.push_back(thread_id);
- if (!pipelineStartupEvent.scheduled())
- schedule(pipelineStartupEvent, clockEdge(Cycles(0)));
-}
-
-void
-MinorCPU::wakeupPipeline()
-{
- for (auto thread_id : readyThreads) {
- DPRINTF(MinorCPU, "ActivateContext thread: %d\n", thread_id);
+ DPRINTF(MinorCPU, "ActivateContext thread: %d\n", thread_id);
- /* Do some cycle accounting. lastStopped is reset to stop the
- * wakeup call on the pipeline from adding the quiesce period
- * to BaseCPU::numCycles */
- stats.quiesceCycles += pipeline->cyclesSinceLastStopped();
- pipeline->resetLastStopped();
-
- /* Wake up the thread, wakeup the pipeline tick */
- threads[thread_id]->activate();
- wakeupOnEvent(Minor::Pipeline::CPUStageId);
+ /* Do some cycle accounting. lastStopped is reset to stop the
+ * wakeup call on the pipeline from adding the quiesce period
+ * to BaseCPU::numCycles */
+ stats.quiesceCycles += pipeline->cyclesSinceLastStopped();
+ pipeline->resetLastStopped();
- pipeline->wakeupFetch(thread_id);
- BaseCPU::activateContext(thread_id);
- }
+ /* Wake up the thread, wakeup the pipeline tick */
+ threads[thread_id]->activate();
+ wakeupOnEvent(Minor::Pipeline::CPUStageId);
+ pipeline->wakeupFetch(thread_id);
- readyThreads.clear();
+ BaseCPU::activateContext(thread_id);
}
void
* Elements of pipeline call TheISA to implement the model. */
Minor::Pipeline *pipeline;
- /** An event that wakes up the pipeline when a thread context is
- * activated */
- EventFunctionWrapper pipelineStartupEvent;
-
- /** List of threads that are ready to wake up and run */
- std::vector<ThreadID> readyThreads;
-
public:
/** Activity recording for pipeline. This belongs to Pipeline but
* stages will access it through the CPU as the MinorCPU object
void activateContext(ThreadID thread_id) override;
void suspendContext(ThreadID thread_id) override;
- /** Wake up ready-to-run threads */
- void wakeupPipeline();
-
/** Thread scheduling utility functions */
std::vector<ThreadID> roundRobinPriority(ThreadID priority)
{
Stats::Scalar storeInstructions;
Stats::Scalar amoInstructions;
- public:
- /** Dump the whole contents of the input buffer. Useful after a
- * prediction changes control flow */
- void dumpAllInput(ThreadID tid);
-
protected:
/** Get a piece of data to work on from the inputBuffer, or 0 if there
* is no data. */
/** Pop an element off the input buffer, if there are any */
void popInput(ThreadID tid);
+ /** Dump the whole contents of the input buffer. Useful after a
+ * prediction changes control flow */
+ void dumpAllInput(ThreadID tid);
+
/** Update local branch prediction structures from feedback from
* Execute. */
void updateBranchPrediction(const BranchData &branch);