OSDN Git Service

Avoid unwanted GCC warning diagnostic messages.
[mingw/mingw-org-wsl.git] / mingwrt / mingwex / clocktime.c
1 /*
2  * clocktime.c
3  *
4  * Implementation of the clock_gettime() element of the POSIX clock API.
5  *
6  * $Id$
7  *
8  * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
9  * Copyright (C) 2017, 2018, MinGW.org Project
10  *
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice (including the next
20  * paragraph) shall be included in all copies or substantial portions of the
21  * Software.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29  * DEALINGS IN THE SOFTWARE.
30  *
31  */
32 #include "clockapi.h"
33
34 int clock_gettime( clockid_t clock_id, struct timespec *current )
35 {
36   /* Standard API function, first implemented in POSIX.1b-1993, to
37    * read the current time indicated by a specified clock; it first
38    * initializes the clock, if necessary, then reads its currently
39    * indicated time, and encodes it for return, in the specified
40    * "current" timespec structure, together with a "validity check"
41    * status code.
42    *
43    * Note that, unlike the clock_getres() API, it is NOT permitted
44    * to specify NULL for the timespec parameter here; doing so will
45    * cause the call to fail, irrespective of the clock validity.
46    */
47   if( current == NULL )
48     return clock_api_invalid_error();
49
50   if( __clock_api_is_valid( clock_id ) )
51   {
52     /* We must be prepared to retrieve clock frequencies from Windows
53      * APIs, which report either LARGE_INTEGER or FILETIME values, but
54      * we prefer to interpret them as scalar int64_t values.
55      */
56     union { uint64_t value; LARGE_INTEGER qpc_value; FILETIME rtc_value; } ct;
57     switch( clock_id->type )
58     {
59       case CLOCK_TYPE_REALTIME:
60         /* The counter for CLOCK_REALTIME, and any derived clock, is
61          * represented by system time, expressed as a count of 100ns
62          * intervals since the start of the Windows FILETIME epoch.
63          */
64         GetSystemTimeAsFileTime( &ct.rtc_value );
65         break;
66
67       case CLOCK_TYPE_MONOTONIC:
68         /* Conversely, the counter for CLOCK_MONOTIME and derivatives
69          * is obtained from the Windows QPC API, if supported...
70          */
71         if( QueryPerformanceCounter( &ct.qpc_value ) > 0 )
72           break;
73
74       /* ...or otherwise, fall through, to force an "invalid status"
75        * return, as we do for any other clock type designation, (which
76        * implicitly includes CLOCK_TYPE_UNIMPLEMENTED; note that this
77        * is incorporated into a default case handler, to suppress any
78        * GCC -Wswitch warnings which might otherwise be diagnosed).
79        */
80       default: return clock_api_invalid_error();
81     }
82     /* In either case, once we have a valid count of clock ticks, we
83      * must adjust it, relative to the timebase for the clock, (which
84      * is recorded within the clock's implementation data structure),
85      * then scale it, and break it down into seconds and nanoseconds
86      * components, (again based on scaling factors which are similarly
87      * recorded within the implementation data)...
88      */
89     ct.value -= clock_id->timebase;
90     current->tv_nsec = (ct.value % clock_id->frequency)
91       * NANOSECONDS_PER_SECOND / clock_id->frequency;
92     current->tv_sec = ct.value / clock_id->frequency;
93
94     /* ...before returning zero, as "successful completion" status...
95      */
96     return 0;
97   }
98   /* ...or -1, indicating failure.
99    */
100   return -1;
101 }
102
103 /* $RCSfile$: end of file */