1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "Timer.hpp"
16 
17 #if !defined(__i386__) && defined(_M_IX86)
18 #	define __i386__ 1
19 #endif
20 
21 #if !defined(__x86_64__) && (defined(_M_AMD64) || defined(_M_X64))
22 #	define __x86_64__ 1
23 #endif
24 
25 #if defined(_WIN32)
26 #	ifndef WIN32_LEAN_AND_MEAN
27 #		define WIN32_LEAN_AND_MEAN
28 #	endif
29 #	include <windows.h>
30 #	include <intrin.h>
31 #else
32 #	include <sys/time.h>
33 #	if defined(__i386__) || defined(__x86_64__)
34 #		include <x86intrin.h>
35 #	endif
36 #endif
37 
38 namespace sw {
39 
Timer()40 Timer::Timer()
41 {
42 }
43 
~Timer()44 Timer::~Timer()
45 {
46 }
47 
seconds()48 double Timer::seconds()
49 {
50 #if defined(_WIN32)
51 	return (double)counter() / (double)frequency();
52 #else
53 	timeval t;
54 	gettimeofday(&t, 0);
55 	return (double)t.tv_sec + (double)t.tv_usec * 1.0e-6;
56 #endif
57 }
58 
ticks()59 int64_t Timer::ticks()
60 {
61 #if defined(_WIN32)
62 #	if defined(_M_ARM64)
63 	return _ReadStatusReg(ARM64_PMCCNTR_EL0);
64 #	else
65 	return __rdtsc();
66 #	endif
67 #elif defined(__i386__) || defined(__x86_64__)
68 	int64_t tsc;
69 	__asm volatile("rdtsc"
70 	               : "=A"(tsc));
71 	return tsc;
72 #else
73 	return 0;
74 #endif
75 }
76 
counter()77 int64_t Timer::counter()
78 {
79 #if defined(_WIN32)
80 	int64_t counter;
81 	QueryPerformanceCounter((LARGE_INTEGER *)&counter);
82 	return counter;
83 #else
84 	timeval t;
85 	gettimeofday(&t, 0);
86 	return t.tv_sec * 1000000 + t.tv_usec;
87 #endif
88 }
89 
frequency()90 int64_t Timer::frequency()
91 {
92 #if defined(_WIN32)
93 	int64_t frequency;
94 	QueryPerformanceFrequency((LARGE_INTEGER *)&frequency);
95 	return frequency;
96 #else
97 	return 1000000;  // gettimeofday uses microsecond resolution
98 #endif
99 }
100 
101 }  // namespace sw
102