summaryrefslogtreecommitdiff
path: root/sim/sim.cpp
diff options
context:
space:
mode:
authorJulian Blake Kongslie2022-07-02 13:45:09 -0700
committerJulian Blake Kongslie2022-07-02 13:45:09 -0700
commitc72951a36d6cb9775dc1ecd9bc26bc13e796f10c (patch)
tree5a8fe196beba5c7c674d1b3d627c9a0beac849f5 /sim/sim.cpp
parentTrivial code reorg. (diff)
downloadissim-c72951a36d6cb9775dc1ecd9bc26bc13e796f10c.tar.xz
Dropping the async interface, and adding some real uarch.
Diffstat (limited to 'sim/sim.cpp')
-rw-r--r--sim/sim.cpp83
1 files changed, 83 insertions, 0 deletions
diff --git a/sim/sim.cpp b/sim/sim.cpp
new file mode 100644
index 0000000..e8f84ee
--- /dev/null
+++ b/sim/sim.cpp
@@ -0,0 +1,83 @@
1#include <utility>
2
3#include "sim/sim.h"
4#include "util/assert.h"
5
6namespace sim {
7
8 void Scheduler::add_schedulable(Schedulable *schedulable)
9 {
10 unsorted_schedulables.emplace(schedulable);
11 sort_needed = true;
12 }
13
14 void Scheduler::remove_schedulable(Schedulable *schedulable)
15 {
16 unsorted_schedulables.erase(schedulable);
17 std::erase_if(constraints, [schedulable](const auto &item) { return item.first == schedulable || item.second == schedulable; });
18 sort_needed = true;
19 }
20
21 void Scheduler::constrain(Schedulable *prior, Schedulable *later)
22 {
23 ASSERT(unsorted_schedulables.count(prior), "Constraint prior is not associated with this Scheduler");
24 ASSERT(unsorted_schedulables.count(later), "Constraint later is not associated with this Scheduler");
25 constraints.emplace(later, prior);
26 sort_needed = true;
27 }
28
29 void Scheduler::topo_sort(std::set<Schedulable *> &live, std::set<Schedulable *> &waiting, Schedulable *candidate)
30 {
31 ASSERT(!live.count(candidate), "Dependency loop");
32 for (auto prereq = constraints.find(candidate); prereq != constraints.end() && prereq->first == candidate; ++prereq) {
33 if (prereq->second != candidate && waiting.count(prereq->second)) {
34 live.emplace(candidate);
35 topo_sort(live, waiting, prereq->second);
36 }
37 }
38 sorted_schedulables.emplace_back(candidate);
39 waiting.erase(candidate);
40 }
41
42 void Scheduler::sort()
43 {
44 sorted_schedulables.clear();
45 sorted_schedulables.reserve(unsorted_schedulables.size());
46 auto waiting = unsorted_schedulables;
47 while (!waiting.empty()) {
48 std::set<Schedulable *> live;
49 topo_sort(live, waiting, *waiting.begin());
50 }
51 ASSERT(sorted_schedulables.size() == unsorted_schedulables.size(), "Did not sort every schedulable");
52 sort_needed = false;
53 }
54
55 void Scheduler::clock()
56 {
57 if (sort_needed)
58 sort();
59 for (const auto &s : sorted_schedulables) {
60 current_schedulable = s;
61 s->clock();
62 }
63 current_schedulable = nullptr;
64 ++now;
65 }
66
67 Schedulable::Schedulable(Scheduler &scheduler)
68 : scheduler(scheduler)
69 {
70 scheduler.add_schedulable(this);
71 }
72
73 Schedulable::~Schedulable()
74 {
75 scheduler.remove_schedulable(this);
76 }
77
78 std::uint64_t Schedulable::now()
79 {
80 return scheduler.now;
81 }
82
83}