clock_gettime.c 2.8 KB
Newer Older
1
/*****************************************************************************\
S
Shengliang Guan 已提交
2 3 4 5 6 7 8 9 10 11
*                                                                             *
*   Filename:	    clock_gettime.c					      *
*                                                                             *
*   Description:    WIN32 port of standard C library's clock_gettime().	      *
*                                                                             *
*   Notes:	    							      *
*                                                                             *
*   History:								      *
*    2014-06-04 JFL Created this file.                                        *
*									      *
12
*         Copyright 2016 Hewlett Packard Enterprise Development LP          *
S
Shengliang Guan 已提交
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 *
\*****************************************************************************/

#include "msvclibx.h"

#include <time.h>
#include <errno.h>


#ifdef _MSDOS

/* Check for the definition of _STRUCT_TIMESPEC before using clock_gettime().
   If it's not defined, use time() instead, which is supported by all OSs. */

#endif /* defined(_MSDOS) */


#ifdef _WIN32

#define WIN32_LEAN_AND_MEAN /* Avoid lots of unnecessary inclusions */
#include <windows.h>
S
TD-1057  
Shengliang Guan 已提交
34 35
#include "msvcTime.h"
#include "sys/msvcStat.h" /* For MsvcLibX's Filetime2Timespec */
S
Shengliang Guan 已提交
36

37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
#define MS_PER_SEC      1000ULL     // MS = milliseconds
#define US_PER_MS       1000ULL     // US = microseconds
#define HNS_PER_US      10ULL       // HNS = hundred-nanoseconds (e.g., 1 hns = 100 ns)
#define NS_PER_US       1000ULL

#define HNS_PER_SEC     (MS_PER_SEC * US_PER_MS * HNS_PER_US)
#define NS_PER_HNS      (100ULL)    // NS = nanoseconds
#define NS_PER_SEC      (MS_PER_SEC * US_PER_MS * NS_PER_US)

int clock_gettime_monotonic(struct timespec *tv) {
  static LARGE_INTEGER ticksPerSec;
  LARGE_INTEGER ticks;
  double seconds;

  if (!ticksPerSec.QuadPart) {
    QueryPerformanceFrequency(&ticksPerSec);
    if (!ticksPerSec.QuadPart) {
      errno = ENOTSUP;
      return -1;
    }
S
Shengliang Guan 已提交
57
  }
58 59 60 61 62 63 64 65 66 67 68 69 70

  QueryPerformanceCounter(&ticks);

  seconds = (double) ticks.QuadPart / (double) ticksPerSec.QuadPart;
  tv->tv_sec = (time_t)seconds;
  tv->tv_nsec = (long)((ULONGLONG)(seconds * NS_PER_SEC) % NS_PER_SEC);

  return 0;
}

int clock_gettime_realtime(struct timespec *pTS) {
  FILETIME ft;

S
Shengliang Guan 已提交
71 72
  GetSystemTimeAsFileTime(&ft);
  Filetime2Timespec(&ft, pTS);
73

S
Shengliang Guan 已提交
74 75 76
  return 0;
}

77 78 79 80 81 82 83 84 85 86 87 88
int clock_gettime(clockid_t clock_id, struct timespec *pTS) {
  if (clock_id == CLOCK_MONOTONIC) {
    return clock_gettime_monotonic(pTS);
  } else if (clock_id == CLOCK_REALTIME) {
    return clock_gettime_realtime(pTS);
  }

  errno = ENOTSUP;

  return -1;
}

S
Shengliang Guan 已提交
89
#endif /* defined(_WIN32) */