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 			return __builtin_ia32_rdtsc();
69 		#else
70 			return 0;
71 		#endif
72 	}
73 
counter()74 	int64_t Timer::counter()
75 	{
76 		#if defined(_WIN32)
77 			int64_t counter;
78 			QueryPerformanceCounter((LARGE_INTEGER*)&counter);
79 			return counter;
80 		#else
81 			timeval t;
82 			gettimeofday(&t, 0);
83 			return t.tv_sec * 1000000 + t.tv_usec;
84 		#endif
85 	}
86 
frequency()87 	int64_t Timer::frequency()
88 	{
89 		#if defined(_WIN32)
90 			int64_t frequency;
91 			QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);
92 			return frequency;
93 		#else
94 			return 1000000;   // gettimeofday uses microsecond resolution
95 		#endif
96 	}
97 }
98