1 // Copyright 2019 The Dawn Authors
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 "utils/Timer.h"
16 
17 #include <CoreServices/CoreServices.h>
18 #include <mach/mach.h>
19 #include <mach/mach_time.h>
20 
21 namespace utils {
22 
23     class OSXTimer : public Timer {
24       public:
OSXTimer()25         OSXTimer() : Timer(), mRunning(false), mSecondCoeff(0) {
26         }
27 
28         ~OSXTimer() override = default;
29 
Start()30         void Start() override {
31             mStartTime = mach_absolute_time();
32             // Cache secondCoeff
33             GetSecondCoeff();
34             mRunning = true;
35         }
36 
Stop()37         void Stop() override {
38             mStopTime = mach_absolute_time();
39             mRunning = false;
40         }
41 
GetElapsedTime() const42         double GetElapsedTime() const override {
43             if (mRunning) {
44                 return mSecondCoeff * (mach_absolute_time() - mStartTime);
45             } else {
46                 return mSecondCoeff * (mStopTime - mStartTime);
47             }
48         }
49 
GetAbsoluteTime()50         double GetAbsoluteTime() override {
51             return GetSecondCoeff() * mach_absolute_time();
52         }
53 
54       private:
GetSecondCoeff()55         double GetSecondCoeff() {
56             // If this is the first time we've run, get the timebase.
57             if (mSecondCoeff == 0.0) {
58                 mach_timebase_info_data_t timebaseInfo;
59                 mach_timebase_info(&timebaseInfo);
60 
61                 mSecondCoeff = timebaseInfo.numer * (1.0 / 1000000000) / timebaseInfo.denom;
62             }
63 
64             return mSecondCoeff;
65         }
66 
67         bool mRunning;
68         uint64_t mStartTime;
69         uint64_t mStopTime;
70         double mSecondCoeff;
71     };
72 
CreateTimer()73     Timer* CreateTimer() {
74         return new OSXTimer();
75     }
76 
77 }  // namespace utils
78