my_getsystime.c 4.21 KB
Newer Older
unknown's avatar
unknown committed
1
/* Copyright (C) 2004 MySQL AB
unknown's avatar
unknown committed
2 3 4

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
unknown's avatar
unknown committed
5
   the Free Software Foundation; version 2 of the License.
unknown's avatar
unknown committed
6 7 8 9 10 11 12 13 14 15 16

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */


17 18 19 20 21
/* 
   TODO: in functions my_micro_time() and my_micro_time_and_time() there
   exists some common code that should be merged into a function.
*/

22 23 24
#include "mysys_priv.h"
#include "my_static.h"

25 26
#ifdef __NETWARE__
#include <nks/time.h>
27 28 29 30
#elif defined(__WIN__)
static ulonglong query_performance_frequency, query_performance_offset;
#elif defined(HAVE_GETHRTIME)
static ulonglong gethrtime_offset;
31 32
#endif

33 34 35 36 37 38 39 40 41 42 43 44 45
/*
  get time since epoc in 100 nanosec units

  NOTE:
  Thus to get the current time we should use the system function
  with the highest possible resolution

  The value is not subject to resetting or drifting by way of adjtime() or
  settimeofday(), and thus it is *NOT* appropriate for getting the current
  timestamp. It can be used for calculating time intervals, though.
  And it's good enough for UUID.
*/

unknown's avatar
unknown committed
46 47 48 49 50 51
ulonglong my_getsystime()
{
#ifdef HAVE_CLOCK_GETTIME
  struct timespec tp;
  clock_gettime(CLOCK_REALTIME, &tp);
  return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100;
52 53
#elif defined(HAVE_GETHRTIME)
  return gethrtime()/100-gethrtime_offset;
unknown's avatar
unknown committed
54
#elif defined(__WIN__)
55
  LARGE_INTEGER t_cnt;
56
  if (query_performance_frequency)
57
  {
unknown's avatar
unknown committed
58
    QueryPerformanceCounter(&t_cnt);
59
    return ((t_cnt.QuadPart / query_performance_frequency * 10000000) +
unknown's avatar
unknown committed
60
            ((t_cnt.QuadPart % query_performance_frequency) * 10000000 /
61
             query_performance_frequency) + query_performance_offset);
62
  }
63
  return 0;
64 65 66 67
#elif defined(__NETWARE__)
  NXTime_t tm;
  NXGetTime(NX_SINCE_1970, NX_NSECONDS, &tm);
  return (ulonglong)tm/100;
unknown's avatar
unknown committed
68 69 70 71 72 73 74
#else
  /* TODO: check for other possibilities for hi-res timestamping */
  struct timeval tv;
  gettimeofday(&tv,NULL);
  return (ulonglong)tv.tv_sec*10000000+(ulonglong)tv.tv_usec*10;
#endif
}
75

76
/* Return current time in microseconds since epoch */
77

78
my_hrtime_t my_hrtime()
79
{
80
  my_hrtime_t hrtime;
81
#if defined(__WIN__)
unknown's avatar
unknown committed
82 83
  ulonglong newtime;
  GetSystemTimeAsFileTime((FILETIME*)&newtime);
84
  hrtime.val= newtime/10;
85 86
#elif defined(HAVE_GETHRTIME)
  struct timeval t;
87 88 89
  /*
    The following loop is here because gettimeofday may fail on some systems
  */
90 91
  while (gettimeofday(&t, NULL) != 0)
  {}
92 93 94 95 96
  hrtime.val= t.tv_sec*1000000 + t.tv_usec;
#else
  hrtime.val= my_getsystime()/10;
#endif
  return hrtime;
97 98 99
}

/*
100
  This function is basically equivalent to
101

102 103
     *interval= my_getsystime()/10;
     *timestamp= my_time();
104

105
   but it avoids calling OS time functions twice, if possible.
106
*/
107
void my_diff_and_hrtime(my_timediff_t *interval, my_hrtime_t *timestamp)
108
{
109 110
  interval->val= my_getsystime() / 10;
#if defined(__WIN__) || defined(HAVE_GETHRTIME)
111
  *timestamp= my_hrtime();
112
#else
113 114
  timestamp->val= interval->val;
#endif
115 116
}

117
void my_time_init()
118
{
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
#ifdef __WIN__
#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10)
  FILETIME ft;
  LARGE_INTEGER li, t_cnt;
  DBUG_ASSERT(sizeof(LARGE_INTEGER) == sizeof(query_performance_frequency));
  if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency) == 0)
    query_performance_frequency= 0;
  else
  {
    GetSystemTimeAsFileTime(&ft);
    li.LowPart=  ft.dwLowDateTime;
    li.HighPart= ft.dwHighDateTime;
    query_performance_offset= li.QuadPart-OFFSET_TO_EPOC;
    QueryPerformanceCounter(&t_cnt);
    query_performance_offset-= (t_cnt.QuadPart /
                                query_performance_frequency * 10000000 +
                                t_cnt.QuadPart %
                                query_performance_frequency * 10000000 /
                                query_performance_frequency);
  }
139
#elif defined(HAVE_GETHRTIME)
140 141
  gethrtime_offset= gethrtime();
#endif
142
}