File: posix_time.cpp

package info (click to toggle)
cataclysm-dda 0.C%2Bgit20190228.faafa3a-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 181,636 kB
  • sloc: cpp: 256,609; python: 2,621; makefile: 862; sh: 495; perl: 37; xml: 33
file content (85 lines) | stat: -rw-r--r-- 3,382 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
#include "posix_time.h"

#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
#include <cerrno>

int
nanosleep( const struct timespec *requested_delay,
           struct timespec *remaining_delay )
{
    static bool initialized;
    /* Number of performance counter increments per nanosecond,
       or zero if it could not be determined.  */
    static double ticks_per_nanosecond;

    if( requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec ) {
        errno = EINVAL;
        return -1;
    }

    /* For requested delays of one second or more, 15ms resolution is
       sufficient.  */
    if( requested_delay->tv_sec == 0 ) {
        if( !initialized ) {
            /* Initialize ticks_per_nanosecond.  */
            LARGE_INTEGER ticks_per_second;

            if( QueryPerformanceFrequency( &ticks_per_second ) )
                ticks_per_nanosecond =
                    ( double ) ticks_per_second.QuadPart / 1000000000.0;

            initialized = true;
        }
        if( ticks_per_nanosecond ) {
            /* QueryPerformanceFrequency worked.  We can use
               QueryPerformanceCounter.  Use a combination of Sleep and
               busy-looping.  */
            /* Number of milliseconds to pass to the Sleep function.
               Since Sleep can take up to 8 ms less or 8 ms more than requested
               (or maybe more if the system is loaded), we subtract 10 ms.  */
            int sleep_millis = static_cast<int>( requested_delay->tv_nsec ) / 1000000 - 10;
            /* Determine how many ticks to delay.  */
            LONGLONG wait_ticks = requested_delay->tv_nsec * ticks_per_nanosecond;
            /* Start.  */
            LARGE_INTEGER counter_before;
            if( QueryPerformanceCounter( &counter_before ) ) {
                /* Wait until the performance counter has reached this value.
                   We don't need to worry about overflow, because the performance
                   counter is reset at reboot, and with a frequency of 3.6E6
                   ticks per second 63 bits suffice for over 80000 years.  */
                LONGLONG wait_until = counter_before.QuadPart + wait_ticks;
                /* Use Sleep for the longest part.  */
                if( sleep_millis > 0 ) {
                    Sleep( sleep_millis );
                }
                /* Busy-loop for the rest.  */
                for( ;; ) {
                    LARGE_INTEGER counter_after;
                    if( !QueryPerformanceCounter( &counter_after ) )
                        /* QueryPerformanceCounter failed, but succeeded earlier.
                           Should not happen.  */
                    {
                        break;
                    }
                    if( counter_after.QuadPart >= wait_until )
                        /* The requested time has elapsed.  */
                    {
                        break;
                    }
                }
                goto done;
            }
        }
    }
    /* Implementation for long delays and as fallback.  */
    Sleep( requested_delay->tv_sec * 1000 + requested_delay->tv_nsec / 1000000 );

done:
    /* Sleep is not interruptible.  So there is no remaining delay.  */
    if( remaining_delay != NULL ) {
        remaining_delay->tv_sec = 0;
        remaining_delay->tv_nsec = 0;
    }
    return 0;
}
#endif