root/lib/gettimeofday.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. initialize
  2. gettimeofday

     1 /* Provide gettimeofday for systems that don't have it or for which it's broken.
     2 
     3    Copyright (C) 2001-2003, 2005-2007, 2009-2023 Free Software
     4    Foundation, Inc.
     5 
     6    This file is free software: you can redistribute it and/or modify
     7    it under the terms of the GNU Lesser General Public License as
     8    published by the Free Software Foundation; either version 2.1 of the
     9    License, or (at your option) any later version.
    10 
    11    This file is distributed in the hope that it will be useful,
    12    but WITHOUT ANY WARRANTY; without even the implied warranty of
    13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14    GNU Lesser General Public License for more details.
    15 
    16    You should have received a copy of the GNU Lesser General Public License
    17    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
    18 
    19 /* written by Jim Meyering */
    20 
    21 #include <config.h>
    22 
    23 /* Specification.  */
    24 #include <sys/time.h>
    25 
    26 #include <time.h>
    27 
    28 #if defined _WIN32 && ! defined __CYGWIN__
    29 # define WINDOWS_NATIVE
    30 # include <windows.h>
    31 #endif
    32 
    33 #ifdef WINDOWS_NATIVE
    34 
    35 /* Don't assume that UNICODE is not defined.  */
    36 # undef LoadLibrary
    37 # define LoadLibrary LoadLibraryA
    38 
    39 # if !(_WIN32_WINNT >= _WIN32_WINNT_WIN8)
    40 
    41 /* Avoid warnings from gcc -Wcast-function-type.  */
    42 #  define GetProcAddress \
    43     (void *) GetProcAddress
    44 
    45 /* GetSystemTimePreciseAsFileTime was introduced only in Windows 8.  */
    46 typedef void (WINAPI * GetSystemTimePreciseAsFileTimeFuncType) (FILETIME *lpTime);
    47 static GetSystemTimePreciseAsFileTimeFuncType GetSystemTimePreciseAsFileTimeFunc = NULL;
    48 static BOOL initialized = FALSE;
    49 
    50 static void
    51 initialize (void)
    52 {
    53   HMODULE kernel32 = LoadLibrary ("kernel32.dll");
    54   if (kernel32 != NULL)
    55     {
    56       GetSystemTimePreciseAsFileTimeFunc =
    57         (GetSystemTimePreciseAsFileTimeFuncType) GetProcAddress (kernel32, "GetSystemTimePreciseAsFileTime");
    58     }
    59   initialized = TRUE;
    60 }
    61 
    62 # else
    63 
    64 #  define GetSystemTimePreciseAsFileTimeFunc GetSystemTimePreciseAsFileTime
    65 
    66 # endif
    67 
    68 #endif
    69 
    70 /* This is a wrapper for gettimeofday.  It is used only on systems
    71    that lack this function, or whose implementation of this function
    72    causes problems.
    73    Work around the bug in some systems whereby gettimeofday clobbers
    74    the static buffer that localtime uses for its return value.  The
    75    gettimeofday function from Mac OS X 10.0.4 (i.e., Darwin 1.3.7) has
    76    this problem.  */
    77 
    78 int
    79 gettimeofday (struct timeval *restrict tv, void *restrict tz)
    80 {
    81 #undef gettimeofday
    82 #ifdef WINDOWS_NATIVE
    83 
    84   /* On native Windows, there are two ways to get the current time:
    85      GetSystemTimeAsFileTime
    86      <https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getsystemtimeasfiletime>
    87      or
    88      GetSystemTimePreciseAsFileTime
    89      <https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime>.
    90      GetSystemTimeAsFileTime produces values that jump by increments of
    91      15.627 milliseconds (!) on average.
    92      Whereas GetSystemTimePreciseAsFileTime values usually jump by 1 or 2
    93      microseconds.
    94      More discussion on this topic:
    95      <http://www.windowstimestamp.com/description>.  */
    96   FILETIME current_time;
    97 
    98 # if !(_WIN32_WINNT >= _WIN32_WINNT_WIN8)
    99   if (!initialized)
   100     initialize ();
   101 # endif
   102   if (GetSystemTimePreciseAsFileTimeFunc != NULL)
   103     GetSystemTimePreciseAsFileTimeFunc (&current_time);
   104   else
   105     GetSystemTimeAsFileTime (&current_time);
   106 
   107   /* Convert from FILETIME to 'struct timeval'.  */
   108   /* FILETIME: <https://docs.microsoft.com/en-us/windows/desktop/api/minwinbase/ns-minwinbase-filetime> */
   109   ULONGLONG since_1601 =
   110     ((ULONGLONG) current_time.dwHighDateTime << 32)
   111     | (ULONGLONG) current_time.dwLowDateTime;
   112   /* Between 1601-01-01 and 1970-01-01 there were 280 normal years and 89 leap
   113      years, in total 134774 days.  */
   114   ULONGLONG since_1970 =
   115     since_1601 - (ULONGLONG) 134774 * (ULONGLONG) 86400 * (ULONGLONG) 10000000;
   116   ULONGLONG microseconds_since_1970 = since_1970 / (ULONGLONG) 10;
   117   tv->tv_sec = microseconds_since_1970 / (ULONGLONG) 1000000;
   118   tv->tv_usec = microseconds_since_1970 % (ULONGLONG) 1000000;
   119 
   120   return 0;
   121 
   122 #else
   123 
   124 # if HAVE_GETTIMEOFDAY
   125 
   126 #  if defined timeval /* 'struct timeval' overridden by gnulib?  */
   127 #   undef timeval
   128   struct timeval otv;
   129   int result = gettimeofday (&otv, (struct timezone *) tz);
   130   if (result == 0)
   131     {
   132       tv->tv_sec = otv.tv_sec;
   133       tv->tv_usec = otv.tv_usec;
   134     }
   135 #  else
   136   int result = gettimeofday (tv, (struct timezone *) tz);
   137 #  endif
   138 
   139   return result;
   140 
   141 # else
   142 
   143 #  if !defined OK_TO_USE_1S_CLOCK
   144 #   error "Only 1-second nominal clock resolution found.  Is that intended?" \
   145           "If so, compile with the -DOK_TO_USE_1S_CLOCK option."
   146 #  endif
   147   tv->tv_sec = time (NULL);
   148   tv->tv_usec = 0;
   149 
   150   return 0;
   151 
   152 # endif
   153 #endif
   154 }

/* [<][>][^][v][top][bottom][index][help] */