timer.hh revision 9651
19651SAndreas.Sandberg@ARM.com/* 29651SAndreas.Sandberg@ARM.com * Copyright (c) 2012 ARM Limited 39651SAndreas.Sandberg@ARM.com * All rights reserved 49651SAndreas.Sandberg@ARM.com * 59651SAndreas.Sandberg@ARM.com * The license below extends only to copyright in the software and shall 69651SAndreas.Sandberg@ARM.com * not be construed as granting a license to any other intellectual 79651SAndreas.Sandberg@ARM.com * property including but not limited to intellectual property relating 89651SAndreas.Sandberg@ARM.com * to a hardware implementation of the functionality of the software 99651SAndreas.Sandberg@ARM.com * licensed hereunder. You may use the software subject to the license 109651SAndreas.Sandberg@ARM.com * terms below provided that you ensure that this notice is replicated 119651SAndreas.Sandberg@ARM.com * unmodified and in its entirety in all distributions of the software, 129651SAndreas.Sandberg@ARM.com * modified or unmodified, in source code or in binary form. 139651SAndreas.Sandberg@ARM.com * 149651SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without 159651SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are 169651SAndreas.Sandberg@ARM.com * met: redistributions of source code must retain the above copyright 179651SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer; 189651SAndreas.Sandberg@ARM.com * redistributions in binary form must reproduce the above copyright 199651SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer in the 209651SAndreas.Sandberg@ARM.com * documentation and/or other materials provided with the distribution; 219651SAndreas.Sandberg@ARM.com * neither the name of the copyright holders nor the names of its 229651SAndreas.Sandberg@ARM.com * contributors may be used to endorse or promote products derived from 239651SAndreas.Sandberg@ARM.com * this software without specific prior written permission. 249651SAndreas.Sandberg@ARM.com * 259651SAndreas.Sandberg@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 269651SAndreas.Sandberg@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 279651SAndreas.Sandberg@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 289651SAndreas.Sandberg@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 299651SAndreas.Sandberg@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 309651SAndreas.Sandberg@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 319651SAndreas.Sandberg@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 329651SAndreas.Sandberg@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 339651SAndreas.Sandberg@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 349651SAndreas.Sandberg@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 359651SAndreas.Sandberg@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 369651SAndreas.Sandberg@ARM.com * 379651SAndreas.Sandberg@ARM.com * Authors: Andreas Sandberg 389651SAndreas.Sandberg@ARM.com */ 399651SAndreas.Sandberg@ARM.com 409651SAndreas.Sandberg@ARM.com#ifndef __CPU_KVM_TIMER_HH__ 419651SAndreas.Sandberg@ARM.com#define __CPU_KVM_TIMER_HH__ 429651SAndreas.Sandberg@ARM.com 439651SAndreas.Sandberg@ARM.com#include <ctime> 449651SAndreas.Sandberg@ARM.com 459651SAndreas.Sandberg@ARM.com#include "sim/core.hh" 469651SAndreas.Sandberg@ARM.com 479651SAndreas.Sandberg@ARM.com/** 489651SAndreas.Sandberg@ARM.com * Timer functions to interrupt VM execution after a number of 499651SAndreas.Sandberg@ARM.com * simulation ticks. The timer allows scaling of the host time to take 509651SAndreas.Sandberg@ARM.com * performance differences between the simulated and real CPU into 519651SAndreas.Sandberg@ARM.com * account. 529651SAndreas.Sandberg@ARM.com * 539651SAndreas.Sandberg@ARM.com * The performance scaling factor is ratio between the target's CPI 549651SAndreas.Sandberg@ARM.com * and the host's CPI. It is larger than 1 if the host is faster than 559651SAndreas.Sandberg@ARM.com * the target and lower than 1 if it is slower. 569651SAndreas.Sandberg@ARM.com * 579651SAndreas.Sandberg@ARM.com * When the timer times out, it sends a signal to the thread that 589651SAndreas.Sandberg@ARM.com * started the timer. The signal forces KVM to drop out of the system 599651SAndreas.Sandberg@ARM.com * call that started the guest and hands control to gem5. 609651SAndreas.Sandberg@ARM.com */ 619651SAndreas.Sandberg@ARM.comclass BaseKvmTimer 629651SAndreas.Sandberg@ARM.com{ 639651SAndreas.Sandberg@ARM.com public: 649651SAndreas.Sandberg@ARM.com /** 659651SAndreas.Sandberg@ARM.com * Setup basic timer functionality shared by all timer 669651SAndreas.Sandberg@ARM.com * implementations. 679651SAndreas.Sandberg@ARM.com * 689651SAndreas.Sandberg@ARM.com * @param signo Signal to deliver 699651SAndreas.Sandberg@ARM.com * @param hostFactor Performance scaling factor 709651SAndreas.Sandberg@ARM.com * @param hostFreq Clock frequency of the host 719651SAndreas.Sandberg@ARM.com */ 729651SAndreas.Sandberg@ARM.com BaseKvmTimer(int signo, float hostFactor, Tick hostFreq) 739651SAndreas.Sandberg@ARM.com : signo(signo), _resolution(0), 749651SAndreas.Sandberg@ARM.com hostFactor(hostFactor), hostFreq(hostFreq) {}; 759651SAndreas.Sandberg@ARM.com virtual ~BaseKvmTimer() {}; 769651SAndreas.Sandberg@ARM.com 779651SAndreas.Sandberg@ARM.com /** 789651SAndreas.Sandberg@ARM.com * Arm the timer so that it fires after a certain number of ticks. 799651SAndreas.Sandberg@ARM.com * 809651SAndreas.Sandberg@ARM.com * @note A timer implementation is free to convert between 819651SAndreas.Sandberg@ARM.com * simulation ticks and virtualized time using any method it 829651SAndreas.Sandberg@ARM.com * chooses. The accuracy of the timer therefore depends on what it 839651SAndreas.Sandberg@ARM.com * measures, an accurate timer implementation should measure the 849651SAndreas.Sandberg@ARM.com * number of cycles or instructions executed in the guest. If such 859651SAndreas.Sandberg@ARM.com * counters are unavailable, it may fallback to wall clock time. 869651SAndreas.Sandberg@ARM.com * 879651SAndreas.Sandberg@ARM.com * @param ticks Number of ticks until the timer fires 889651SAndreas.Sandberg@ARM.com */ 899651SAndreas.Sandberg@ARM.com virtual void arm(Tick ticks) = 0; 909651SAndreas.Sandberg@ARM.com /** 919651SAndreas.Sandberg@ARM.com * Disarm the timer. 929651SAndreas.Sandberg@ARM.com * 939651SAndreas.Sandberg@ARM.com * When this method has returned, the timer may no longer deliver 949651SAndreas.Sandberg@ARM.com * signals upon timeout. 959651SAndreas.Sandberg@ARM.com */ 969651SAndreas.Sandberg@ARM.com virtual void disarm() = 0; 979651SAndreas.Sandberg@ARM.com 989651SAndreas.Sandberg@ARM.com /** 999651SAndreas.Sandberg@ARM.com * Determine the resolution of the timer in ticks. This method is 1009651SAndreas.Sandberg@ARM.com * mainly used to determine the smallest number of ticks the timer 1019651SAndreas.Sandberg@ARM.com * can wait before triggering a signal. 1029651SAndreas.Sandberg@ARM.com * 1039651SAndreas.Sandberg@ARM.com * @return Minimum number of ticks the timer can resolve 1049651SAndreas.Sandberg@ARM.com */ 1059651SAndreas.Sandberg@ARM.com Tick resolution() { 1069651SAndreas.Sandberg@ARM.com if (_resolution == 0) 1079651SAndreas.Sandberg@ARM.com _resolution = calcResolution(); 1089651SAndreas.Sandberg@ARM.com return _resolution; 1099651SAndreas.Sandberg@ARM.com } 1109651SAndreas.Sandberg@ARM.com 1119651SAndreas.Sandberg@ARM.com /** 1129651SAndreas.Sandberg@ARM.com * Convert cycles executed on the host into Ticks executed in the 1139651SAndreas.Sandberg@ARM.com * simulator. Scales the results using the hostFactor to take CPU 1149651SAndreas.Sandberg@ARM.com * performance differences into account. 1159651SAndreas.Sandberg@ARM.com * 1169651SAndreas.Sandberg@ARM.com * @return Host cycles executed in VM converted to simulation ticks 1179651SAndreas.Sandberg@ARM.com */ 1189651SAndreas.Sandberg@ARM.com Tick ticksFromHostCycles(uint64_t cycles) { 1199651SAndreas.Sandberg@ARM.com return cycles * hostFactor * hostFreq; 1209651SAndreas.Sandberg@ARM.com } 1219651SAndreas.Sandberg@ARM.com 1229651SAndreas.Sandberg@ARM.com /** 1239651SAndreas.Sandberg@ARM.com * Convert nanoseconds executed on the host into Ticks executed in 1249651SAndreas.Sandberg@ARM.com * the simulator. Scales the results using the hostFactor to take 1259651SAndreas.Sandberg@ARM.com * CPU performance differences into account. 1269651SAndreas.Sandberg@ARM.com * 1279651SAndreas.Sandberg@ARM.com * @return Nanoseconds executed in VM converted to simulation ticks 1289651SAndreas.Sandberg@ARM.com */ 1299651SAndreas.Sandberg@ARM.com Tick ticksFromHostNs(uint64_t ns) { 1309651SAndreas.Sandberg@ARM.com return ns * hostFactor * SimClock::Float::ns; 1319651SAndreas.Sandberg@ARM.com } 1329651SAndreas.Sandberg@ARM.com 1339651SAndreas.Sandberg@ARM.com protected: 1349651SAndreas.Sandberg@ARM.com /** 1359651SAndreas.Sandberg@ARM.com * Calculate the timer resolution, used by resolution() which 1369651SAndreas.Sandberg@ARM.com * caches the result. 1379651SAndreas.Sandberg@ARM.com * 1389651SAndreas.Sandberg@ARM.com * @return Minimum number of ticks the timer can resolve 1399651SAndreas.Sandberg@ARM.com */ 1409651SAndreas.Sandberg@ARM.com virtual Tick calcResolution() = 0; 1419651SAndreas.Sandberg@ARM.com 1429651SAndreas.Sandberg@ARM.com /** 1439651SAndreas.Sandberg@ARM.com * Convert a time in simulator ticks to host nanoseconds. 1449651SAndreas.Sandberg@ARM.com * 1459651SAndreas.Sandberg@ARM.com * @return Simulation ticks converted into nanoseconds on the host 1469651SAndreas.Sandberg@ARM.com */ 1479651SAndreas.Sandberg@ARM.com uint64_t hostNs(Tick ticks) { 1489651SAndreas.Sandberg@ARM.com return ticks / (SimClock::Float::ns * hostFactor); 1499651SAndreas.Sandberg@ARM.com } 1509651SAndreas.Sandberg@ARM.com 1519651SAndreas.Sandberg@ARM.com /** 1529651SAndreas.Sandberg@ARM.com * Convert a time in simulator ticks to host cycles 1539651SAndreas.Sandberg@ARM.com * 1549651SAndreas.Sandberg@ARM.com * 1559651SAndreas.Sandberg@ARM.com * @return Simulation ticks converted into CPU cycles on the host 1569651SAndreas.Sandberg@ARM.com */ 1579651SAndreas.Sandberg@ARM.com uint64_t hostCycles(Tick ticks) { 1589651SAndreas.Sandberg@ARM.com return ticks / (hostFreq * hostFactor); 1599651SAndreas.Sandberg@ARM.com } 1609651SAndreas.Sandberg@ARM.com 1619651SAndreas.Sandberg@ARM.com /** Signal to deliver when the timer times out */ 1629651SAndreas.Sandberg@ARM.com int signo; 1639651SAndreas.Sandberg@ARM.com 1649651SAndreas.Sandberg@ARM.com private: 1659651SAndreas.Sandberg@ARM.com /** Cached resolution */ 1669651SAndreas.Sandberg@ARM.com mutable Tick _resolution; 1679651SAndreas.Sandberg@ARM.com 1689651SAndreas.Sandberg@ARM.com /** Performance scaling factor */ 1699651SAndreas.Sandberg@ARM.com float hostFactor; 1709651SAndreas.Sandberg@ARM.com /** Host frequency */ 1719651SAndreas.Sandberg@ARM.com Tick hostFreq; 1729651SAndreas.Sandberg@ARM.com}; 1739651SAndreas.Sandberg@ARM.com 1749651SAndreas.Sandberg@ARM.com/** 1759651SAndreas.Sandberg@ARM.com * Timer based on standard POSIX timers. The POSIX timer API supports 1769651SAndreas.Sandberg@ARM.com * several different clock with different characteristics. 1779651SAndreas.Sandberg@ARM.com * 1789651SAndreas.Sandberg@ARM.com * @note It might be tempting to use 1799651SAndreas.Sandberg@ARM.com * CLOCK_(THREAD|PROCESS)_CPUTIME_ID, however, this clock usually has 1809651SAndreas.Sandberg@ARM.com * much lower resolution than the real-time clocks. 1819651SAndreas.Sandberg@ARM.com */ 1829651SAndreas.Sandberg@ARM.comclass PosixKvmTimer : public BaseKvmTimer 1839651SAndreas.Sandberg@ARM.com{ 1849651SAndreas.Sandberg@ARM.com public: 1859651SAndreas.Sandberg@ARM.com /** 1869651SAndreas.Sandberg@ARM.com * @param signo Signal to deliver 1879651SAndreas.Sandberg@ARM.com * @param clockID ID of the clock to use 1889651SAndreas.Sandberg@ARM.com * @param hostFactor Performance scaling factor 1899651SAndreas.Sandberg@ARM.com * @param hostFreq Clock frequency of the host 1909651SAndreas.Sandberg@ARM.com */ 1919651SAndreas.Sandberg@ARM.com PosixKvmTimer(int signo, clockid_t clockID, 1929651SAndreas.Sandberg@ARM.com float hostFactor, Tick hostFreq); 1939651SAndreas.Sandberg@ARM.com ~PosixKvmTimer(); 1949651SAndreas.Sandberg@ARM.com 1959651SAndreas.Sandberg@ARM.com void arm(Tick ticks); 1969651SAndreas.Sandberg@ARM.com void disarm(); 1979651SAndreas.Sandberg@ARM.com 1989651SAndreas.Sandberg@ARM.com protected: 1999651SAndreas.Sandberg@ARM.com Tick calcResolution(); 2009651SAndreas.Sandberg@ARM.com 2019651SAndreas.Sandberg@ARM.com private: 2029651SAndreas.Sandberg@ARM.com clockid_t clockID; 2039651SAndreas.Sandberg@ARM.com timer_t timer; 2049651SAndreas.Sandberg@ARM.com}; 2059651SAndreas.Sandberg@ARM.com 2069651SAndreas.Sandberg@ARM.com#endif 207