# At a local mysql-5.1-bugteam repository of davi
3520 Davi Arnaut 2010-12-13
Bug#42054: SELECT CURDATE() is returning bad value
The problem from a user point of view was that on Solaris the
time related functions (e.g. NOW(), SYSDATE(), etc) would always
return a fixed time. This bug was happening due to a logic in the
time retrieving wrapper function which would only call the time()
function every half second. This interval between calls would be
calculated using the gethrtime() and the logic relied on the fact
that time returned by it is monotonic. Unfortunately, due to bugs
in the gethrtime() implementation, there are some cases where
the time returned by it can drift (See Solaris bug id 6600939),
potentially causing the interval calculation logic to fail.
Since this logic was being used due to ancient performance reasons,
the solution is to simply rely on time(), which nowadays is just a
wrapper around the somewhat fast gettimeofday function. This also
allows us to eliminate a lock which was used to control access
to the variables used to track the half second interval. In spite
of the the aforementioned problem, gethrtime() is still used in a
few places where we need a high resolution but under which drifts
wouldn't cause problems.
@ mysys/my_getsystime.c
Use time() even if gethrtime() is available. Remove logic which
relied on gethrtime() to only call time() every half second.
@ mysys/my_thr_init.c
Remove mutex which is no longer used.
@ mysys/mysys_priv.h
Remove mutex which is no longer used.
modified:
mysys/my_getsystime.c
mysys/my_thr_init.c
mysys/mysys_priv.h
=== modified file 'mysys/my_getsystime.c'
--- a/mysys/my_getsystime.c 2008-02-26 16:44:04 +0000
+++ b/mysys/my_getsystime.c 2010-12-13 23:34:32 +0000
@@ -70,10 +70,6 @@ ulonglong my_getsystime()
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)
{
@@ -81,7 +77,6 @@ time_t my_time(myf flags __attribute__((
fprintf(stderr, "%s: Warning: time() call failed\n", my_progname);
}
return t;
-#endif
}
@@ -159,25 +154,6 @@ ulonglong my_micro_time_and_time(time_t
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();
- if ((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;
#else
ulonglong newtime;
struct timeval t;
@@ -187,7 +163,12 @@ ulonglong my_micro_time_and_time(time_t
while (gettimeofday(&t, NULL) != 0)
{}
*time_arg= t.tv_sec;
- newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec;
+#if defined(HAVE_GETHRTIME)
+ newtime= (ulonglong) gethrtime()/1000;
+#else
+ newtime= (ulonglong) t.tv_sec * 1000000 + t.tv_usec;
+#endif
+
return newtime;
#endif /* defined(__WIN__) */
}
=== modified file 'mysys/my_thr_init.c'
--- a/mysys/my_thr_init.c 2009-12-17 11:45:13 +0000
+++ b/mysys/my_thr_init.c 2010-12-13 23:34:32 +0000
@@ -30,7 +30,7 @@ pthread_key(struct st_my_thread_var, THR
#endif /* USE_TLS */
pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,
THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap,
- THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, THR_LOCK_time,
+ THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads,
THR_LOCK_myisam_mmap;
pthread_cond_t THR_COND_threads;
@@ -151,7 +151,6 @@ my_bool my_thread_global_init(void)
pthread_mutex_init(&THR_LOCK_net,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_charset,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_threads,MY_MUTEX_INIT_FAST);
- pthread_mutex_init(&THR_LOCK_time,MY_MUTEX_INIT_FAST);
pthread_cond_init(&THR_COND_threads, NULL);
#if defined( __WIN__) || defined(OS2)
win_pthread_init();
@@ -216,7 +215,6 @@ void my_thread_global_end(void)
pthread_mutex_destroy(&THR_LOCK_myisam_mmap);
pthread_mutex_destroy(&THR_LOCK_heap);
pthread_mutex_destroy(&THR_LOCK_net);
- pthread_mutex_destroy(&THR_LOCK_time);
pthread_mutex_destroy(&THR_LOCK_charset);
if (all_threads_killed)
{
=== modified file 'mysys/mysys_priv.h'
--- a/mysys/mysys_priv.h 2007-07-30 08:33:50 +0000
+++ b/mysys/mysys_priv.h 2010-12-13 23:34:32 +0000
@@ -28,7 +28,7 @@
#include <my_pthread.h>
extern pthread_mutex_t THR_LOCK_malloc, THR_LOCK_open, THR_LOCK_keycache;
extern pthread_mutex_t THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_net;
-extern pthread_mutex_t THR_LOCK_charset, THR_LOCK_time;
+extern pthread_mutex_t THR_LOCK_charset;
#else
#include <my_no_pthread.h>
#endif
Attachment: [text/bzr-bundle] bzr/davi.arnaut@oracle.com-20101213233432-kmsx3tvqcq101sa6.bundle