timer.hh revision 9651:f551c8ad12a5
1/* 2 * Copyright (c) 2012 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 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 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#ifndef __CPU_KVM_TIMER_HH__ 41#define __CPU_KVM_TIMER_HH__ 42 43#include <ctime> 44 45#include "sim/core.hh" 46 47/** 48 * Timer functions to interrupt VM execution after a number of 49 * simulation ticks. The timer allows scaling of the host time to take 50 * performance differences between the simulated and real CPU into 51 * account. 52 * 53 * The performance scaling factor is ratio between the target's CPI 54 * and the host's CPI. It is larger than 1 if the host is faster than 55 * the target and lower than 1 if it is slower. 56 * 57 * When the timer times out, it sends a signal to the thread that 58 * started the timer. The signal forces KVM to drop out of the system 59 * call that started the guest and hands control to gem5. 60 */ 61class BaseKvmTimer 62{ 63 public: 64 /** 65 * Setup basic timer functionality shared by all timer 66 * implementations. 67 * 68 * @param signo Signal to deliver 69 * @param hostFactor Performance scaling factor 70 * @param hostFreq Clock frequency of the host 71 */ 72 BaseKvmTimer(int signo, float hostFactor, Tick hostFreq) 73 : signo(signo), _resolution(0), 74 hostFactor(hostFactor), hostFreq(hostFreq) {}; 75 virtual ~BaseKvmTimer() {}; 76 77 /** 78 * Arm the timer so that it fires after a certain number of ticks. 79 * 80 * @note A timer implementation is free to convert between 81 * simulation ticks and virtualized time using any method it 82 * chooses. The accuracy of the timer therefore depends on what it 83 * measures, an accurate timer implementation should measure the 84 * number of cycles or instructions executed in the guest. If such 85 * counters are unavailable, it may fallback to wall clock time. 86 * 87 * @param ticks Number of ticks until the timer fires 88 */ 89 virtual void arm(Tick ticks) = 0; 90 /** 91 * Disarm the timer. 92 * 93 * When this method has returned, the timer may no longer deliver 94 * signals upon timeout. 95 */ 96 virtual void disarm() = 0; 97 98 /** 99 * Determine the resolution of the timer in ticks. This method is 100 * mainly used to determine the smallest number of ticks the timer 101 * can wait before triggering a signal. 102 * 103 * @return Minimum number of ticks the timer can resolve 104 */ 105 Tick resolution() { 106 if (_resolution == 0) 107 _resolution = calcResolution(); 108 return _resolution; 109 } 110 111 /** 112 * Convert cycles executed on the host into Ticks executed in the 113 * simulator. Scales the results using the hostFactor to take CPU 114 * performance differences into account. 115 * 116 * @return Host cycles executed in VM converted to simulation ticks 117 */ 118 Tick ticksFromHostCycles(uint64_t cycles) { 119 return cycles * hostFactor * hostFreq; 120 } 121 122 /** 123 * Convert nanoseconds executed on the host into Ticks executed in 124 * the simulator. Scales the results using the hostFactor to take 125 * CPU performance differences into account. 126 * 127 * @return Nanoseconds executed in VM converted to simulation ticks 128 */ 129 Tick ticksFromHostNs(uint64_t ns) { 130 return ns * hostFactor * SimClock::Float::ns; 131 } 132 133 protected: 134 /** 135 * Calculate the timer resolution, used by resolution() which 136 * caches the result. 137 * 138 * @return Minimum number of ticks the timer can resolve 139 */ 140 virtual Tick calcResolution() = 0; 141 142 /** 143 * Convert a time in simulator ticks to host nanoseconds. 144 * 145 * @return Simulation ticks converted into nanoseconds on the host 146 */ 147 uint64_t hostNs(Tick ticks) { 148 return ticks / (SimClock::Float::ns * hostFactor); 149 } 150 151 /** 152 * Convert a time in simulator ticks to host cycles 153 * 154 * 155 * @return Simulation ticks converted into CPU cycles on the host 156 */ 157 uint64_t hostCycles(Tick ticks) { 158 return ticks / (hostFreq * hostFactor); 159 } 160 161 /** Signal to deliver when the timer times out */ 162 int signo; 163 164 private: 165 /** Cached resolution */ 166 mutable Tick _resolution; 167 168 /** Performance scaling factor */ 169 float hostFactor; 170 /** Host frequency */ 171 Tick hostFreq; 172}; 173 174/** 175 * Timer based on standard POSIX timers. The POSIX timer API supports 176 * several different clock with different characteristics. 177 * 178 * @note It might be tempting to use 179 * CLOCK_(THREAD|PROCESS)_CPUTIME_ID, however, this clock usually has 180 * much lower resolution than the real-time clocks. 181 */ 182class PosixKvmTimer : public BaseKvmTimer 183{ 184 public: 185 /** 186 * @param signo Signal to deliver 187 * @param clockID ID of the clock to use 188 * @param hostFactor Performance scaling factor 189 * @param hostFreq Clock frequency of the host 190 */ 191 PosixKvmTimer(int signo, clockid_t clockID, 192 float hostFactor, Tick hostFreq); 193 ~PosixKvmTimer(); 194 195 void arm(Tick ticks); 196 void disarm(); 197 198 protected: 199 Tick calcResolution(); 200 201 private: 202 clockid_t clockID; 203 timer_t timer; 204}; 205 206#endif 207