ReactOS 0.4.16-dev-852-gcfcc8d8
clock.cpp
Go to the documentation of this file.
1//
2// clock.cpp
3//
4// Copyright (c) Microsoft Corporation. All rights reserved.
5//
6// The clock() function, which calculates the amount of elapsed time since the
7// process started execution.
8//
10#include <sys/timeb.h>
11#include <sys/types.h>
12
13
14
15// The source frequency of the performance counter and the counter value at
16// process startup, in the source frequency.
17static long long source_frequency;
18static long long start_count;
19
20
21
22// Scales a 64-bit counter from the QueryPerformanceCounter frequency to the
23// clock() frequency defined by CLOCKS_PER_SEC. This is the same algorithm as
24// is used internally by QueryPerformanceCounter to deal with frequency changes.
25static long long scale_count(long long count)
26{
27 // Convert the count to seconds and multiply this by the destination frequency:
28 long long scaled_count = (count / source_frequency) * CLOCKS_PER_SEC;
29
30 // To reduce error introduced by scaling using integer division, separately
31 // handle the remainder from the above division by multiplying the left-over
32 // counter by the destination frequency, then diviting by the input frequency:
34
35 scaled_count += (count * CLOCKS_PER_SEC) / source_frequency;
36
37 return scaled_count;
38}
39
40
41
42// This function initializes the global start_count variable when the CRT is
43// initialized. This initializer always runs in the CRT DLL; it only runs in
44// the static CRT if this object file is linked into the module, which will only
45// happen if some user code calls clock().
47{
48 LARGE_INTEGER local_frequency;
49 LARGE_INTEGER local_start_count;
50 if (!QueryPerformanceFrequency(&local_frequency) ||
51 !QueryPerformanceCounter(&local_start_count) ||
52 local_frequency.QuadPart == 0)
53 {
55 start_count = -1;
56 return 0;
57 }
58
59 source_frequency = local_frequency.QuadPart;
60 start_count = local_start_count.QuadPart;
61
62 return 0;
63}
64
65_CRT_LINKER_FORCE_INCLUDE(__acrt_clock_initializer);
66
67// Calculates and returns the amount of elapsed time since the process started
68// execution. During CRT initialization, the 'start_count' global variable is
69// initialized to the current tick count; subsequent calls to clock() get the
70// new tick count and subtract the 'start_count' from it.
71//
72// The return value is the number of CLK_TCKs that have elapsed (milliseconds).
73// On failure, -1 is returned.
74extern "C" clock_t __cdecl clock()
75{
76 if (start_count == -1)
77 return -1;
78
79 LARGE_INTEGER current_count;
80 if (!QueryPerformanceCounter(&current_count))
81 return -1;
82
83 long long const result = current_count.QuadPart - start_count;
84 if (result < 0)
85 return -1;
86
87 long long const scaled_result = scale_count(result);
88
89 // Per C11 7.27.2.1 ("The clock function")/3, "If the processor time used...
90 // cannot be represented, the function returns the value (clock_t)(-1)."
91 if (scaled_result > LONG_MAX)
92 return -1;
93
94 return static_cast<clock_t>(scaled_result);
95}
#define __cdecl
Definition: accygwin.h:79
static long long start_count
Definition: clock.cpp:18
int __cdecl __acrt_initialize_clock()
Definition: clock.cpp:46
static long long source_frequency
Definition: clock.cpp:17
static long long scale_count(long long count)
Definition: clock.cpp:25
clock_t __cdecl clock()
Definition: clock.cpp:74
#define _CRT_LINKER_FORCE_INCLUDE(name)
BOOL WINAPI QueryPerformanceFrequency(OUT PLARGE_INTEGER lpFrequency)
Definition: perfcnt.c:45
BOOL WINAPI QueryPerformanceCounter(OUT PLARGE_INTEGER lpPerformanceCount)
Definition: perfcnt.c:23
__kernel_clock_t clock_t
Definition: linux.h:257
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint64EXT * result
Definition: glext.h:11304
#define LONG_MAX
Definition: intsafe.h:154
#define CLOCKS_PER_SEC
Definition: time.h:81
LONGLONG QuadPart
Definition: typedefs.h:114