/
SystemState.cpp
90 lines (84 loc) · 2.47 KB
/
SystemState.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Copyright (c) 2011, Richard Osborne, All rights reserved
// This software is freely distributable under a derivative of the
// University of Illinois/NCSA Open Source License posted in
// LICENSE.txt and at <http://github.xcore.com/>
#include "SystemState.h"
#include "Node.h"
#include "Core.h"
SystemState::~SystemState()
{
for (std::vector<Node*>::iterator it = nodes.begin(), e = nodes.end();
it != e; ++it) {
delete *it;
}
}
void SystemState::addNode(std::auto_ptr<Node> n)
{
n->setParent(this);
nodes.push_back(n.get());
n.release();
}
ThreadState *SystemState::deschedule(ThreadState ¤t)
{
assert(¤t == currentThread);
//std::cout << "Deschedule " << current->id() << "\n";
current.waiting() = true;
currentThread = 0;
handleNonThreads();
if (scheduler.empty()) {
Tracer::get().noRunnableThreads(*this);
current.pc = current.getParent().getNoThreadsAddr();
current.waiting() = false;
currentThread = ¤t;
return ¤t;
}
ThreadState &next = static_cast<ThreadState&>(scheduler.front());
currentThread = &next;
scheduler.pop();
return &next;
}
void SystemState::
completeEvent(ThreadState &t, EventableResource &res, bool interrupt)
{
if (interrupt) {
t.regs[SSR] = t.sr.to_ulong();
t.regs[SPC] = t.getParent().targetPc(t.pc);
t.regs[SED] = t.regs[ED];
t.ieble() = false;
t.inint() = true;
t.ink() = true;
} else {
t.inenb() = 0;
}
t.eeble() = false;
// EventableResource::completeEvent sets the ED and PC.
res.completeEvent();
if (Tracer::get().getTracingEnabled()) {
if (interrupt) {
Tracer::get().interrupt(t, res, t.getParent().targetPc(t.pc),
t.regs[SSR], t.regs[SPC], t.regs[SED],
t.regs[ED]);
} else {
Tracer::get().event(t, res, t.getParent().targetPc(t.pc), t.regs[ED]);
}
}
}
ChanEndpoint *SystemState::getChanendDest(ResourceID ID)
{
unsigned coreID = ID.node();
// TODO build lookup map.
for (std::vector<Node*>::iterator it = nodes.begin(), e = nodes.end();
it != e; ++it) {
const std::vector<Core*> &cores = (*it)->getCores();
for (std::vector<Core*>::const_iterator it2 = cores.begin(),
e2 = cores.end(); it2 != e2; ++it2) {
if ((*it2)->getCoreID() == coreID) {
ChanEndpoint *result;
bool isLocal = (*it2)->getLocalChanendDest(ID, result);
assert(isLocal);
return result;
}
}
}
return 0;
}