46 #include "config/the_isa.hh"
54 #include "debug/Activity.hh"
55 #include "debug/Drain.hh"
56 #include "debug/O3CPU.hh"
57 #include "debug/Quiesce.hh"
58 #include "enums/MemoryMode.hh"
86 tickEvent([this]{
tick(); },
"FullO3CPU tick",
88 threadExitEvent([
this]{ exitThreads(); },
"FullO3CPU exit threads",
93 removeInstsThisCycle(
false),
103 regFile(params->numPhysIntRegs,
104 params->numPhysFloatRegs,
105 params->numPhysVecRegs,
106 params->numPhysVecPredRegs,
107 params->numPhysCCRegs,
110 freeList(
name() +
".freelist", ®File),
114 scoreboard(
name() +
".scoreboard",
115 regFile.totalNumPhysRegs()),
117 isa(numThreads, NULL),
119 timeBuffer(params->backComSize, params->forwardComSize),
120 fetchQueue(params->backComSize, params->forwardComSize),
121 decodeQueue(params->backComSize, params->forwardComSize),
122 renameQueue(params->backComSize, params->forwardComSize),
123 iewQueue(params->backComSize, params->forwardComSize),
124 activityRec(
name(), NumStages,
125 params->backComSize + params->forwardComSize,
130 lastRunningCycle(curCycle())
132 if (!params->switched_out) {
135 _status = SwitchedOut;
138 if (params->checker) {
139 BaseCPU *temp_checker = params->checker;
142 checker->setSystem(params->system);
148 thread.resize(numThreads);
149 tids.resize(numThreads);
157 fetch.setActiveThreads(&activeThreads);
158 decode.setActiveThreads(&activeThreads);
159 rename.setActiveThreads(&activeThreads);
160 iew.setActiveThreads(&activeThreads);
161 commit.setActiveThreads(&activeThreads);
164 fetch.setTimeBuffer(&timeBuffer);
165 decode.setTimeBuffer(&timeBuffer);
166 rename.setTimeBuffer(&timeBuffer);
167 iew.setTimeBuffer(&timeBuffer);
168 commit.setTimeBuffer(&timeBuffer);
171 fetch.setFetchQueue(&fetchQueue);
172 decode.setFetchQueue(&fetchQueue);
173 commit.setFetchQueue(&fetchQueue);
174 decode.setDecodeQueue(&decodeQueue);
175 rename.setDecodeQueue(&decodeQueue);
176 rename.setRenameQueue(&renameQueue);
177 iew.setRenameQueue(&renameQueue);
178 iew.setIEWQueue(&iewQueue);
179 commit.setIEWQueue(&iewQueue);
180 commit.setRenameQueue(&renameQueue);
182 commit.setIEWStage(&iew);
183 rename.setIEWStage(&iew);
184 rename.setCommitStage(&commit);
190 active_threads = params->workload.size();
192 if (active_threads > Impl::MaxThreads) {
193 panic(
"Workload Size too large. Increase the 'MaxThreads' "
194 "constant in your O3CPU impl. file (e.g. o3/alpha/impl.hh) "
195 "or edit your workload size.");
206 rename.setScoreboard(&scoreboard);
207 iew.setScoreboard(&scoreboard);
210 for (
ThreadID tid = 0; tid < numThreads; tid++) {
211 isa[tid] =
dynamic_cast<TheISA::ISA *
>(params->isa[tid]);
229 for (
ThreadID tid = 0; tid < active_threads; tid++) {
241 commitRenameMap[tid].setEntry(
248 if (vecMode == Enums::Full) {
253 renameMap[tid].setEntry(rid, phys_reg);
254 commitRenameMap[tid].setEntry(rid, phys_reg);
263 renameMap[tid].setEntry(lrid, phys_elem);
264 commitRenameMap[tid].setEntry(lrid, phys_elem);
272 commitRenameMap[tid].setEntry(
283 rename.setRenameMap(renameMap);
284 commit.setRenameMap(commitRenameMap);
285 rename.setFreeList(&freeList);
290 lastActivatedCycle = 0;
292 DPRINTF(O3CPU,
"Creating O3CPU object.\n");
295 this->thread.resize(this->numThreads);
297 for (
ThreadID tid = 0; tid < this->numThreads; ++tid) {
300 assert(this->numThreads == 1);
301 this->thread[tid] =
new Thread(
this, 0, NULL);
303 if (tid < params->workload.size()) {
304 DPRINTF(O3CPU,
"Workload[%i] process is %#x",
305 tid, this->thread[tid]);
307 (
typename Impl::O3CPU *)(
this),
308 tid, params->workload[tid]);
318 (
typename Impl::O3CPU *)(
this),
333 if (params->checker) {
335 o3_tc, this->checker);
338 o3_tc->
cpu = (
typename Impl::O3CPU *)(
this);
340 o3_tc->
thread = this->thread[tid];
343 this->thread[tid]->tc = tc;
346 this->threadContexts.push_back(tc);
350 if (!params->switched_out && interrupts.empty()) {
351 fatal(
"FullO3CPU %s has no interrupt controller.\n"
352 "Ensure createInterruptController() is called.\n",
name());
355 for (
ThreadID tid = 0; tid < this->numThreads; tid++)
356 this->thread[tid]->setFuncExeInst(0);
359 template <
class Impl>
364 template <
class Impl>
373 fetch.regProbePoints();
374 rename.regProbePoints();
375 iew.regProbePoints();
376 commit.regProbePoints();
379 template <
class Impl>
387 .name(
name() +
".timesIdled")
388 .desc(
"Number of times that the entire CPU went into an idle state and"
389 " unscheduled itself")
393 .name(
name() +
".idleCycles")
394 .desc(
"Total number of cycles that the CPU has spent unscheduled due "
399 .name(
name() +
".quiesceCycles")
400 .desc(
"Total number of cycles that CPU has spent quiesced or waiting "
410 .name(
name() +
".committedInsts")
411 .desc(
"Number of Instructions Simulated")
416 .name(
name() +
".committedOps")
417 .desc(
"Number of Ops (including micro ops) Simulated")
421 .name(
name() +
".cpi")
422 .desc(
"CPI: Cycles Per Instruction")
424 cpi = numCycles / committedInsts;
427 .name(
name() +
".cpi_total")
428 .desc(
"CPI: Total CPI of All Threads")
430 totalCpi = numCycles /
sum(committedInsts);
433 .name(
name() +
".ipc")
434 .desc(
"IPC: Instructions Per Cycle")
436 ipc = committedInsts / numCycles;
439 .name(
name() +
".ipc_total")
440 .desc(
"IPC: Total IPC of All Threads")
442 totalIpc =
sum(committedInsts) / numCycles;
444 this->iew.regStats();
447 .name(
name() +
".int_regfile_reads")
448 .desc(
"number of integer regfile reads")
449 .prereq(intRegfileReads);
452 .name(
name() +
".int_regfile_writes")
453 .desc(
"number of integer regfile writes")
454 .prereq(intRegfileWrites);
457 .name(
name() +
".fp_regfile_reads")
458 .desc(
"number of floating regfile reads")
459 .prereq(fpRegfileReads);
462 .name(
name() +
".fp_regfile_writes")
463 .desc(
"number of floating regfile writes")
464 .prereq(fpRegfileWrites);
467 .name(
name() +
".vec_regfile_reads")
468 .desc(
"number of vector regfile reads")
469 .prereq(vecRegfileReads);
472 .name(
name() +
".vec_regfile_writes")
473 .desc(
"number of vector regfile writes")
474 .prereq(vecRegfileWrites);
477 .name(
name() +
".pred_regfile_reads")
478 .desc(
"number of predicate regfile reads")
479 .prereq(vecPredRegfileReads);
482 .name(
name() +
".pred_regfile_writes")
483 .desc(
"number of predicate regfile writes")
484 .prereq(vecPredRegfileWrites);
487 .name(
name() +
".cc_regfile_reads")
488 .desc(
"number of cc regfile reads")
489 .prereq(ccRegfileReads);
492 .name(
name() +
".cc_regfile_writes")
493 .desc(
"number of cc regfile writes")
494 .prereq(ccRegfileWrites);
497 .name(
name() +
".misc_regfile_reads")
498 .desc(
"number of misc regfile reads")
499 .prereq(miscRegfileReads);
502 .name(
name() +
".misc_regfile_writes")
503 .desc(
"number of misc regfile writes")
504 .prereq(miscRegfileWrites);
507 template <
class Impl>
511 DPRINTF(
O3CPU,
"\n\nFullO3CPU: Ticking main, FullO3CPU.\n");
512 assert(!switchedOut());
532 timeBuffer.advance();
534 fetchQueue.advance();
535 decodeQueue.advance();
536 renameQueue.advance();
539 activityRec.advance();
541 if (removeInstsThisCycle) {
542 cleanUpRemovedInsts();
545 if (!tickEvent.scheduled()) {
546 if (_status == SwitchedOut) {
549 lastRunningCycle = curCycle();
550 }
else if (!activityRec.active() || _status == Idle) {
552 lastRunningCycle = curCycle();
555 schedule(tickEvent, clockEdge(
Cycles(1)));
561 updateThreadPriority();
566 template <
class Impl>
572 for (
ThreadID tid = 0; tid < numThreads; ++tid) {
575 thread[tid]->noSquashFromTC =
true;
577 thread[tid]->initMemProxies(thread[tid]->getTC());
581 for (
int tid = 0; tid < numThreads; ++tid)
582 thread[tid]->noSquashFromTC =
false;
584 commit.setThreads(thread);
587 template <
class Impl>
593 fetch.startupStage();
594 decode.startupStage();
596 rename.startupStage();
597 commit.startupStage();
600 template <
class Impl>
605 std::find(activeThreads.begin(), activeThreads.end(), tid);
607 DPRINTF(
O3CPU,
"[tid:%i] Calling activate thread.\n", tid);
608 assert(!switchedOut());
610 if (isActive == activeThreads.end()) {
611 DPRINTF(
O3CPU,
"[tid:%i] Adding to active threads list\n",
614 activeThreads.push_back(tid);
618 template <
class Impl>
624 assert(!commit.executingHtmTransaction(tid));
628 std::find(activeThreads.begin(), activeThreads.end(), tid);
630 DPRINTF(
O3CPU,
"[tid:%i] Calling deactivate thread.\n", tid);
631 assert(!switchedOut());
633 if (thread_it != activeThreads.end()) {
634 DPRINTF(
O3CPU,
"[tid:%i] Removing from active threads list\n",
636 activeThreads.erase(thread_it);
639 fetch.deactivateThread(tid);
640 commit.deactivateThread(tid);
643 template <
class Impl>
651 total += thread[
i]->numInst;
656 template <
class Impl>
664 total += thread[
i]->numOp;
669 template <
class Impl>
673 assert(!switchedOut());
686 if (lastActivatedCycle == 0 || lastActivatedCycle <
curTick()) {
687 scheduleTickEvent(
Cycles(0));
691 activityRec.activity();
692 fetch.wakeFromQuiesce();
694 Cycles cycles(curCycle() - lastRunningCycle);
700 lastActivatedCycle =
curTick();
708 template <
class Impl>
712 DPRINTF(
O3CPU,
"[tid:%i] Suspending Thread Context.\n", tid);
713 assert(!switchedOut());
715 deactivateThread(tid);
718 if (activeThreads.size() == 0) {
719 unscheduleTickEvent();
720 lastRunningCycle = curCycle();
724 DPRINTF(Quiesce,
"Suspending Context\n");
729 template <
class Impl>
734 DPRINTF(
O3CPU,
"[tid:%i] Halt Context called. Deallocating\n", tid);
735 assert(!switchedOut());
737 deactivateThread(tid);
743 template <
class Impl>
752 src_tc =
system->threads[tid];
754 src_tc = tcBase(tid);
761 renameMap[tid].setEntry(reg_id, phys_reg);
762 scoreboard.setReg(phys_reg);
769 renameMap[tid].setEntry(reg_id, phys_reg);
770 scoreboard.setReg(phys_reg);
777 renameMap[tid].setEntry(reg_id, phys_reg);
778 scoreboard.setReg(phys_reg);
785 pcState(src_tc->
pcState(), tid);
789 activateContext(tid);
792 commit.rob->resetEntries();
795 template <
class Impl>
799 DPRINTF(
O3CPU,
"[tid:%i] Removing thread context from CPU.\n", tid);
812 commit.clearStates(tid);
813 fetch.clearStates(tid);
814 decode.clearStates(tid);
815 rename.clearStates(tid);
816 iew.clearStates(tid);
821 assert(iew.instQueue.getCount(tid) == 0);
822 assert(iew.ldstQueue.getCount(tid) == 0);
823 assert(commit.rob->isEmpty(tid));
839 template <
class Impl>
843 if (vecMode == Enums::Elem) {
847 commitRenameMap[tid].lookup(
851 }
else if (vecMode == Enums::Full) {
854 commitRenameMap[tid].lookup(
861 template <
class Impl>
865 auto pc = this->pcState(tid);
871 if (new_mode != vecMode) {
874 renameMap[tid].switchMode(vecMode);
875 commitRenameMap[tid].switchMode(vecMode);
876 renameMap[tid].switchFreeList(freelist);
877 setVectorsAsReady(tid);
881 template <
class Impl>
886 return this->interrupts[0]->getInterrupt();
889 template <
class Impl>
900 this->interrupts[0]->updateIntrInfo();
902 DPRINTF(
O3CPU,
"Interrupt %s being handled\n", interrupt->name());
903 this->trap(interrupt, 0,
nullptr);
906 template <
class Impl>
912 fault->invoke(this->threadContexts[tid], inst);
915 template <
class Impl>
919 DPRINTF(
O3CPU,
"[tid:%i] Executing syscall().\n\n", tid);
921 DPRINTF(Activity,
"Activity: syscall() called.\n");
925 ++(this->thread[tid]->funcExeInst);
928 this->thread[tid]->syscall();
932 --(this->thread[tid]->funcExeInst);
935 template <
class Impl>
939 thread[tid]->serialize(
cp);
942 template <
class Impl>
946 thread[tid]->unserialize(
cp);
949 template <
class Impl>
954 deschedulePowerGatingEvent();
960 DPRINTF(Drain,
"Draining...\n");
972 if (!isCpuDrained()) {
974 for (
auto t : threadContexts) {
976 DPRINTF(Drain,
"Currently suspended so activate %i \n",
980 activateContext(
t->threadId());
985 activityRec.activity();
987 DPRINTF(Drain,
"CPU not drained\n");
991 DPRINTF(Drain,
"CPU is already drained\n");
992 if (tickEvent.scheduled())
993 deschedule(tickEvent);
999 for (
int i = 0;
i < timeBuffer.getSize(); ++
i) {
1000 timeBuffer.advance();
1001 fetchQueue.advance();
1002 decodeQueue.advance();
1003 renameQueue.advance();
1012 template <
class Impl>
1019 if (tickEvent.scheduled())
1020 deschedule(tickEvent);
1022 DPRINTF(Drain,
"CPU done draining, processing drain event\n");
1028 template <
class Impl>
1032 assert(isCpuDrained());
1033 fetch.drainSanityCheck();
1034 decode.drainSanityCheck();
1035 rename.drainSanityCheck();
1036 iew.drainSanityCheck();
1037 commit.drainSanityCheck();
1040 template <
class Impl>
1046 if (!instList.empty() || !removeList.empty()) {
1047 DPRINTF(Drain,
"Main CPU structures not drained.\n");
1051 if (!fetch.isDrained()) {
1052 DPRINTF(Drain,
"Fetch not drained.\n");
1056 if (!decode.isDrained()) {
1057 DPRINTF(Drain,
"Decode not drained.\n");
1061 if (!rename.isDrained()) {
1062 DPRINTF(Drain,
"Rename not drained.\n");
1066 if (!iew.isDrained()) {
1067 DPRINTF(Drain,
"IEW not drained.\n");
1071 if (!commit.isDrained()) {
1072 DPRINTF(Drain,
"Commit not drained.\n");
1079 template <
class Impl>
1083 fetch.drainStall(tid);
1086 template <
class Impl>
1093 DPRINTF(Drain,
"Resuming...\n");
1096 fetch.drainResume();
1097 commit.drainResume();
1102 DPRINTF(Drain,
"Activating thread: %i\n",
i);
1108 assert(!tickEvent.scheduled());
1110 schedule(tickEvent, nextCycle());
1113 schedulePowerGatingEvent();
1116 template <
class Impl>
1123 activityRec.reset();
1125 _status = SwitchedOut;
1128 checker->switchOut();
1131 template <
class Impl>
1137 fetch.takeOverFrom();
1138 decode.takeOverFrom();
1139 rename.takeOverFrom();
1141 commit.takeOverFrom();
1143 assert(!tickEvent.scheduled());
1149 lastRunningCycle = curCycle();
1153 template <
class Impl>
1157 if (!
system->isTimingMode()) {
1158 fatal(
"The O3 CPU requires the memory system to be in "
1159 "'timing' mode.\n");
1163 template <
class Impl>
1167 return this->isa[tid]->readMiscRegNoEffect(misc_reg);
1170 template <
class Impl>
1175 return this->isa[tid]->readMiscReg(misc_reg);
1178 template <
class Impl>
1182 this->isa[tid]->setMiscRegNoEffect(misc_reg,
val);
1185 template <
class Impl>
1189 miscRegfileWrites++;
1190 this->isa[tid]->setMiscReg(misc_reg,
val);
1193 template <
class Impl>
1198 return regFile.readIntReg(phys_reg);
1201 template <
class Impl>
1206 return regFile.readFloatReg(phys_reg);
1209 template <
class Impl>
1215 return regFile.readVecReg(phys_reg);
1218 template <
class Impl>
1224 return regFile.getWritableVecReg(phys_reg);
1227 template <
class Impl>
1232 return regFile.readVecElem(phys_reg);
1235 template <
class Impl>
1240 vecPredRegfileReads++;
1241 return regFile.readVecPredReg(phys_reg);
1244 template <
class Impl>
1249 vecPredRegfileWrites++;
1250 return regFile.getWritableVecPredReg(phys_reg);
1253 template <
class Impl>
1258 return regFile.readCCReg(phys_reg);
1261 template <
class Impl>
1266 regFile.setIntReg(phys_reg,
val);
1269 template <
class Impl>
1274 regFile.setFloatReg(phys_reg,
val);
1277 template <
class Impl>
1282 regFile.setVecReg(phys_reg,
val);
1285 template <
class Impl>
1290 regFile.setVecElem(phys_reg,
val);
1293 template <
class Impl>
1298 vecPredRegfileWrites++;
1299 regFile.setVecPredReg(phys_reg,
val);
1302 template <
class Impl>
1307 regFile.setCCReg(phys_reg,
val);
1310 template <
class Impl>
1318 return regFile.readIntReg(phys_reg);
1321 template <
class Impl>
1329 return regFile.readFloatReg(phys_reg);
1332 template <
class Impl>
1342 template <
class Impl>
1349 return getWritableVecReg(phys_reg);
1352 template <
class Impl>
1362 template <
class Impl>
1369 return readVecPredReg(phys_reg);
1372 template <
class Impl>
1379 return getWritableVecPredReg(phys_reg);
1382 template <
class Impl>
1390 return regFile.readCCReg(phys_reg);
1393 template <
class Impl>
1401 regFile.setIntReg(phys_reg,
val);
1404 template <
class Impl>
1412 regFile.setFloatReg(phys_reg,
val);
1415 template <
class Impl>
1425 template <
class Impl>
1432 setVecElem(phys_reg,
val);
1435 template <
class Impl>
1442 setVecPredReg(phys_reg,
val);
1445 template <
class Impl>
1453 regFile.setCCReg(phys_reg,
val);
1456 template <
class Impl>
1460 return commit.pcState(tid);
1463 template <
class Impl>
1467 commit.pcState(
val, tid);
1470 template <
class Impl>
1474 return commit.instAddr(tid);
1477 template <
class Impl>
1481 return commit.nextInstAddr(tid);
1484 template <
class Impl>
1488 return commit.microPC(tid);
1491 template <
class Impl>
1495 this->thread[tid]->noSquashFromTC =
true;
1496 this->commit.generateTCEvent(tid);
1499 template <
class Impl>
1503 instList.push_back(inst);
1505 return --(instList.end());
1508 template <
class Impl>
1513 if (!inst->isMicroop() || inst->isLastMicroop()) {
1514 thread[tid]->numInst++;
1515 thread[tid]->threadStats.numInsts++;
1516 committedInsts[tid]++;
1520 thread[tid]->comInstEventQueue.serviceEvents(thread[tid]->numInst);
1522 thread[tid]->numOp++;
1523 thread[tid]->threadStats.numOps++;
1524 committedOps[tid]++;
1526 probeInstCommit(inst->staticInst, inst->instAddr());
1529 template <
class Impl>
1533 DPRINTF(
O3CPU,
"Removing committed instruction [tid:%i] PC %s "
1535 inst->threadNumber, inst->pcState(), inst->seqNum);
1537 removeInstsThisCycle =
true;
1540 removeList.push(inst->getInstListIt());
1543 template <
class Impl>
1547 DPRINTF(
O3CPU,
"Thread %i: Deleting instructions from instruction"
1552 bool rob_empty =
false;
1554 if (instList.empty()) {
1556 }
else if (rob.isEmpty(tid)) {
1557 DPRINTF(
O3CPU,
"ROB is empty, squashing all insts.\n");
1558 end_it = instList.begin();
1561 end_it = (rob.readTailInst(tid))->getInstListIt();
1562 DPRINTF(
O3CPU,
"ROB is not empty, squashing insts not in ROB.\n");
1565 removeInstsThisCycle =
true;
1567 ListIt inst_it = instList.end();
1573 while (inst_it != end_it) {
1574 assert(!instList.empty());
1576 squashInstIt(inst_it, tid);
1584 squashInstIt(inst_it, tid);
1588 template <
class Impl>
1592 assert(!instList.empty());
1594 removeInstsThisCycle =
true;
1596 ListIt inst_iter = instList.end();
1600 DPRINTF(
O3CPU,
"Deleting instructions from instruction "
1601 "list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n",
1602 tid, seq_num, (*inst_iter)->seqNum);
1604 while ((*inst_iter)->seqNum > seq_num) {
1606 bool break_loop = (inst_iter == instList.begin());
1608 squashInstIt(inst_iter, tid);
1617 template <
class Impl>
1621 if ((*instIt)->threadNumber == tid) {
1623 "[tid:%i] [sn:%lli] PC %s\n",
1624 (*instIt)->threadNumber,
1626 (*instIt)->pcState());
1629 (*instIt)->setSquashed();
1634 removeList.push(instIt);
1638 template <
class Impl>
1642 while (!removeList.empty()) {
1644 "[tid:%i] [sn:%lli] PC %s\n",
1645 (*removeList.front())->threadNumber,
1646 (*removeList.front())->seqNum,
1647 (*removeList.front())->pcState());
1649 instList.erase(removeList.front());
1654 removeInstsThisCycle =
false;
1664 template <
class Impl>
1670 ListIt inst_list_it = instList.begin();
1672 cprintf(
"Dumping Instruction List\n");
1674 while (inst_list_it != instList.end()) {
1675 cprintf(
"Instruction:%i\nPC:%#x\n[tid:%i]\n[sn:%lli]\nIssued:%i\n"
1677 num, (*inst_list_it)->instAddr(), (*inst_list_it)->threadNumber,
1678 (*inst_list_it)->seqNum, (*inst_list_it)->isIssued(),
1679 (*inst_list_it)->isSquashed());
1692 template <
class Impl>
1696 if (activityRec.active() || tickEvent.scheduled()) {
1697 DPRINTF(Activity,
"CPU already running.\n");
1701 DPRINTF(Activity,
"Waking up CPU\n");
1703 Cycles cycles(curCycle() - lastRunningCycle);
1707 idleCycles += cycles;
1708 numCycles += cycles;
1711 schedule(tickEvent, clockEdge());
1714 template <
class Impl>
1723 DPRINTF(Quiesce,
"Suspended Processor woken\n");
1724 this->threadContexts[tid]->activate();
1727 template <
class Impl>
1731 for (
ThreadID tid = 0; tid < numThreads; tid++) {
1741 template <
class Impl>
1745 if (activeThreads.size() > 1) {
1750 unsigned high_thread = *list_begin;
1752 activeThreads.erase(list_begin);
1754 activeThreads.push_back(high_thread);
1758 template <
class Impl>
1762 DPRINTF(
O3CPU,
"Thread %d is inserted to exitingThreads list\n", tid);
1768 assert(exitingThreads.count(tid) == 0);
1775 exitingThreads.emplace(std::make_pair(tid,
false));
1778 template <
class Impl>
1782 return exitingThreads.count(tid) == 1;
1785 template <
class Impl>
1789 assert(exitingThreads.count(tid) == 1);
1793 exitingThreads[tid] =
true;
1801 if (!threadExitEvent.scheduled()) {
1802 schedule(threadExitEvent, nextCycle());
1806 template <
class Impl>
1811 assert(exitingThreads.size() > 0);
1814 auto it = exitingThreads.begin();
1815 while (it != exitingThreads.end()) {
1817 bool readyToExit = it->second;
1821 haltContext(thread_id);
1823 it = exitingThreads.erase(it);
1830 template <
class Impl>
1841 this->iew.ldstQueue.resetHtmStartsStops(tid);
1842 this->commit.resetHtmStartsStops(tid);
1846 std::make_shared<Request>(
addr, size, flags, _dataRequestorId);
1848 req->taskId(taskId());
1849 req->setContext(this->thread[tid]->contextId());
1850 req->setHtmAbortCause(cause);
1852 assert(req->isHTMAbort());
1855 uint8_t *memData =
new uint8_t[8];
1861 if (!this->iew.ldstQueue.getDataPort().sendTimingReq(abort_pkt)) {
1862 panic(
"HTM abort signal was not sent to the memory subsystem.");