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
38namespace sw
39{
40 Timer::Timer()
41 {
42 }
43
44 Timer::~Timer()
45 {
46 }
47
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
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": "=A" (tsc));
70 return tsc;
71 #else
72 return 0;
73 #endif
74 }
75
76 int64_t Timer::counter()
77 {
78 #if defined(_WIN32)
79 int64_t counter;
80 QueryPerformanceCounter((LARGE_INTEGER*)&counter);
81 return counter;
82 #else
83 timeval t;
84 gettimeofday(&t, 0);
85 return t.tv_sec * 1000000 + t.tv_usec;
86 #endif
87 }
88
89 int64_t Timer::frequency()
90 {
91 #if defined(_WIN32)
92 int64_t frequency;
93 QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);
94 return frequency;
95 #else
96 return 1000000; // gettimeofday uses microsecond resolution
97 #endif
98 }
99}
100