1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
|
/*
* --- GSMP-COPYRIGHT-NOTE-BEGIN ---
*
* This copyright note is auto-generated by ./scripts/Create-CopyPatch.
* Please add additional copyright information _after_ the line containing
* the GSMP-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by
* the ./scripts/Create-CopyPatch script. Do not edit this copyright text!
*
* GSMP: utility/src/Timer.cc
* Copyright (C) 2018 René Rebe, ExactCODE GmbH; Germany.
* Copyright (C) 2000 - 2010 Valentin Ziegler and René Rebe
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2. A copy of the GNU General
* Public License can be found in the file LICENSE.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANT-
* ABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* --- GSMP-COPYRIGHT-NOTE-END ---
*/
/*
* Alternatively, commercial licensing options are available from the
* copyright holder ExactCODE GmbH Germany.
*/
#include "Timer.hh"
#include <sys/types.h>
#include <sys/stat.h>
#ifdef _WIN32
#include <windows.h> // Sleep()
#else
#include <unistd.h>
#endif
#include <iostream>
#ifndef _WIN32
Utility::TickTimer::TickTimer ()
{
times (&m_times);
}
void Utility::TickTimer::Reset ()
{
times (&m_times);
}
uint64_t Utility::TickTimer::Delta () const
{
tms t_times;
times (&t_times);
return t_times.tms_utime - m_times.tms_utime;
}
uint64_t Utility::TickTimer::Value () const
{
tms t_times;
times (&t_times);
return t_times.tms_utime;
}
uint64_t Utility::TickTimer::PerSecond () const
{
return sysconf (_SC_CLK_TCK);
}
#endif
// ---
#if 0 /* dead code */
Utility::TimebaseTimer::TimebaseTimer ()
{
start_tick = Value ();
}
void Utility::TimebaseTimer::Reset ()
{
start_tick = Value ();
}
uint64_t Utility::TimebaseTimer::Delta () const
{
return Value () - start_tick;
}
uint64_t Utility::TimebaseTimer::Value () const
{
#if defined(__i386__) || defined(_MSC_VER)
#ifdef _MSC_VER
#if _M_X64
return __rdtsc();
#else
uint32_t lo, hi;
__asm rdtsc
__asm mov lo, eax
__asm mov hi, edx
return ((uint64_t)hi << 32) | lo;
#endif
#else
uint64_t x;
__asm__ __volatile__ (".byte 0x0f, 0x31" : "=A" (x));
return x;
#endif
#elif defined(__x86_64__)
uint32_t hi, lo;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
return ((uint64_t)hi << 32) | lo;
#elif defined(__powerpc64__)
uint64_t x;
__asm__ __volatile__ (
"\tmftb %0"
: "=r"(x)
);
return x;
#elif defined(__powerpc__) || defined(__ppc__)
uint32_t hi, lo, tmp;
__asm__ __volatile__ (
"0: \n"
"\tmftbu %0 \n"
"\tmftb %1 \n"
"\tmftbu %2 \n"
"\tcmpw %2,%0 \n"
"\tbne 0b \n"
: "=r"(hi),"=r"(lo),"=r"(tmp)
);
return ((uint64_t)hi << 32) | lo;
#elif defined(__sparc_v9__)
#ifdef __LP64__
uint64_t ticks;
__asm__ volatile(
"rd %%tick, %0\n"
: "=r" (ticks) // : "0" (ticks)
);
return ticks;
#else
uint32_t hi, lo;
__asm__ volatile(
"rd %%tick,%%g3\n"
"\tor %%g3,0,%0\n" // lower bits
"\tsrlx %%g3,32,%%g3\n"
"\tor %%g3,0,%1" // higher bits
: "=r" (lo), "=r" (hi)
);
return ((uint64_t)hi << 32) | lo;
#endif
#elif defined(__mips__)
unsigned int ticks;
__asm__ __volatile__ ("dmfc0 %0,$9" : "=r" (ticks));
return ticks;
#elif defined(__ia64__)
unsigned int ticks;
__asm__ __volatile__ ("mov %0=ar.itc ;;" : "=rO" (ticks));
return ticks;
#elif defined(__bfin__)
unsigned int ticks;
__asm__ __volatile__ ("%0 = CYCLES;\n\t" : "=&d" (ticks) : : "R1");
return ticks
#else
// TODO (at least): Alpha, ARM, AVR32, SuperH, ...
#warning "No CPU timebase read implemented for this architecture, yet!"
return 0;
#endif
}
uint64_t Utility::TimebaseTimer::PerSecond () const
{
static uint64_t per_second = 0;
// meassure, not yet very accurate, depends on a exact 1s schedule of the OS
if (!per_second) {
uint64_t s1 = Value ();
#ifndef _WIN32
sleep (1);
#else
Sleep (1000);
#endif
uint64_t s2 = Value ();
per_second = s2 - s1;
}
return per_second;
}
#endif
|