Gabe Black has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/12445
Change subject: systemc: Keep track of more cases when we should be ready
after resume.
......................................................................
systemc: Keep track of more cases when we should be ready after resume.
If a thread self suspends, it should be marked as ready after resuming.
If a process was already ready when suspended, it should also be
remarked as ready after resuming.
Special care has to be taken in pre-initialization situations so that
processes are put on the right lists, and whether a process is tracked
is already marked as ready.
Change-Id: I15da7d747db591785358d47781297468c5f9fd09
---
M src/systemc/core/process.cc
M src/systemc/core/scheduler.cc
M src/systemc/core/scheduler.hh
3 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/src/systemc/core/process.cc b/src/systemc/core/process.cc
index 830b8c7..1fd16e0 100644
--- a/src/systemc/core/process.cc
+++ b/src/systemc/core/process.cc
@@ -160,12 +160,16 @@
if (!_suspended) {
_suspended = true;
- _suspendedReady = false;
- }
+ _suspendedReady = scheduler.suspend(this);
- if (procKind() != ::sc_core::SC_METHOD_PROC_ &&
- scheduler.current() == this) {
- scheduler.yield();
+ if (procKind() != ::sc_core::SC_METHOD_PROC_ &&
+ scheduler.current() == this) {
+ // This isn't in the spec, but Accellera says that a thread
that
+ // self suspends should be marked ready immediately when it's
+ // resumed.
+ _suspendedReady = true;
+ scheduler.yield();
+ }
}
}
@@ -178,7 +182,7 @@
if (_suspended) {
_suspended = false;
if (_suspendedReady)
- ready();
+ scheduler.resume(this);
_suspendedReady = false;
}
}
diff --git a/src/systemc/core/scheduler.cc b/src/systemc/core/scheduler.cc
index 46053b4..9b431ac 100644
--- a/src/systemc/core/scheduler.cc
+++ b/src/systemc/core/scheduler.cc
@@ -201,6 +201,39 @@
}
void
+Scheduler::resume(Process *p)
+{
+ if (initDone)
+ ready(p);
+ else
+ initList.pushLast(p);
+}
+
+bool
+Scheduler::suspend(Process *p)
+{
+ if (initDone) {
+ // After initialization, the only list we can be on is the ready
list.
+ bool was_ready = (p->nextListNode != nullptr);
+ p->popListNode();
+ return was_ready;
+ } else {
+ bool was_ready = false;
+ // Check the ready list to see if we find this process.
+ ListNode *n = readyList.nextListNode;
+ while (n != &readyList) {
+ if (n == p) {
+ was_ready = true;
+ break;
+ }
+ }
+ if (was_ready)
+ toFinalize.pushLast(p);
+ return was_ready;
+ }
+}
+
+void
Scheduler::requestUpdate(Channel *c)
{
updateList.pushLast(c);
diff --git a/src/systemc/core/scheduler.hh b/src/systemc/core/scheduler.hh
index 2da8da4..f55ff1f 100644
--- a/src/systemc/core/scheduler.hh
+++ b/src/systemc/core/scheduler.hh
@@ -182,6 +182,14 @@
// Put a process on the ready list.
void ready(Process *p);
+ // Mark a process as ready if init is finished, or put it on the list
of
+ // processes to be initialized.
+ void resume(Process *p);
+
+ // Remove a process from the ready/init list if it was on one of them,
and
+ // return if it was.
+ bool suspend(Process *p);
+
// Schedule an update for a given channel.
void requestUpdate(Channel *c);
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/12445
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I15da7d747db591785358d47781297468c5f9fd09
Gerrit-Change-Number: 12445
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev