drain.cc revision 10998:cd22d66592bf
11758SN/A/*
21762SN/A * Copyright (c) 2012, 2015 ARM Limited
31758SN/A * All rights reserved
41758SN/A *
51758SN/A * The license below extends only to copyright in the software and shall
61758SN/A * not be construed as granting a license to any other intellectual
71758SN/A * property including but not limited to intellectual property relating
81758SN/A * to a hardware implementation of the functionality of the software
91758SN/A * licensed hereunder.  You may use the software subject to the license
101758SN/A * terms below provided that you ensure that this notice is replicated
111758SN/A * unmodified and in its entirety in all distributions of the software,
121758SN/A * modified or unmodified, in source code or in binary form.
131758SN/A *
141758SN/A * Redistribution and use in source and binary forms, with or without
151758SN/A * modification, are permitted provided that the following conditions are
161758SN/A * met: redistributions of source code must retain the above copyright
171758SN/A * notice, this list of conditions and the following disclaimer;
181758SN/A * redistributions in binary form must reproduce the above copyright
191758SN/A * notice, this list of conditions and the following disclaimer in the
201758SN/A * documentation and/or other materials provided with the distribution;
211758SN/A * neither the name of the copyright holders nor the names of its
221758SN/A * contributors may be used to endorse or promote products derived from
231758SN/A * this software without specific prior written permission.
241758SN/A *
251758SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
261758SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
272665Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282665Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
292665Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
301758SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
312SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
322984Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33732SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
343565Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35732SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
362984Sgblack@eecs.umich.edu *
373536Sgblack@eecs.umich.edu * Authors: Andreas Sandberg
38732SN/A */
39732SN/A
401858SN/A#include "sim/drain.hh"
411717SN/A
422683Sktlim@umich.edu#include "base/misc.hh"
432680Sktlim@umich.edu#include "base/trace.hh"
44676SN/A#include "debug/Drain.hh"
452710Sstever@eecs.umich.edu#include "sim/sim_exit.hh"
462SN/A
475566Snate@binkert.orgDrainManager DrainManager::_instance;
485566Snate@binkert.org
491858SN/ADrainManager::DrainManager()
502SN/A    : _count(0),
512SN/A      _state(DrainState::Running)
522SN/A{
532SN/A}
542SN/A
552SN/ADrainManager::~DrainManager()
562680Sktlim@umich.edu{
572SN/A}
582680Sktlim@umich.edu
59190SN/Abool
602680Sktlim@umich.eduDrainManager::tryDrain()
612680Sktlim@umich.edu{
622114SN/A    panic_if(_state == DrainState::Drained,
633468Sgblack@eecs.umich.edu             "Trying to drain a drained system\n");
642700Sktlim@umich.edu
654172Ssaidi@eecs.umich.edu    panic_if(_count != 0,
662680Sktlim@umich.edu             "Drain counter must be zero at the start of a drain cycle\n");
672700Sktlim@umich.edu
682700Sktlim@umich.edu    DPRINTF(Drain, "Trying to drain %u objects.\n", drainableCount());
692SN/A    _state = DrainState::Draining;
702SN/A    for (auto *obj : _allDrainable)
712SN/A        _count += obj->dmDrain() == DrainState::Drained ? 0 : 1;
721133SN/A
73716SN/A    if (_count == 0) {
741133SN/A        DPRINTF(Drain, "Drain done.\n");
75716SN/A        _state = DrainState::Drained;
76716SN/A        return true;
77716SN/A    } else {
78716SN/A        DPRINTF(Drain, "Need another drain cycle. %u/%u objects not ready.\n",
79716SN/A                _count, drainableCount());
80716SN/A        return false;
814172Ssaidi@eecs.umich.edu    }
82716SN/A}
83716SN/A
844172Ssaidi@eecs.umich.eduvoid
85716SN/ADrainManager::resume()
86716SN/A{
874172Ssaidi@eecs.umich.edu    panic_if(_state == DrainState::Running,
88716SN/A             "Trying to resume a system that is already running\n");
89716SN/A
90716SN/A    warn_if(_state == DrainState::Draining,
91716SN/A            "Resuming a system that isn't fully drained, this is untested and "
92716SN/A            "likely to break\n");
93716SN/A
94716SN/A    panic_if(_count != 0,
951133SN/A             "Resume called in the middle of a drain cycle. %u objects "
96716SN/A             "left to drain.\n", _count);
97716SN/A
98716SN/A    DPRINTF(Drain, "Resuming %u objects.\n", drainableCount());
99716SN/A    _state = DrainState::Running;
100716SN/A    for (auto *obj : _allDrainable)
101716SN/A        obj->dmDrainResume();
102716SN/A}
103716SN/A
104716SN/Avoid
105716SN/ADrainManager::preCheckpointRestore()
106716SN/A{
107716SN/A    panic_if(_state != DrainState::Running,
1084172Ssaidi@eecs.umich.edu             "preCheckpointRestore() called on a system that isn't in the "
1094172Ssaidi@eecs.umich.edu             "Running state.\n");
1104172Ssaidi@eecs.umich.edu
1112147SN/A    DPRINTF(Drain, "Applying pre-restore fixes to %u objects.\n",
112716SN/A            drainableCount());
1134172Ssaidi@eecs.umich.edu    _state = DrainState::Drained;
114716SN/A    for (auto *obj : _allDrainable)
115716SN/A        obj->_drainState = DrainState::Drained;
116716SN/A}
117716SN/A
1181133SN/Avoid
119716SN/ADrainManager::signalDrainDone()
1201133SN/A{
121716SN/A    if (--_count == 0) {
122716SN/A        DPRINTF(Drain, "All %u objects drained..\n", drainableCount());
123739SN/A        exitSimLoop("Finished drain", 0);
124739SN/A    }
1252683Sktlim@umich.edu}
1262683Sktlim@umich.edu
127716SN/A
128716SN/Avoid
1292SN/ADrainManager::registerDrainable(Drainable *obj)
1302683Sktlim@umich.edu{
1312SN/A    std::lock_guard<std::mutex> lock(globalLock);
1323521Sgblack@eecs.umich.edu    _allDrainable.insert(obj);
1332147SN/A}
1342SN/A
1354172Ssaidi@eecs.umich.eduvoid
1362SN/ADrainManager::unregisterDrainable(Drainable *obj)
1372SN/A{
1382341SN/A    std::lock_guard<std::mutex> lock(globalLock);
1392341SN/A    _allDrainable.erase(obj);
1402SN/A}
1412SN/A
1422SN/Asize_t
1432154SN/ADrainManager::drainableCount() const
1442SN/A{
1452SN/A    std::lock_guard<std::mutex> lock(globalLock);
1462245SN/A    return _allDrainable.size();
1472245SN/A}
1482245SN/A
1495566Snate@binkert.org
1502245SN/A
1512245SN/ADrainable::Drainable()
1522245SN/A    : _drainManager(DrainManager::instance()),
1532245SN/A      _drainState(_drainManager.state())
1542245SN/A{
1555566Snate@binkert.org    _drainManager.registerDrainable(this);
1562245SN/A}
1572245SN/A
1584997Sgblack@eecs.umich.eduDrainable::~Drainable()
1594997Sgblack@eecs.umich.edu{
1604997Sgblack@eecs.umich.edu    _drainManager.unregisterDrainable(this);
1614997Sgblack@eecs.umich.edu}
1624997Sgblack@eecs.umich.edu
1634997Sgblack@eecs.umich.eduDrainState
1644997Sgblack@eecs.umich.eduDrainable::dmDrain()
1654997Sgblack@eecs.umich.edu{
1664997Sgblack@eecs.umich.edu    _drainState = DrainState::Draining;
1674997Sgblack@eecs.umich.edu    _drainState = drain();
1684997Sgblack@eecs.umich.edu    assert(_drainState == DrainState::Draining ||
1694997Sgblack@eecs.umich.edu           _drainState == DrainState::Drained);
1704997Sgblack@eecs.umich.edu
1715566Snate@binkert.org    return _drainState;
1724997Sgblack@eecs.umich.edu}
1734997Sgblack@eecs.umich.edu
1744997Sgblack@eecs.umich.eduvoid
1754997Sgblack@eecs.umich.eduDrainable::dmDrainResume()
1762159SN/A{
1773468Sgblack@eecs.umich.edu    panic_if(_drainState != DrainState::Drained,
1782159SN/A             "Trying to resume an object that hasn't been drained\n");
1795543Ssaidi@eecs.umich.edu
1802SN/A    _drainState = DrainState::Running;
1812SN/A    drainResume();
1823459Sgblack@eecs.umich.edu}
1833459Sgblack@eecs.umich.edu