root.cc revision 8232
1695SN/A/* 21762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 3695SN/A * Copyright (c) 2011 Advanced Micro Devices 4695SN/A * All rights reserved. 5695SN/A * 6695SN/A * Redistribution and use in source and binary forms, with or without 7695SN/A * modification, are permitted provided that the following conditions are 8695SN/A * met: redistributions of source code must retain the above copyright 9695SN/A * notice, this list of conditions and the following disclaimer; 10695SN/A * redistributions in binary form must reproduce the above copyright 11695SN/A * notice, this list of conditions and the following disclaimer in the 12695SN/A * documentation and/or other materials provided with the distribution; 13695SN/A * neither the name of the copyright holders nor the names of its 14695SN/A * contributors may be used to endorse or promote products derived from 15695SN/A * this software without specific prior written permission. 16695SN/A * 17695SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18695SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19695SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20695SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21695SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22695SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23695SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24695SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25695SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26695SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 272665Ssaidi@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282665Ssaidi@eecs.umich.edu * 29695SN/A * Authors: Nathan Binkert 30695SN/A * Steve Reinhardt 31873SN/A * Gabe Black 32873SN/A */ 33873SN/A 34873SN/A#include "base/misc.hh" 35695SN/A#include "debug/TimeSync.hh" 362621SN/A#include "sim/root.hh" 37695SN/A 38695SN/ARoot *Root::_root = NULL; 39695SN/A 40695SN/A/* 41695SN/A * This function is called periodically by an event in M5 and ensures that 42695SN/A * at least as much real time has passed between invocations as simulated time. 43695SN/A * If not, the function either sleeps, or if the difference is small enough 44695SN/A * spin waits. 45695SN/A */ 46695SN/Avoid 47695SN/ARoot::timeSync() 48695SN/A{ 49695SN/A Time cur_time, diff, period = timeSyncPeriod(); 50695SN/A 51695SN/A do { 52695SN/A cur_time.setTimer(); 53695SN/A diff = cur_time - lastTime; 54695SN/A Time remainder = period - diff; 55695SN/A if (diff < period && remainder > _spinThreshold) { 56695SN/A DPRINTF(TimeSync, "Sleeping to sync with real time.\n"); 57695SN/A // Sleep until the end of the period, or until a signal. 58695SN/A sleep(remainder); 59695SN/A // Refresh the current time. 60695SN/A cur_time.setTimer(); 61695SN/A } 62695SN/A } while (diff < period); 63695SN/A lastTime = cur_time; 64695SN/A schedule(&syncEvent, curTick() + _periodTick); 65695SN/A} 66695SN/A 67695SN/Avoid 68695SN/ARoot::timeSyncEnable(bool en) 69695SN/A{ 70729SN/A if (en == _enabled) 71695SN/A return; 72695SN/A _enabled = en; 73695SN/A if (_enabled) { 74695SN/A // Get event going. 75695SN/A Tick periods = ((curTick() + _periodTick - 1) / _periodTick); 76695SN/A Tick nextPeriod = periods * _periodTick; 77695SN/A schedule(&syncEvent, nextPeriod); 78695SN/A } else { 79695SN/A // Stop event. 80695SN/A deschedule(&syncEvent); 81695SN/A } 82695SN/A} 83695SN/A 84695SN/A/// Configure the period for time sync events. 85695SN/Avoid 86695SN/ARoot::timeSyncPeriod(Time newPeriod) 87695SN/A{ 88695SN/A bool en = timeSyncEnabled(); 89695SN/A _period = newPeriod; 90695SN/A _periodTick = _period.getTick(); 91695SN/A timeSyncEnable(en); 92695SN/A} 93695SN/A 94695SN/A/// Set the threshold for time remaining to spin wait. 95695SN/Avoid 96695SN/ARoot::timeSyncSpinThreshold(Time newThreshold) 97695SN/A{ 98695SN/A bool en = timeSyncEnabled(); 99695SN/A _spinThreshold = newThreshold; 100695SN/A timeSyncEnable(en); 101695SN/A} 102695SN/A 103695SN/ARoot::Root(RootParams *p) : SimObject(p), _enabled(false), 104695SN/A _periodTick(p->time_sync_period), syncEvent(this) 105695SN/A{ 106695SN/A _period.setTick(p->time_sync_period); 107695SN/A _spinThreshold.setTick(p->time_sync_spin_threshold); 108695SN/A 109695SN/A assert(_root == NULL); 110695SN/A _root = this; 111695SN/A lastTime.setTimer(); 112695SN/A} 113695SN/A 114695SN/Avoid 115695SN/ARoot::initState() 116695SN/A{ 117695SN/A timeSyncEnable(params()->time_sync_enable); 118695SN/A} 119695SN/A 120695SN/Avoid 121695SN/ARoot::loadState(Checkpoint *cp) 122695SN/A{ 123695SN/A timeSyncEnable(params()->time_sync_enable); 124695SN/A} 125695SN/A 126695SN/ARoot * 127695SN/ARootParams::create() 128695SN/A{ 129695SN/A static bool created = false; 130695SN/A if (created) 131695SN/A panic("only one root object allowed!"); 1321395SN/A 133695SN/A created = true; 134695SN/A 135695SN/A return new Root(this); 136695SN/A} 137695SN/A