File Coverage

Nanos.xs
Criterion Covered Total %
statement 24 25 96.0
branch 18 24 75.0
condition n/a
subroutine n/a
pod n/a
total 42 49 85.7


line stmt bran cond sub pod time code
1             #include "EXTERN.h"
2             #include "perl.h"
3             #include "XSUB.h"
4             #include
5              
6             #ifdef HAS_CLOCK_GETTIME
7             #include
8             #include
9             #include
10             #endif
11              
12             #ifdef HAS_WINHR
13             #include
14             #endif
15              
16             #if defined(HAS_CLOCK_GETTIME) || defined(HAS_WINHR)
17             static void
18 11           get_hrtime(int use_realtime, uint64_t *sec_out, uint64_t *nsec_out)
19             {
20             #ifdef HAS_CLOCK_GETTIME
21             {
22             struct timespec ts;
23 11           clockid_t clock_id = use_realtime ? CLOCK_REALTIME : CLOCK_MONOTONIC;
24 11 50         if (clock_gettime(clock_id, &ts) != 0) {
25 0           croak("hrtime(): clock_gettime() failed: %s", strerror(errno));
26             }
27 11           *sec_out = (uint64_t)ts.tv_sec;
28 11           *nsec_out = (uint64_t)ts.tv_nsec;
29             }
30             #else
31             if (use_realtime) {
32             FILETIME ft;
33             ULARGE_INTEGER ul;
34             GetSystemTimePreciseAsFileTime(&ft);
35             ul.LowPart = ft.dwLowDateTime;
36             ul.HighPart = ft.dwHighDateTime;
37             ul.QuadPart -= 116444736000000000ULL;
38             *sec_out = ul.QuadPart / 10000000ULL;
39             *nsec_out = (ul.QuadPart % 10000000ULL) * 100ULL;
40             } else {
41             LARGE_INTEGER freq, counter;
42             int64_t remainder;
43             if (!QueryPerformanceFrequency(&freq)) {
44             croak("hrtime(): QueryPerformanceFrequency() failed");
45             }
46             if (!QueryPerformanceCounter(&counter)) {
47             croak("hrtime(): QueryPerformanceCounter() failed");
48             }
49             *sec_out = (uint64_t)(counter.QuadPart / freq.QuadPart);
50             remainder = counter.QuadPart % freq.QuadPart;
51             *nsec_out = (uint64_t)((remainder * 1000000000LL) / freq.QuadPart);
52             }
53             #endif
54 11           }
55             #endif
56              
57             MODULE = Time::Nanos PACKAGE = Time::Nanos
58              
59             PROTOTYPES: DISABLE
60              
61             void
62             hrtime(...)
63             PPCODE:
64             #if !defined(HAS_CLOCK_GETTIME) && !defined(HAS_WINHR)
65             croak("hrtime(): high-resolution clock is not available on this platform");
66             #else
67             {
68             uint64_t sec_part, nsec_part;
69 12           int want_list = 0;
70 12           int use_realtime = 0;
71              
72 12 100         if (items > 0 && SvTRUE(ST(0))) {
    100          
73 2           want_list = 1;
74             }
75              
76 12 100         if (items > 1 && SvOK(ST(1))) {
    50          
77             STRLEN len;
78 6           const char *clock_name = SvPV(ST(1), len);
79 6 100         if (len == 9 && strnEQ(clock_name, "monotonic", 9)) {
    50          
80 1           use_realtime = 0;
81 5 100         } else if (len == 8 && strnEQ(clock_name, "realtime", 8)) {
    50          
82 4           use_realtime = 1;
83             } else {
84 1           croak("hrtime(): unknown clock source '%s' (valid: 'monotonic', 'realtime')", clock_name);
85             }
86             }
87              
88 11           get_hrtime(use_realtime, &sec_part, &nsec_part);
89              
90 11 100         if (want_list) {
91 2 50         EXTEND(SP, 2);
92 2           PUSHs(sv_2mortal(newSVuv((UV)sec_part)));
93 2           PUSHs(sv_2mortal(newSVuv((UV)nsec_part)));
94             } else {
95 9 50         EXTEND(SP, 1);
96 9           PUSHs(sv_2mortal(newSVuv(
97             (UV)(sec_part * 1000000000ULL + nsec_part)
98             )));
99             }
100             }
101             #endif