diff options
-rw-r--r-- | client/mysqltest.cc | 2 | ||||
-rw-r--r-- | include/my_pthread.h | 12 | ||||
-rw-r--r-- | include/my_sys.h | 9 | ||||
-rw-r--r-- | mysys/my_getsystime.c | 101 | ||||
-rw-r--r-- | mysys/queues.c | 6 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 7 | ||||
-rw-r--r-- | sql/mysqld.cc | 6 | ||||
-rw-r--r-- | sql/sql_class.h | 13 | ||||
-rw-r--r-- | sql/sql_connect.cc | 2 | ||||
-rw-r--r-- | sql/sql_profile.cc | 2 |
10 files changed, 60 insertions, 100 deletions
diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 98315ef6abe..7aaa479e879 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -8516,7 +8516,7 @@ void timer_output(void) ulonglong timer_now(void) { - return my_micro_time() / 1000; + return my_interval_timer() / 1000000; } diff --git a/include/my_pthread.h b/include/my_pthread.h index a7e4ea25064..a2476d4265c 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -426,9 +426,9 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex); #ifndef set_timespec_nsec #define set_timespec_nsec(ABSTIME,NSEC) \ { \ - ulonglong now= my_getsystime() + (NSEC/100); \ - (ABSTIME).ts_sec= (now / ULL(10000000)); \ - (ABSTIME).ts_nsec= (now % ULL(10000000) * 100 + ((NSEC) % 100)); \ + ulonglong now= my_hrtime().val*1000 + (NSEC); \ + (ABSTIME).ts_sec= now / 1000000000ULL; \ + (ABSTIME).ts_nsec= now % 1000000000ULL; \ } #endif /* !set_timespec_nsec */ #else @@ -444,9 +444,9 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex); #ifndef set_timespec_nsec #define set_timespec_nsec(ABSTIME,NSEC) \ {\ - ulonglong now= my_getsystime() + (NSEC/100); \ - (ABSTIME).tv_sec= (time_t) (now / ULL(10000000)); \ - (ABSTIME).tv_nsec= (long) (now % ULL(10000000) * 100 + ((NSEC) % 100)); \ + ulonglong now= my_hrtime().val*1000 + (NSEC); \ + (ABSTIME).tv_sec= (time_t) (now / 1000000000ULL); \ + (ABSTIME).tv_nsec= (long) (now % 1000000000ULL); \ } #endif /* !set_timespec_nsec */ #endif /* HAVE_TIMESPEC_TS_SEC */ diff --git a/include/my_sys.h b/include/my_sys.h index 96754d2e85d..48370ea7c38 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -894,21 +894,18 @@ extern ulong crc32(ulong crc, const uchar *buf, uint len); extern uint my_set_max_open_files(uint files); void my_free_open_file_info(void); -#define HRTIME_RESOLUTION 1000000 +#define HRTIME_RESOLUTION 1000000 /* microseconds */ typedef struct {ulonglong val;} my_hrtime_t; -typedef struct {ulonglong val;} my_timediff_t; void my_time_init(); extern my_hrtime_t my_hrtime(); -void my_diff_and_hrtime(my_timediff_t *interval, my_hrtime_t *timestamp); -extern ulonglong my_getsystime(void); +extern ulonglong my_interval_timer(void); -#define my_micro_time() (my_getsystime()/10) +#define microsecond_interval_timer() (my_interval_timer()/1000) #define hrtime_to_time(X) ((X).val/1000000) #define hrtime_from_time(X) ((ulonglong)((X)*1000000ULL)) #define hrtime_to_double(X) ((X).val/(double)HRTIME_RESOLUTION) #define hrtime_sec_part(X) ((ulong)((X).val%1000000)) #define my_time(X) hrtime_to_time(my_hrtime()) -#define my_micro_and_hrtime(X,Y) my_diff_and_hrtime(X,Y) extern my_bool my_gethwaddr(uchar *to); extern int my_getncpus(); diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c index 125d389f3d5..1e713ea26c3 100644 --- a/mysys/my_getsystime.c +++ b/mysys/my_getsystime.c @@ -14,67 +14,66 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* - 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__) -static ulonglong query_performance_frequency, query_performance_offset; #define OFFSET_TO_EPOC 116444736000000000LL -#elif defined(HAVE_GETHRTIME) -static ulonglong gethrtime_offset; +static ulonglong query_performance_frequency; #endif /* - get time since epoc in 100 nanosec units + 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 - 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. + The value is not 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_getsystime() +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()/100-gethrtime_offset; + 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 in microseconds since epoch */ +/* Return current time in HRTIME_RESOLUTION (microseconds) since epoch */ my_hrtime_t my_hrtime() { @@ -84,60 +83,24 @@ my_hrtime_t my_hrtime() GetSystemTimeAsFileTime((FILETIME*)&newtime); newtime -= OFFSET_TO_EPOC; hrtime.val= newtime/10; -#elif defined(HAVE_GETHRTIME) - struct timeval t; - /* - The following loop is here because gettimeofday may fail on some systems - */ - while (gettimeofday(&t, NULL) != 0) - {} - hrtime.val= t.tv_sec*1000000 + t.tv_usec; +#elif defined(HAVE_CLOCK_GETTIME) + struct timespec tp; + clock_gettime(CLOCK_REALTIME, &tp); + return tp.tv_sec*1000000ULL+tp.tv_nsec/1000ULL; #else - hrtime.val= my_getsystime()/10; + struct timeval t; + /* The following loop is here because gettimeofday may fail on some systems */ + while (gettimeofday(&t, NULL) != 0) {} + hrtime.val= t.tv_sec*1000000ULL + t.tv_usec; #endif return hrtime; } -/* - This function is basically equivalent to - - *interval= my_getsystime()/10; - *timestamp= my_time(); - - but it avoids calling OS time functions twice, if possible. -*/ -void my_diff_and_hrtime(my_timediff_t *interval, my_hrtime_t *timestamp) -{ - interval->val= my_getsystime() / 10; -#if defined(__WIN__) || defined(HAVE_GETHRTIME) - *timestamp= my_hrtime(); -#else - timestamp->val= interval->val; -#endif -} - void my_time_init() { #ifdef __WIN__ - FILETIME ft; - LARGE_INTEGER li, t_cnt; - DBUG_ASSERT(sizeof(LARGE_INTEGER) == sizeof(query_performance_frequency)); + compile_time_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); - } -#elif defined(HAVE_GETHRTIME) - gethrtime_offset= gethrtime(); #endif } diff --git a/mysys/queues.c b/mysys/queues.c index 9c85e493141..ff7fc1bc308 100644 --- a/mysys/queues.c +++ b/mysys/queues.c @@ -596,15 +596,15 @@ bool do_test(uint no_parts, uint l_max_ind, bool l_fix_used) static void start_measurement() { - start_time= my_getsystime(); + start_time= my_interval_timer(); } static void stop_measurement() { - ulonglong stop_time= my_getsystime(); + ulonglong stop_time= my_interval_timer(); uint time_in_micros; stop_time-= start_time; - stop_time/= 10; /* Convert to microseconds */ + stop_time/= 1000; /* Convert to microseconds */ time_in_micros= (uint)stop_time; printf("Time expired is %u microseconds \n", time_in_micros); } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index fd5c47d25cb..ef6bf611637 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3446,6 +3446,8 @@ err: static struct rand_struct uuid_rand; static uint nanoseq; static ulonglong uuid_time=0; +static longlong interval_timer_offset; + static char clock_seq_and_node_str[]="-0000-000000000000"; /** @@ -3473,6 +3475,7 @@ static void set_clock_seq_str() uint16 clock_seq= ((uint)(my_rnd(&uuid_rand)*16383)) | UUID_VARIANT; tohex(clock_seq_and_node_str+1, clock_seq, 4); nanoseq= 0; + interval_timer_offset= my_hrtime().val * 10 - my_interval_timer()/100 + UUID_TIME_OFFSET; } String *Item_func_uuid::val_str(String *str) @@ -3512,7 +3515,7 @@ String *Item_func_uuid::val_str(String *str) set_clock_seq_str(); } - ulonglong tv= my_getsystime() + UUID_TIME_OFFSET + nanoseq; + ulonglong tv= my_interval_timer()/100 + interval_timer_offset + nanoseq; if (likely(tv > uuid_time)) { @@ -3564,7 +3567,7 @@ String *Item_func_uuid::val_str(String *str) irrelevant in the new numberspace. */ set_clock_seq_str(); - tv= my_getsystime() + UUID_TIME_OFFSET; + tv= my_interval_timer()/100 + interval_timer_offset; nanoseq= 0; DBUG_PRINT("uuid",("making new numberspace")); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 98cf221b679..07d76edcbbf 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1947,7 +1947,7 @@ static bool cache_thread() this thread for handling of new THD object/connection. */ thd->mysys_var->abort= 0; - thd->thr_create_utime= my_micro_time(); + thd->thr_create_utime= microsecond_interval_timer(); threads.append(thd); return(1); } @@ -4907,7 +4907,7 @@ void handle_connection_in_main_thread(THD *thd) thread_cache_size=0; // Safety threads.append(thd); pthread_mutex_unlock(&LOCK_thread_count); - thd->start_utime= my_micro_time(); + thd->start_utime= microsecond_interval_timer(); handle_one_connection(thd); } @@ -4933,7 +4933,7 @@ void create_thread_to_handle_connection(THD *thd) thread_created++; threads.append(thd); DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id)); - thd->prior_thr_create_utime= thd->start_utime= my_micro_time(); + thd->prior_thr_create_utime= thd->start_utime= microsecond_interval_timer(); if ((error=pthread_create(&thd->real_id,&connection_attrib, handle_one_connection, (void*) thd))) diff --git a/sql/sql_class.h b/sql/sql_class.h index 507b2902eda..9a0a9bc5b38 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2028,17 +2028,14 @@ public: { start_time= hrtime_to_my_time(user_time); start_time_sec_part= hrtime_sec_part(user_time); - start_utime= utime_after_lock= my_micro_time(); } else { - my_hrtime_t hrtime; - my_timediff_t timediff; - my_micro_and_hrtime(&timediff, &hrtime); + my_hrtime_t hrtime= my_hrtime(); start_time= hrtime_to_my_time(hrtime); start_time_sec_part= hrtime_sec_part(hrtime); - utime_after_lock= start_utime= timediff.val; } + start_utime= utime_after_lock= microsecond_interval_timer(); } inline void set_current_time() { @@ -2051,15 +2048,15 @@ public: user_time= t; start_time= hrtime_to_my_time(user_time); start_time_sec_part= hrtime_sec_part(user_time); - start_utime= utime_after_lock= my_micro_time(); + start_utime= utime_after_lock= microsecond_interval_timer(); } inline void set_time(my_time_t t, ulong sec_part) { my_hrtime_t hrtime= { hrtime_from_time(t) + sec_part }; set_time(hrtime); } - void set_time_after_lock() { utime_after_lock= my_micro_time(); } - ulonglong current_utime() { return my_micro_time(); } + void set_time_after_lock() { utime_after_lock= microsecond_interval_timer(); } + ulonglong current_utime() { return microsecond_interval_timer(); } inline ulonglong found_rows(void) { return limit_found_rows; diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 28c1acc4716..a6e91b0f910 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1084,7 +1084,7 @@ pthread_handler_t handle_one_connection(void *arg) { THD *thd= (THD*) arg; - thd->thr_create_utime= my_micro_time(); + thd->thr_create_utime= microsecond_interval_timer(); if (thread_scheduler.init_new_connection_thread()) { diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc index c661f3744aa..732e7431efc 100644 --- a/sql/sql_profile.cc +++ b/sql/sql_profile.cc @@ -221,7 +221,7 @@ void PROF_MEASUREMENT::set_label(const char *status_arg, */ void PROF_MEASUREMENT::collect() { - time_usecs= (double) my_getsystime() / 10.0; /* 1 sec was 1e7, now is 1e6 */ + time_usecs= my_interval_timer() / 1e3; /* ns to us */ #ifdef HAVE_GETRUSAGE getrusage(RUSAGE_SELF, &rusage); #endif |