1 // =================================================================================================
2 // Copyright 2006 Adobe Systems Incorporated
3 // All Rights Reserved.
4 //
5 // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms
6 // of the Adobe license agreement accompanying it.
7 // =================================================================================================
8
9 #include "public/include/XMP_Environment.h"
10 #include "public/include/XMP_Const.h"
11
12 #include "source/PerfUtils.hpp"
13
14 #include <stdio.h>
15
16 #if XMP_WinBuild
17 #pragma warning ( disable : 4996 ) // '...' was declared deprecated
18 #endif
19
20 // =================================================================================================
21 // =================================================================================================
22
23 #if XMP_WinBuild
24
25 #pragma warning ( disable : 4800 ) // forcing bool to 0/1
26
GetTimerInfo()27 const char * PerfUtils::GetTimerInfo()
28 {
29 LARGE_INTEGER freq;
30 static char msgBuffer[1000];
31
32 bool ok = (bool) QueryPerformanceFrequency ( &freq );
33 if ( ! ok ) throw XMP_Error ( kXMPErr_ExternalFailure, "Failure from QueryPerformanceFrequency" );
34
35 if ( freq.HighPart != 0 ) {
36 return "Windows PerfUtils measures finer than nanoseconds, using the QueryPerformanceCounter() timer";
37 }
38
39 double rate = 1.0 / (double)freq.LowPart;
40 _snprintf ( msgBuffer, sizeof(msgBuffer),
41 "Windows PerfUtils measures %e second, using the QueryPerformanceCounter() timer", rate );
42 return msgBuffer;
43
44 } // PerfUtils::GetTimerInfo
45
46 // ------------------------------------------------------------------------------------------------
47
NoteThisMoment()48 PerfUtils::MomentValue PerfUtils::NoteThisMoment()
49 {
50 LARGE_INTEGER now;
51
52 bool ok = (bool) QueryPerformanceCounter ( &now );
53 if ( ! ok ) throw XMP_Error ( kXMPErr_ExternalFailure, "Failure from QueryPerformanceCounter" );
54 return now.QuadPart;
55
56 } // PerfUtils::NoteThisMoment
57
58 // ------------------------------------------------------------------------------------------------
59
GetElapsedSeconds(PerfUtils::MomentValue start,PerfUtils::MomentValue finish)60 double PerfUtils::GetElapsedSeconds ( PerfUtils::MomentValue start, PerfUtils::MomentValue finish )
61 {
62 LARGE_INTEGER freq;
63
64 bool ok = (bool) QueryPerformanceFrequency ( &freq );
65 if ( ! ok ) throw XMP_Error ( kXMPErr_ExternalFailure, "Failure from QueryPerformanceFrequency" );
66
67 const double scale = (double)freq.QuadPart;
68
69 const double elapsed = (double)(finish - start) / scale;
70 return elapsed;
71
72 } // PerfUtils::GetElapsedSeconds
73
74 #endif
75
76 // =================================================================================================
77
78 #if XMP_UNIXBuild
79
GetTimerInfo()80 const char * PerfUtils::GetTimerInfo()
81 {
82 return "UNIX PerfUtils measures nano seconds, using the POSIX clock_gettime() timer";
83 } // PerfUtils::GetTimerInfo
84
85 // ------------------------------------------------------------------------------------------------
86
NoteThisMoment()87 PerfUtils::MomentValue PerfUtils::NoteThisMoment()
88 {
89 MomentValue moment = kZeroMoment;
90 if ( clock_gettime( CLOCK_MONOTONIC, &moment ) != 0 )
91 throw XMP_Error( kXMPErr_ExternalFailure, "Failure from clock_gettime" );
92 return moment;
93 } // PerfUtils::NoteThisMoment
94
95 // ------------------------------------------------------------------------------------------------
96
GetElapsedSeconds(PerfUtils::MomentValue start,PerfUtils::MomentValue finish)97 double PerfUtils::GetElapsedSeconds ( PerfUtils::MomentValue start, PerfUtils::MomentValue finish )
98 {
99 double startInSeconds = start.tv_sec + start.tv_nsec / 1000000000.0;
100 double finishInSeconds = finish.tv_sec + finish.tv_nsec / 1000000000.0;
101 return finishInSeconds - startInSeconds;
102 } // PerfUtils::GetElapsedSeconds
103
104 #endif
105
106 // =================================================================================================
107
108 #if XMP_MacBuild | XMP_iOSBuild
109
110 #include <mach/mach.h>
111 #include <mach/mach_time.h>
112
GetTimerInfo()113 const char * PerfUtils::GetTimerInfo()
114 {
115 return "Mac PerfUtils measures nano seconds, using the mach_absolute_time() timer";
116 } // PerfUtils::GetTimerInfo
117
118 // ------------------------------------------------------------------------------------------------
119
NoteThisMoment()120 PerfUtils::MomentValue PerfUtils::NoteThisMoment()
121 {
122 return mach_absolute_time();
123 } // PerfUtils::NoteThisMoment
124
125 // ------------------------------------------------------------------------------------------------
126
GetElapsedSeconds(PerfUtils::MomentValue start,PerfUtils::MomentValue finish)127 double PerfUtils::GetElapsedSeconds ( PerfUtils::MomentValue start, PerfUtils::MomentValue finish )
128 {
129 static mach_timebase_info_data_t sTimebaseInfo;
130 static double sConversionFactor = 0.0;
131 // If this is the first time we've run, get the timebase.
132 // We can use denom == 0 to indicate that sTimebaseInfo is
133 // uninitialized because it makes no sense to have a zero
134 // denominator is a fraction.
135
136 if ( sTimebaseInfo.denom == 0 ) {
137 mach_timebase_info(&sTimebaseInfo);
138 sConversionFactor = ((double)sTimebaseInfo.denom / (double)sTimebaseInfo.numer);
139 sConversionFactor /= 1000000000.0;
140 }
141
142 return ( finish - start ) * sConversionFactor;
143 } // PerfUtils::GetElapsedSeconds
144
145 #endif
146
147
148