drain.cc (10910:32f3d1c454ec) drain.cc (10912:b99a6662d7c2)
1/*
2 * Copyright (c) 2012, 2015 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 24 unchanged lines hidden (view full) ---

33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Andreas Sandberg
38 */
39
40#include "sim/drain.hh"
1/*
2 * Copyright (c) 2012, 2015 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 24 unchanged lines hidden (view full) ---

33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Andreas Sandberg
38 */
39
40#include "sim/drain.hh"
41
42#include "base/misc.hh"
43#include "base/trace.hh"
44#include "debug/Drain.hh"
41#include "sim/sim_exit.hh"
42
45#include "sim/sim_exit.hh"
46
47DrainManager DrainManager::_instance;
48
43DrainManager::DrainManager()
49DrainManager::DrainManager()
44 : _count(0)
50 : _count(0),
51 _state(DrainState::Running)
45{
46}
47
48DrainManager::~DrainManager()
49{
50}
51
52{
53}
54
55DrainManager::~DrainManager()
56{
57}
58
59bool
60DrainManager::tryDrain()
61{
62 panic_if(_state == DrainState::Drained,
63 "Trying to drain a drained system\n");
64
65 panic_if(_count != 0,
66 "Drain counter must be zero at the start of a drain cycle\n");
67
68 DPRINTF(Drain, "Trying to drain %u objects.\n", drainableCount());
69 _state = DrainState::Draining;
70 for (auto *obj : _allDrainable)
71 _count += obj->drain(&_instance);
72
73 if (_count == 0) {
74 DPRINTF(Drain, "Drain done.\n");
75 _state = DrainState::Drained;
76 return true;
77 } else {
78 DPRINTF(Drain, "Need another drain cycle. %u/%u objects not ready.\n",
79 _count, drainableCount());
80 return false;
81 }
82}
83
52void
84void
53DrainManager::drainCycleDone()
85DrainManager::resume()
54{
86{
55 exitSimLoop("Finished drain", 0);
87 panic_if(_state == DrainState::Running,
88 "Trying to resume a system that is already running\n");
89
90 warn_if(_state == DrainState::Draining,
91 "Resuming a system that isn't fully drained, this is untested and "
92 "likely to break\n");
93
94 panic_if(_count != 0,
95 "Resume called in the middle of a drain cycle. %u objects "
96 "left to drain.\n", _count);
97
98 DPRINTF(Drain, "Resuming %u objects.\n", drainableCount());
99 _state = DrainState::Running;
100 for (auto *obj : _allDrainable)
101 obj->drainResume();
56}
57
102}
103
104void
105DrainManager::preCheckpointRestore()
106{
107 panic_if(_state != DrainState::Running,
108 "preCheckpointRestore() called on a system that isn't in the "
109 "Running state.\n");
58
110
111 DPRINTF(Drain, "Applying pre-restore fixes to %u objects.\n",
112 drainableCount());
113 _state = DrainState::Drained;
114 for (auto *obj : _allDrainable)
115 obj->_drainState = DrainState::Drained;
116}
59
117
118void
119DrainManager::signalDrainDone()
120{
121 if (--_count == 0) {
122 DPRINTF(Drain, "All %u objects drained..\n", drainableCount());
123 exitSimLoop("Finished drain", 0);
124 }
125}
126
127
128void
129DrainManager::registerDrainable(Drainable *obj)
130{
131 std::lock_guard<std::mutex> lock(globalLock);
132 _allDrainable.insert(obj);
133}
134
135void
136DrainManager::unregisterDrainable(Drainable *obj)
137{
138 std::lock_guard<std::mutex> lock(globalLock);
139 _allDrainable.erase(obj);
140}
141
142size_t
143DrainManager::drainableCount() const
144{
145 std::lock_guard<std::mutex> lock(globalLock);
146 return _allDrainable.size();
147}
148
149
150
60Drainable::Drainable()
151Drainable::Drainable()
61 : _drainState(DrainState::Running)
152 : _drainManager(DrainManager::instance()),
153 _drainState(DrainState::Running)
62{
154{
155 _drainManager.registerDrainable(this);
63}
64
65Drainable::~Drainable()
66{
156}
157
158Drainable::~Drainable()
159{
160 _drainManager.unregisterDrainable(this);
67}
68
69void
70Drainable::drainResume()
71{
72 _drainState = DrainState::Running;
73}
161}
162
163void
164Drainable::drainResume()
165{
166 _drainState = DrainState::Running;
167}