forked from xcore/tool_axe
-
Notifications
You must be signed in to change notification settings - Fork 1
/
SystemState.h
104 lines (88 loc) · 2.86 KB
/
SystemState.h
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// 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/>
#ifndef _SystemState_h_
#define _SystemState_h_
#include <vector>
#include <memory>
#include "Thread.h"
#include "RunnableQueue.h"
class Node;
class ChanEndpoint;
class SystemState {
std::vector<Node*> nodes;
RunnableQueue scheduler;
/// The currently executing runnable.
Runnable *currentRunnable;
PendingEvent pendingEvent;
bool stats;
void completeEvent(Thread &t, EventableResource &res, bool interrupt);
public:
typedef std::vector<Node*>::iterator node_iterator;
typedef std::vector<Node*>::const_iterator const_node_iterator;
SystemState() : currentRunnable(0), stats(false) {
pendingEvent.set = false;
}
~SystemState();
void finalize();
RunnableQueue &getScheduler() { return scheduler; }
void addNode(std::auto_ptr<Node> n);
void dump();
void enableStats() { stats = true; }
Runnable *getExecutingRunnable() {
return currentRunnable;
}
int run();
/// Schedule a thread.
void schedule(Thread &thread) {
thread.waiting() = false;
thread.pausedOn = 0;
scheduler.push(thread, thread.time);
}
void scheduleOther(Runnable &runnable, ticks_t time) {
scheduler.push(runnable, time);
}
/// Take an event on a thread. The thread must not be the current thread.
void takeEvent(Thread &thread, EventableResource &res, bool interrupt)
{
if (thread.waiting()) {
if (thread.pausedOn) {
thread.pausedOn->cancel();
}
schedule(thread);
}
completeEvent(thread, res, interrupt);
}
/// Take an event on the current thread.
/// \param CycleThread Whether to cycle the running thread after the
/// event is taken.
/// \return The new time and pc.
void takeEvent(Thread ¤t)
{
current.time = std::max(current.time, pendingEvent.time);
// TODO this is probably the wrong place for this.
current.waiting() = false;
completeEvent(current, *pendingEvent.res, pendingEvent.interrupt);
pendingEvent.set = false;
}
/// Sets a pending event on the current thread.
void setPendingEvent(EventableResource &res, ticks_t time, bool interrupt)
{
if (pendingEvent.set && pendingEvent.time <= time)
return;
pendingEvent.set = true;
pendingEvent.res = &res;
pendingEvent.interrupt = interrupt;
pendingEvent.time = time;
}
bool hasPendingEvent() const {
return pendingEvent.set;
}
node_iterator node_begin() { return nodes.begin(); }
node_iterator node_end() { return nodes.end(); }
const_node_iterator node_begin() const { return nodes.begin(); }
const_node_iterator node_end() const { return nodes.end(); }
int node_count() { return nodes.size(); }
};
#endif // _SystemState_h_