File: pyi_floatclock.c

package info (click to toggle)
python-pyinstrument 5.1.1%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,624 kB
  • sloc: python: 6,713; ansic: 897; makefile: 46; sh: 26; javascript: 18
file content (102 lines) | stat: -rw-r--r-- 2,804 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include "pyi_floatclock.h"

#include <Python.h>
#include <time.h> // gettimeofday, clock()
#include <float.h> // DBL_MAX


/*
The windows implementations mostly stolen from timemodule.c
*/

#if defined(MS_WINDOWS) && !defined(__BORLANDC__)
#include <windows.h>

double pyi_monotonic_coarse_resolution(void)
{
    return DBL_MAX;
}

/* use QueryPerformanceCounter on Windows */

double pyi_floatclock(PYIFloatClockType timer)
{
    if (timer == PYI_FLOATCLOCK_MONOTONIC_COARSE) {
        warn_once("CLOCK_MONOTONIC_COARSE not available on this system.");
    }
    static LARGE_INTEGER ctrStart;
    static double divisor = 0.0;
    LARGE_INTEGER now;
    double diff;

    if (divisor == 0.0) {
        LARGE_INTEGER freq;
        QueryPerformanceCounter(&ctrStart);
        if (!QueryPerformanceFrequency(&freq) || freq.QuadPart == 0) {
            /* Unlikely to happen - this works on all intel
               machines at least!  Revert to clock() */
            return ((double)clock()) / CLOCKS_PER_SEC;
        }
        divisor = (double)freq.QuadPart;
    }
    QueryPerformanceCounter(&now);
    diff = (double)(now.QuadPart - ctrStart.QuadPart);
    return diff / divisor;
}

#else  /* !MS_WINDOWS */

#include <unistd.h>
#include <sys/time.h> // clock_gettime

static double SEC_PER_NSEC = 1e-9;
static double SEC_PER_USEC = 1e-6;

double pyi_monotonic_coarse_resolution(void)
{
#ifdef CLOCK_MONOTONIC_COARSE
    static double resolution = -1;
    if (resolution == -1) {
        struct timespec res;
        int success = clock_getres(CLOCK_MONOTONIC_COARSE, &res);
        if (success == 0) {
            resolution = res.tv_sec + res.tv_nsec * SEC_PER_NSEC;
        } else {
            // clock_getres failed, so let's set the resolution to something
            // so this timer is never used.
            resolution = DBL_MAX;
        }
    }
    return resolution;
#else
    return DBL_MAX;
#endif
}

double pyi_floatclock(PYIFloatClockType timer)
{
    // gets the current time in seconds, as quickly as possible.
#ifdef _POSIX_TIMERS
    struct timespec t;
    int res;
    if (timer == PYI_FLOATCLOCK_MONOTONIC_COARSE) {
# ifdef CLOCK_MONOTONIC_COARSE
        res = clock_gettime(CLOCK_MONOTONIC_COARSE, &t);
        if (res == 0) return t.tv_sec + t.tv_nsec * SEC_PER_NSEC;
# else
        warn_once("CLOCK_MONOTONIC_COARSE not available on this system.");
# endif
    }
# ifdef CLOCK_MONOTONIC
    res = clock_gettime(CLOCK_MONOTONIC, &t);
    if (res == 0) return t.tv_sec + t.tv_nsec * SEC_PER_NSEC;
# endif
    res = clock_gettime(CLOCK_REALTIME, &t);
    if (res == 0) return t.tv_sec + t.tv_nsec * SEC_PER_NSEC;
#endif
    struct timeval tv;
    gettimeofday(&tv, (struct timezone *)NULL);
    return (double)tv.tv_sec + tv.tv_usec * SEC_PER_USEC;
}

#endif  /* MS_WINDOWS */