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
|
#include "timing.h"
static clock_type_t g_clock_type = CPU_CLOCK;
int set_timing_clock_type(clock_type_t type)
{
// validate
if ((type != WALL_CLOCK) && (type != CPU_CLOCK))
{
return 0;
}
g_clock_type = type;
return 1;
}
clock_type_t get_timing_clock_type(void)
{
return g_clock_type;
}
#if !defined(_WINDOWS)
static long long gettimeofday_usec(void)
{
struct timeval tv;
long long rc;
#ifdef GETTIMEOFDAY_NO_TZ
gettimeofday(&tv);
#else
gettimeofday(&tv, (struct timezone *)NULL);
#endif
rc = tv.tv_sec;
rc = rc * 1000000 + tv.tv_usec;
return rc;
}
#endif
#if defined(_WINDOWS)
long long
tickcount(void)
{
LARGE_INTEGER li;
FILETIME ftCreate, ftExit, ftKernel, ftUser;
if (g_clock_type == CPU_CLOCK) {
GetThreadTimes(GetCurrentThread(), &ftCreate, &ftExit, &ftKernel, &ftUser);
li.LowPart = ftKernel.dwLowDateTime+ftUser.dwLowDateTime;
li.HighPart = ftKernel.dwHighDateTime+ftUser.dwHighDateTime;
} else if (g_clock_type == WALL_CLOCK) {
QueryPerformanceCounter(&li);
}
return li.QuadPart;
}
double
tickfactor(void)
{
LARGE_INTEGER li;
if (g_clock_type == WALL_CLOCK) {
if (QueryPerformanceFrequency(&li)) {
return 1.0 / li.QuadPart;
} else {
return 0.000001;
}
} else if (g_clock_type == CPU_CLOCK) {
return 0.0000001;
}
return 0.0000001; // for suppressing warning: all paths must return a value
}
#elif defined(_MACH)
long long
tickcount(void)
{
long long rc;
rc = 0;
if (g_clock_type == CPU_CLOCK) {
thread_basic_info_t tinfo_b;
thread_info_data_t tinfo_d;
mach_msg_type_number_t tinfo_cnt;
tinfo_cnt = THREAD_INFO_MAX;
thread_info(mach_thread_self(), THREAD_BASIC_INFO, (thread_info_t)tinfo_d, &tinfo_cnt);
tinfo_b = (thread_basic_info_t)tinfo_d;
if (!(tinfo_b->flags & TH_FLAGS_IDLE))
{
rc = (tinfo_b->user_time.seconds + tinfo_b->system_time.seconds);
rc = (rc * 1000000) + (tinfo_b->user_time.microseconds + tinfo_b->system_time.microseconds);
}
} else if (g_clock_type == WALL_CLOCK) {
rc = gettimeofday_usec();
}
return rc;
}
double
tickfactor(void)
{
return 0.000001;
}
#elif defined(_UNIX)
long long
tickcount(void)
{
long long rc;
rc = 0; // suppress "may be uninitialized" warning
if (g_clock_type == CPU_CLOCK) {
#if defined(USE_CLOCK_TYPE_CLOCKGETTIME)
struct timespec tp;
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp);
rc = tp.tv_sec;
rc = rc * 1000000000 + (tp.tv_nsec);
#elif (defined(USE_CLOCK_TYPE_RUSAGE) && defined(RUSAGE_WHO))
struct timeval tv;
struct rusage usage;
getrusage(RUSAGE_WHO, &usage);
rc = (usage.ru_utime.tv_sec + usage.ru_stime.tv_sec);
rc = (rc * 1000000) + (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec);
#endif
} else if (g_clock_type == WALL_CLOCK) {
rc = gettimeofday_usec();
}
return rc;
}
double
tickfactor(void)
{
if (g_clock_type == CPU_CLOCK) {
#if defined(USE_CLOCK_TYPE_CLOCKGETTIME)
return 0.000000001;
#elif defined(USE_CLOCK_TYPE_RUSAGE)
return 0.000001;
#endif
} else if (g_clock_type == WALL_CLOCK) {
return 0.000001;
}
return 1.0; // suppress "reached end of non-void function" warning
}
#endif /* *nix */
|