diff options
author | Michael Widenius <monty@askmonty.org> | 2011-05-28 05:11:32 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2011-05-28 05:11:32 +0300 |
commit | f197991f4102ed8ac66b7b57071f24f1d3b86aea (patch) | |
tree | b4590b80e7d50b664d8e6ff6a62978cb2402f0a6 /mysys/my_getsystime.c | |
parent | de44b51e151a00a00d0e396dc57ced3682d24d78 (diff) | |
parent | 306ed65302e14f303fdc33cfa9d19016fb319440 (diff) | |
download | mariadb-git-f197991f4102ed8ac66b7b57071f24f1d3b86aea.tar.gz |
Merge with 5.1-microseconds
A lot of small fixes and new test cases.
client/mysqlbinlog.cc:
Cast removed
client/mysqltest.cc:
Added missing DBUG_RETURN
include/my_pthread.h:
set_timespec_time_nsec() now only takes one argument
mysql-test/t/date_formats.test:
Remove --disable_ps_protocl as now also ps supports microseconds
mysys/my_uuid.c:
Changed to use my_interval_timer() instead of my_getsystime()
mysys/waiting_threads.c:
Changed to use my_hrtime()
sql/field.h:
Added bool special_const_compare() for fields that may convert values before compare (like year)
sql/field_conv.cc:
Added test to get optimal copying of identical temporal values.
sql/item.cc:
Return that item_int is equal if it's positive, even if unsigned flag is different.
Fixed Item_cache_str::save_in_field() to have identical null check as other similar functions
Added proper NULL check to Item_cache_int::save_in_field()
sql/item_cmpfunc.cc:
Don't call convert_constant_item() if there is nothing that is worth converting.
Simplified test when years should be converted
sql/item_sum.cc:
Mark cache values in Item_sum_hybrid as not constants to ensure they are not replaced by other cache values in compare_datetime()
sql/item_timefunc.cc:
Changed sec_to_time() to take a my_decimal argument to ensure we don't loose any sub seconds.
Added Item_temporal_func::get_time() (This simplifies some things)
sql/mysql_priv.h:
Added Lazy_string_decimal()
sql/mysqld.cc:
Added my_decimal constants max_seconds_for_time_type, time_second_part_factor
sql/table.cc:
Changed expr_arena to be of type CONVENTIONAL_EXECUTION to ensure that we don't loose any items that are created by fix_fields()
sql/tztime.cc:
TIME_to_gmt_sec() now sets *in_dst_time_gap in case of errors
This is needed to be able to detect if timestamp is 0
storage/maria/lockman.c:
Changed from my_getsystime() to set_timespec_time_nsec()
storage/maria/ma_loghandler.c:
Changed from my_getsystime() to my_hrtime()
storage/maria/ma_recovery.c:
Changed from my_getsystime() to mmicrosecond_interval_timer()
storage/maria/unittest/trnman-t.c:
Changed from my_getsystime() to mmicrosecond_interval_timer()
storage/xtradb/handler/ha_innodb.cc:
Added support for new time,datetime and timestamp
unittest/mysys/thr_template.c:
my_getsystime() -> my_interval_timer()
unittest/mysys/waiting_threads-t.c:
my_getsystime() -> my_interval_timer()
Diffstat (limited to 'mysys/my_getsystime.c')
-rw-r--r-- | mysys/my_getsystime.c | 228 |
1 files changed, 53 insertions, 175 deletions
diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c index 6bffcd65d30..cb063e27c1f 100644 --- a/mysys/my_getsystime.c +++ b/mysys/my_getsystime.c @@ -14,224 +14,102 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* get time since epoc in 100 nanosec units */ -/* thus to get the current time we should use the system function - with the highest possible resolution */ - -/* - TODO: in functions my_micro_time() and my_micro_time_and_time() there - exists some common code that should be merged into a function. -*/ #include "mysys_priv.h" #include "my_static.h" #ifdef __NETWARE__ #include <nks/time.h> +#elif defined(__WIN__) +#define OFFSET_TO_EPOC 116444736000000000LL +static ulonglong query_performance_frequency; #endif #ifdef HAVE_LINUX_UNISTD_H #include <linux/unistd.h> #endif +/* + return number of nanoseconds since unspecified (but always the same) + point in the past + + NOTE: + Thus to get the current time we should use the system function + with the highest possible resolution -ulonglong my_getsystime() + The value is not anchored to any specific point in time (e.g. epoch) nor + is it 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. +*/ + +ulonglong my_interval_timer() { #ifdef HAVE_CLOCK_GETTIME struct timespec tp; - clock_gettime(CLOCK_REALTIME, &tp); - return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100; + clock_gettime(CLOCK_MONOTONIC, &tp); + return tp.tv_sec*1000000000ULL+tp.tv_nsec; +#elif defined(HAVE_GETHRTIME) + return gethrtime(); #elif defined(__WIN__) LARGE_INTEGER t_cnt; if (query_performance_frequency) { QueryPerformanceCounter(&t_cnt); - return ((t_cnt.QuadPart / query_performance_frequency * 10000000) + - ((t_cnt.QuadPart % query_performance_frequency) * 10000000 / - query_performance_frequency) + query_performance_offset); + return (t_cnt.QuadPart / query_performance_frequency * 1000000000ULL) + + ((t_cnt.QuadPart % query_performance_frequency) * 1000000000ULL / + query_performance_frequency); + } + else + { + ulonglong newtime; + GetSystemTimeAsFileTime((FILETIME*)&newtime); + return newtime*100ULL; } - return 0; #elif defined(__NETWARE__) NXTime_t tm; NXGetTime(NX_SINCE_1970, NX_NSECONDS, &tm); - return (ulonglong)tm/100; + return (ulonglong)tm; #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; + return tv.tv_sec*1000000000ULL+tv.tv_usec*1000ULL; #endif } -/* - Return current time - - SYNOPSIS - my_time() - flags If MY_WME is set, write error if time call fails - -*/ - -time_t my_time(myf flags __attribute__((unused))) -{ - time_t t; -#ifdef HAVE_GETHRTIME - (void) my_micro_time_and_time(&t); - return t; -#else - /* The following loop is here beacuse time() may fail on some systems */ - while ((t= time(0)) == (time_t) -1) - { - if (flags & MY_WME) - fprintf(stderr, "%s: Warning: time() call failed\n", my_progname); - } - return t; -#endif -} - - -/* - Return time in micro seconds - - SYNOPSIS - my_micro_time() - - NOTES - This function is to be used to measure performance in micro seconds. - As it's not defined whats the start time for the clock, this function - us only useful to measure time between two moments. - - For windows platforms we need the frequency value of the CUP. This is - initalized in my_init.c through QueryPerformanceFrequency(). - - If Windows platform doesn't support QueryPerformanceFrequency() we will - obtain the time via GetClockCount, which only supports milliseconds. - - RETURN - Value in microseconds from some undefined point in time -*/ - -ulonglong my_micro_time() -{ -#if defined(__WIN__) - ulonglong newtime; - GetSystemTimeAsFileTime((FILETIME*)&newtime); - return (newtime/10); -#elif defined(HAVE_GETHRTIME) - return gethrtime()/1000; -#else - ulonglong newtime; - struct timeval t; - /* - The following loop is here because gettimeofday may fail on some systems - */ - while (gettimeofday(&t, NULL) != 0) - {} - newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec; - return newtime; -#endif /* defined(__WIN__) */ -} - - -/* - Return time in seconds and timer in microseconds (not different start!) - - SYNOPSIS - my_micro_time_and_time() - time_arg Will be set to seconds since epoch (00:00:00 UTC, - January 1, 1970) - - NOTES - This function is to be useful when we need both the time and microtime. - For example in MySQL this is used to get the query time start of a query - and to measure the time of a query (for the slow query log) - - IMPLEMENTATION - Value of time is as in time() call. - Value of microtime is same as my_micro_time(), which may be totally - unrealated to time() +/* Return current time in HRTIME_RESOLUTION (microseconds) since epoch */ - RETURN - Value in microseconds from some undefined point in time -*/ - -#define DELTA_FOR_SECONDS LL(500000000) /* Half a second */ - -ulonglong my_micro_time_and_time(time_t *time_arg) +my_hrtime_t my_hrtime() { + my_hrtime_t hrtime; #if defined(__WIN__) ulonglong newtime; GetSystemTimeAsFileTime((FILETIME*)&newtime); - *time_arg= (time_t) ((newtime - OFFSET_TO_EPOCH) / 10000000); - return (newtime/10); -#elif defined(HAVE_GETHRTIME) - /* - Solaris has a very slow time() call. We optimize this by using the very - fast gethrtime() call and only calling time() every 1/2 second - */ - static hrtime_t prev_gethrtime= 0; - static time_t cur_time= 0; - hrtime_t cur_gethrtime; - - pthread_mutex_lock(&THR_LOCK_time); - cur_gethrtime= gethrtime(); - /* - Due to bugs in the Solaris (x86) implementation of gethrtime(), - the time returned by it might not be monotonic. Don't use the - cached time(2) value if this is a case. - */ - if ((prev_gethrtime > cur_gethrtime) || - ((cur_gethrtime - prev_gethrtime) > DELTA_FOR_SECONDS)) - { - cur_time= time(0); - prev_gethrtime= cur_gethrtime; - } - *time_arg= cur_time; - pthread_mutex_unlock(&THR_LOCK_time); - return cur_gethrtime/1000; + newtime -= OFFSET_TO_EPOC; + hrtime.val= newtime/10; +#elif defined(HAVE_CLOCK_GETTIME) + struct timespec tp; + clock_gettime(CLOCK_REALTIME, &tp); + hrtime.val= tp.tv_sec*1000000ULL+tp.tv_nsec/1000ULL; #else - ulonglong newtime; struct timeval t; - /* - The following loop is here because gettimeofday may fail on some systems - */ - while (gettimeofday(&t, NULL) != 0) - {} - *time_arg= t.tv_sec; - newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec; - return newtime; -#endif /* defined(__WIN__) */ + /* The following loop is here because gettimeofday may fail */ + while (gettimeofday(&t, NULL) != 0) {} + hrtime.val= t.tv_sec*1000000ULL + t.tv_usec; +#endif + return hrtime; } -/* - Returns current time - - SYNOPSIS - my_time_possible_from_micro() - microtime Value from very recent my_micro_time() - - NOTES - This function returns the current time. The microtime argument is only used - if my_micro_time() uses a function that can safely be converted to the - current time. - - RETURN - current time -*/ - -time_t my_time_possible_from_micro(ulonglong microtime __attribute__((unused))) +void my_time_init() { -#if defined(__WIN__) - time_t t; - while ((t= time(0)) == (time_t) -1) - {} - return t; -#elif defined(HAVE_GETHRTIME) - return my_time(0); /* Cached time */ -#else - return (time_t) (microtime / 1000000); -#endif /* defined(__WIN__) */ +#ifdef __WIN__ + compile_time_assert(sizeof(LARGE_INTEGER) == + sizeof(query_performance_frequency)); + if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency) == 0) + query_performance_frequency= 0; +#endif } |