summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
authorunknown <monty@mysql.com/nosik.monty.fi>2007-07-30 11:33:50 +0300
committerunknown <monty@mysql.com/nosik.monty.fi>2007-07-30 11:33:50 +0300
commitb59217ebbbb9c2869ab914805729b3ca57c976fa (patch)
treeb1f9aa6b9e6bcbc36eded4aeb066d360e7541e72 /mysys
parentae8d075508dd1e942ee15ef4194c525f31e36098 (diff)
downloadmariadb-git-b59217ebbbb9c2869ab914805729b3ca57c976fa.tar.gz
Slow query log to file now displays queries with microsecond precission
--long-query-time is now given in seconds with microseconds as decimals --min_examined_row_limit added for slow query log long_query_time user variable is now double with 6 decimals Added functions to get time in microseconds Added faster time() functions for system that has gethrtime() (Solaris) We now do less time() calls. Added field->in_read_set() and field->in_write_set() for easier field manipulation by handlers set_var.cc and my_getopt() can now handle DOUBLE variables. All time() calls changed to my_time() my_time() now does retry's if time() call fails. Added debug function for stopping in mysql_admin_table() when tables are locked Some trivial function and struct variable renames to avoid merge errors. Fixed compiler warnings Initialization of some time variables on windows moved to my_init() include/my_getopt.h: Added support for double arguments include/my_sys.h: Fixed wrong type to packfrm() Added new my_time functions include/mysql/plugin.h: Added support for DOUBLE libmysql/CMakeLists.txt: Added new time functions libmysql/Makefile.shared: Added new time functions mysql-test/r/variables.result: Testing of long_query_time mysql-test/t/variables.test: Testing of long_query_time mysys/charset.c: Fixed compiler warnings mysys/default_modify.c: Fixed compiler warnings mysys/hash.c: Fixed compiler warnings mysys/mf_getdate.c: Use my_time() mysys/mf_iocache2.c: Fixed compiler warnings mysys/mf_pack.c: Fixed compiler warnings mysys/mf_path.c: Fixed compiler warnings mysys/my_append.c: Fixed compiler warnings mysys/my_compress.c: Fixed compiler warnings mysys/my_copy.c: Fixed compiler warnings mysys/my_gethwaddr.c: Fixed compiler warnings mysys/my_getopt.c: Added support for double arguments mysys/my_getsystime.c: Added functions to get time in microseconds. Added faster time() functions for system that has gethrtime() (Solaris) Moved windows initialization code to my_init() mysys/my_init.c: Added initializing of variables needed for windows time functions mysys/my_static.c: Added variables needed for windows time functions mysys/my_static.h: Added variables needed for windows time functions mysys/my_thr_init.c: Added THR_LOCK_time, used for faster my_time() mysys/mysys_priv.h: Added THR_LOCK_time, used for faster my_time() mysys/thr_alarm.c: time() -> my_time() sql/event_data_objects.cc: end_time() -> set_current_time() sql/event_queue.cc: end_time() -> set_current_time() sql/event_scheduler.cc: Fixed compiler warnings sql/field.h: Added field->in_read_set() and field->in_write_set() for easier field manipulation by handlers sql/item.h: Added decimal to Item_float(double) sql/item_cmpfunc.h: Added decimal to Item_float(double) sql/item_timefunc.cc: time() -> my_time() sql/item_xmlfunc.cc: Fixed compiler warning sql/lock.cc: lock_time() -> set_time_after_lock() sql/log.cc: Timing in slow query log to file is now done in microseconds Changed some while() loops to for() loops. Fixed indentation time() -> my_time() sql/log.h: Slow query logging is now done based on microseconds sql/log_event.cc: time() -> my_time() Fixed arguments to new Item_float() sql/mysql_priv.h: Fixed compiler warnings Added opt_log_slow_slave_statements sql/mysqld.cc: Added --log_slow_slave_statements and --min_examined_row_limit --long-query-time now takes a double argument with microsecond resolution Don't write shutdown message when using --help Removed not needed \n Thread create time and connect time is now done in microseconds time() -> my_time() Avoid some time() calls sql/net_serv.cc: Fixed compiler warnings sql/parse_file.cc: time() -> my_time() sql/set_var.cc: Added support for DOUBLE variables Added support for variables that are given in seconds with microsecond resolution sql/set_var.h: Added support for variables that are given in seconds with microsecond resolution sql/slave.cc: Allow logging of slave queries to slow query log if 'opt_log_slow_slave_statements' is given time() -> my_time() sql/sql_cache.h: Fixed compiler warning() sql/sql_class.cc: Initialize new THD variables sql/sql_class.h: long_query_time is now in microseconds Added min_examined_row_limit Reordered some THD elements for higher efficency Added timers in microseconds (connect_utime, thr_create_utime, start_utime and utime_after_lock) Start of query is now recorded both in seconds and in microseconds. Following renames was made for more clarity and avoid merge problems from earlier versions: connect_time -> connect_utime thr_create_time -> thr_create_utime end_time() -> set_current_time() lock_time() -> set_time_after_lock() Added THD::start_utime, which is start of query in microseconds from some arbitary time Added function THD::current_utime() Removed safe_time() as retry's are handled in my_time() sql/sql_connect.cc: User resources are now using microsecond resolution sql/sql_insert.cc: end_time() -> set_current_time() sql-common/client.c: time() -> my_time() sql/sql_parse.cc: Testing if we should print to slow_query_log() is now done with microsecond precission. If min_examined_row_limit is given, only log queries to slow query log that has examined more rows than this. sql/sql_select.cc: Simplify code now that Item_float() takes decimals as argument sql/sql_show.cc: time() -> my_time() Added support for SYS_DOUBLE sql/sql_table.cc: Added debug function for stopping in mysql_admin_table() when tables are locked sql/structs.h: intime -> reset_utime
Diffstat (limited to 'mysys')
-rw-r--r--mysys/charset.c8
-rw-r--r--mysys/default_modify.c2
-rw-r--r--mysys/hash.c20
-rw-r--r--mysys/mf_getdate.c2
-rw-r--r--mysys/mf_iocache2.c14
-rw-r--r--mysys/mf_pack.c4
-rw-r--r--mysys/mf_path.c2
-rw-r--r--mysys/my_append.c15
-rw-r--r--mysys/my_compress.c13
-rw-r--r--mysys/my_copy.c6
-rw-r--r--mysys/my_gethwaddr.c2
-rw-r--r--mysys/my_getopt.c43
-rw-r--r--mysys/my_getsystime.c186
-rw-r--r--mysys/my_init.c22
-rw-r--r--mysys/my_static.c5
-rw-r--r--mysys/my_static.h2
-rw-r--r--mysys/my_thr_init.c4
-rw-r--r--mysys/mysys_priv.h2
-rw-r--r--mysys/thr_alarm.c12
19 files changed, 298 insertions, 66 deletions
diff --git a/mysys/charset.c b/mysys/charset.c
index 1c81e480404..cc1a238f281 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -323,14 +323,14 @@ static int charset_initialized=0;
static my_bool my_read_charset_file(const char *filename, myf myflags)
{
- char *buf;
+ uchar *buf;
int fd;
uint len, tmp_len;
MY_STAT stat_info;
if (!my_stat(filename, &stat_info, MYF(myflags)) ||
((len= (uint)stat_info.st_size) > MY_MAX_ALLOWED_BUF) ||
- !(buf= (char *)my_malloc(len,myflags)))
+ !(buf= (uchar*) my_malloc(len,myflags)))
return TRUE;
if ((fd=my_open(filename,O_RDONLY,myflags)) < 0)
@@ -340,7 +340,7 @@ static my_bool my_read_charset_file(const char *filename, myf myflags)
if (tmp_len != len)
goto error;
- if (my_parse_charset_xml(buf,len,add_collation))
+ if (my_parse_charset_xml((char*) buf,len,add_collation))
{
#ifdef NOT_YET
printf("ERROR at line %d pos %d '%s'\n",
@@ -350,7 +350,7 @@ static my_bool my_read_charset_file(const char *filename, myf myflags)
#endif
}
- my_free(buf, myflags);
+ my_free(buf, myflags);
return FALSE;
error:
diff --git a/mysys/default_modify.c b/mysys/default_modify.c
index b2a43f511b9..78f6105b071 100644
--- a/mysys/default_modify.c
+++ b/mysys/default_modify.c
@@ -218,7 +218,7 @@ int modify_defaults_file(const char *file_location, const char *option,
if (my_chsize(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0,
MYF(MY_WME)) ||
my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) ||
- my_fwrite(cnf_file, file_buffer, (size_t) (dst_ptr - file_buffer),
+ my_fwrite(cnf_file, (uchar*) file_buffer, (size_t) (dst_ptr - file_buffer),
MYF(MY_NABP)))
goto err;
}
diff --git a/mysys/hash.c b/mysys/hash.c
index 47ddc5aa97d..4532b06b533 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -137,7 +137,7 @@ void my_hash_reset(HASH *hash)
DBUG_VOID_RETURN;
}
- /* some helper functions */
+/* some helper functions */
/*
This function is char* instead of uchar* as HPUX11 compiler can't
@@ -149,9 +149,9 @@ hash_key(const HASH *hash, const uchar *record, size_t *length,
my_bool first)
{
if (hash->get_key)
- return (*hash->get_key)(record,length,first);
+ return (char*) (*hash->get_key)(record,length,first);
*length=hash->key_length;
- return (uchar*) record+hash->key_offset;
+ return (char*) record+hash->key_offset;
}
/* Calculate pos according to keys */
@@ -313,12 +313,14 @@ my_bool my_hash_insert(HASH *info,const uchar *record)
uchar *ptr_to_rec,*ptr_to_rec2;
HASH_LINK *data,*empty,*gpos,*gpos2,*pos;
- LINT_INIT(gpos); LINT_INIT(gpos2);
- LINT_INIT(ptr_to_rec); LINT_INIT(ptr_to_rec2);
+ LINT_INIT(gpos);
+ LINT_INIT(gpos2);
+ LINT_INIT(ptr_to_rec);
+ LINT_INIT(ptr_to_rec2);
if (HASH_UNIQUE & info->flags)
{
- char *key= (char*) hash_key(info, record, &idx, 1);
+ uchar *key= (uchar*) hash_key(info, record, &idx, 1);
if (hash_search(info, key, idx))
return(TRUE); /* Duplicate entry */
}
@@ -544,14 +546,16 @@ my_bool hash_update(HASH *hash, uchar *record, uchar *old_key,
if (HASH_UNIQUE & hash->flags)
{
HASH_SEARCH_STATE state;
- char *found, *new_key= hash_key(hash, record, &idx, 1);
+ uchar *found, *new_key= (uchar*) hash_key(hash, record, &idx, 1);
if ((found= hash_first(hash, new_key, idx, &state)))
+ {
do
{
- if (found != (char*) record)
+ if (found != record)
DBUG_RETURN(1); /* Duplicate entry */
}
while ((found= hash_next(hash, new_key, idx, &state)));
+ }
}
data=dynamic_element(&hash->array,0,HASH_LINK*);
diff --git a/mysys/mf_getdate.c b/mysys/mf_getdate.c
index 2f08027a477..3a8e1be6a0b 100644
--- a/mysys/mf_getdate.c
+++ b/mysys/mf_getdate.c
@@ -42,7 +42,7 @@ void get_date(register char * to, int flag, time_t date)
struct tm tm_tmp;
#endif
- skr=date ? (time_t) date : time((time_t*) 0);
+ skr=date ? (time_t) date : my_time(0);
#if defined(HAVE_LOCALTIME_R) && defined(_REENTRANT)
if (flag & GETDATE_GMT)
localtime_r(&skr,&tm_tmp);
diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c
index 8a5b91661c4..87ea995f518 100644
--- a/mysys/mf_iocache2.c
+++ b/mysys/mf_iocache2.c
@@ -246,7 +246,7 @@ size_t my_b_gets(IO_CACHE *info, char *to, size_t max_length)
for (;;)
{
- char *pos,*end;
+ uchar *pos, *end;
if (length > max_length)
length=max_length;
for (pos=info->read_pos,end=pos+length ; pos < end ;)
@@ -323,7 +323,7 @@ size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args)
length= (size_t) (fmt - start);
out_length+=length;
- if (my_b_write(info, start, length))
+ if (my_b_write(info, (const uchar*) start, length))
goto err;
if (*fmt == '\0') /* End of format */
@@ -378,14 +378,14 @@ size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args)
size_t length2 = strlen(par);
/* TODO: implement minimum width and precision */
out_length+= length2;
- if (my_b_write(info, par, length2))
+ if (my_b_write(info, (uchar*) par, length2))
goto err;
}
else if (*fmt == 'b') /* Sized buffer parameter, only precision makes sense */
{
char *par = va_arg(args, char *);
out_length+= precision;
- if (my_b_write(info, par, precision))
+ if (my_b_write(info, (uchar*) par, precision))
goto err;
}
else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
@@ -400,7 +400,7 @@ size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args)
else
length2= (size_t) (int10_to_str((long) (uint) iarg,buff,10)- buff);
out_length+= length2;
- if (my_b_write(info, buff, length2))
+ if (my_b_write(info, (uchar*) buff, length2))
goto err;
}
else if ((*fmt == 'l' && fmt[1] == 'd') || fmt[1] == 'u')
@@ -416,13 +416,13 @@ size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args)
else
length2= (size_t) (int10_to_str(iarg,buff,10)- buff);
out_length+= length2;
- if (my_b_write(info, buff, length2))
+ if (my_b_write(info, (uchar*) buff, length2))
goto err;
}
else
{
/* %% or unknown code */
- if (my_b_write(info, backtrack, fmt-backtrack))
+ if (my_b_write(info, (uchar*) backtrack, (size_t) (fmt-backtrack)))
goto err;
out_length+= fmt-backtrack;
}
diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c
index 99c0c959d94..a31b9595c85 100644
--- a/mysys/mf_pack.c
+++ b/mysys/mf_pack.c
@@ -56,7 +56,7 @@ void pack_dirname(char * to, const char *from)
(buff_length == d_length && !bcmp(buff,start,d_length))) &&
*start != FN_LIBCHAR && *start)
{ /* Put current dir before */
- bchange(to,d_length,buff,buff_length,strlen(to)+1);
+ bchange((uchar*) to, d_length, (uchar*) buff, buff_length, strlen(to)+1);
}
}
@@ -328,7 +328,7 @@ size_t unpack_dirname(char * to, const char *from)
if (buff+h_length < suffix)
bmove(buff+h_length,suffix,length);
else
- bmove_upp(buff+h_length+length,suffix+length,length);
+ bmove_upp((uchar*) buff+h_length+length, (uchar*) suffix+length, length);
bmove(buff,tilde_expansion,h_length);
}
}
diff --git a/mysys/mf_path.c b/mysys/mf_path.c
index 7baded9d715..73e73cb7f76 100644
--- a/mysys/mf_path.c
+++ b/mysys/mf_path.c
@@ -46,7 +46,7 @@ char * my_path(char * to, const char *progname,
if (!test_if_hard_path(to))
{
if (!my_getwd(curr_dir,FN_REFLEN,MYF(0)))
- bchange(to,0,curr_dir, (uint) strlen(curr_dir), (uint) strlen(to)+1);
+ bchange((uchar*) to, 0, (uchar*) curr_dir, strlen(curr_dir), strlen(to)+1);
}
}
else
diff --git a/mysys/my_append.c b/mysys/my_append.c
index ddd3c91e832..35881a959d5 100644
--- a/mysys/my_append.c
+++ b/mysys/my_append.c
@@ -27,21 +27,22 @@ struct utimbuf {
};
#endif
- /* Append a file to another */
-
-int my_append(const char *from, const char *to, myf MyFlags)
+/*
+ Append a file to another
+ NOTES
+ Don't set MY_FNABP or MY_NABP bits on when calling this function
+*/
- /* Dont set MY_FNABP or MY_NABP bits on
- when calling this funktion */
+int my_append(const char *from, const char *to, myf MyFlags)
{
uint Count;
File from_file,to_file;
- char buff[IO_SIZE];
+ uchar buff[IO_SIZE];
DBUG_ENTER("my_append");
DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags));
- from_file=to_file= -1;
+ from_file= to_file= -1;
if ((from_file=my_open(from,O_RDONLY,MyFlags)) >= 0)
{
diff --git a/mysys/my_compress.c b/mysys/my_compress.c
index d495a1c1c6d..bc9f8317487 100644
--- a/mysys/my_compress.c
+++ b/mysys/my_compress.c
@@ -154,17 +154,20 @@ my_bool my_uncompress(uchar *packet, size_t len, size_t *complen)
SYNOPSIS
packfrm()
- data Data reference to frm file data
+ data Data reference to frm file data.
len Length of frm file data
out:pack_data Reference to the pointer to the packed frm data
out:pack_len Length of packed frm file data
+ NOTES
+ data is replaced with compressed content
+
RETURN VALUES
0 Success
>0 Failure
*/
-int packfrm(const uchar *data, size_t len,
+int packfrm(uchar *data, size_t len,
uchar **pack_data, size_t *pack_len)
{
int error;
@@ -178,8 +181,8 @@ int packfrm(const uchar *data, size_t len,
if (my_compress((uchar*)data, &org_len, &comp_len))
goto err;
- DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", org_len, comp_len));
- DBUG_DUMP("compressed", (char*)data, org_len);
+ DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", (ulong) org_len, (ulong) comp_len));
+ DBUG_DUMP("compressed", data, org_len);
error= 2;
blob_len= BLOB_HEADER + org_len;
@@ -235,7 +238,7 @@ int unpackfrm(uchar **unpack_data, size_t *unpack_len,
complen= uint4korr(pack_data+8);
DBUG_PRINT("blob",("ver: %lu complen: %lu orglen: %lu",
- ver, complen, orglen));
+ ver, (ulong) complen, (ulong) orglen));
DBUG_DUMP("blob->data", pack_data + BLOB_HEADER, complen);
if (ver != 1)
diff --git a/mysys/my_copy.c b/mysys/my_copy.c
index 3f8b0695a25..cd741b1eb52 100644
--- a/mysys/my_copy.c
+++ b/mysys/my_copy.c
@@ -54,7 +54,7 @@ int my_copy(const char *from, const char *to, myf MyFlags)
my_bool new_file_stat= 0; /* 1 if we could stat "to" */
int create_flag;
File from_file,to_file;
- char buff[IO_SIZE];
+ uchar buff[IO_SIZE];
MY_STAT stat_buff,new_stat_buff;
DBUG_ENTER("my_copy");
DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags));
@@ -80,10 +80,12 @@ int my_copy(const char *from, const char *to, myf MyFlags)
MyFlags)) < 0)
goto err;
- while ((Count=my_read(from_file,buff,IO_SIZE,MyFlags)) != 0)
+ while ((Count=my_read(from_file, buff, sizeof(buff), MyFlags)) != 0)
+ {
if (Count == (uint) -1 ||
my_write(to_file,buff,Count,MYF(MyFlags | MY_NABP)))
goto err;
+ }
if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags))
DBUG_RETURN(-1); /* Error on close */
diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c
index 01abc02058b..845b5aa4152 100644
--- a/mysys/my_gethwaddr.c
+++ b/mysys/my_gethwaddr.c
@@ -19,7 +19,7 @@
#include "mysys_priv.h"
#include <m_string.h>
-#ifndef MAIN
+#if !defined(__FreeBSD__) || defined(__linux__)
static my_bool memcpy_and_test(uchar *to, uchar *from, uint len)
{
uint i, res=1;
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index 32a5452e451..3a5b130e067 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -32,6 +32,7 @@ my_bool getopt_compare_strings(const char *s,
static longlong getopt_ll(char *arg, const struct my_option *optp, int *err);
static ulonglong getopt_ull(char *arg, const struct my_option *optp,
int *err);
+static double getopt_double(char *arg, const struct my_option *optp, int *err);
static void init_variables(const struct my_option *options);
static int setval(const struct my_option *opts, uchar* *value, char *argument,
my_bool set_maximum_value);
@@ -611,6 +612,9 @@ static int setval(const struct my_option *opts, uchar* *value, char *argument,
case GET_ULL:
*((ulonglong*) result_pos)= getopt_ull(argument, opts, &err);
break;
+ case GET_DOUBLE:
+ *((double*) result_pos)= getopt_double(argument, opts, &err);
+ break;
case GET_STR:
*((char**) result_pos)= argument;
break;
@@ -720,7 +724,7 @@ my_bool getopt_compare_strings(register const char *s, register const char *t,
be k|K for kilo, m|M for mega or g|G for giga.
*/
-static longlong eval_num_suffix (char *argument, int *error, char *option_name)
+static longlong eval_num_suffix(char *argument, int *error, char *option_name)
{
char *endchar;
longlong num;
@@ -802,6 +806,37 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp)
/*
+ Get double value withing ranges
+
+ Evaluates and returns the value that user gave as an argument to a variable.
+
+ RETURN
+ decimal value of arg
+
+ In case of an error, prints an error message and sets *err to
+ EXIT_ARGUMENT_INVALID. Otherwise err is not touched
+*/
+
+static double getopt_double(char *arg, const struct my_option *optp, int *err)
+{
+ double num;
+ int error;
+ char *end= arg + 1000; /* Big enough as *arg is \0 terminated */
+ num= my_strtod(arg, &end, &error);
+ if (end[0] != 0 || error)
+ {
+ fprintf(stderr,
+ "%s: ERROR: Invalid decimal value for option '%s'\n",
+ my_progname, optp->name);
+ *err= EXIT_ARGUMENT_INVALID;
+ return 0.0;
+ }
+ if (optp->max_value && num > (double) optp->max_value)
+ num= (double) optp->max_value;
+ return max(num, (double) optp->min_value);
+}
+
+/*
Init one value to it's default values
SYNOPSIS
@@ -838,6 +873,9 @@ static void init_one_value(const struct my_option *option, uchar* *variable,
case GET_SET:
*((ulonglong*) variable)= (ulonglong) value;
break;
+ case GET_DOUBLE:
+ *((double*) variable)= (double) value;
+ break;
case GET_STR:
/*
Do not clear variable value if it has no default value.
@@ -1052,6 +1090,9 @@ void my_print_variables(const struct my_option *options)
longlong2str(*((ulonglong*) value), buff, 10);
printf("%s\n", buff);
break;
+ case GET_DOUBLE:
+ printf("%g\n", *(double*) value);
+ break;
default:
printf("(Disabled)\n");
break;
diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c
index 2fd7eed7778..17ba1232d7a 100644
--- a/mysys/my_getsystime.c
+++ b/mysys/my_getsystime.c
@@ -29,28 +29,17 @@ ulonglong my_getsystime()
clock_gettime(CLOCK_REALTIME, &tp);
return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100;
#elif defined(__WIN__)
-#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10)
- static __int64 offset=0, freq;
LARGE_INTEGER t_cnt;
- if (!offset)
+ struct timeval tv;
+ if (query_performance_frequency)
{
- /* strictly speaking there should be a mutex to protect
- initialization section. But my_getsystime() is called from
- UUID() code, and UUID() calls are serialized with a mutex anyway
- */
- LARGE_INTEGER li;
- FILETIME ft;
- GetSystemTimeAsFileTime(&ft);
- li.LowPart=ft.dwLowDateTime;
- li.HighPart=ft.dwHighDateTime;
- offset=li.QuadPart-OFFSET_TO_EPOC;
- QueryPerformanceFrequency(&li);
- freq=li.QuadPart;
QueryPerformanceCounter(&t_cnt);
- offset-=t_cnt.QuadPart/freq*10000000+t_cnt.QuadPart%freq*10000000/freq;
+ return (t_cnt.QuadPart / query_performance_frequency * 10000000+
+ t_cnt.QuadPart % query_performance_frequency * 10000000/
+ query_performance_frequency+query_performance_offset);
}
- QueryPerformanceCounter(&t_cnt);
- return t_cnt.QuadPart/freq*10000000+t_cnt.QuadPart%freq*10000000/freq+offset;
+ gettimeofday(&tv,NULL);
+ return (ulonglong)tv.tv_sec*10000000+(ulonglong)tv.tv_usec*10;
#elif defined(__NETWARE__)
NXTime_t tm;
NXGetTime(NX_SINCE_1970, NX_NSECONDS, &tm);
@@ -62,3 +51,164 @@ ulonglong my_getsystime()
return (ulonglong)tv.tv_sec*10000000+(ulonglong)tv.tv_usec*10;
#endif
}
+
+
+/*
+ Return current time
+
+ SYNOPSIS
+ my_time()
+ flags If MY_WME is set, write error if time call fails
+
+*/
+
+#define DELTA_FOR_SECONDS LL(500000000) /* Half a second */
+
+time_t my_time(myf flags __attribute__((unused)))
+{
+#ifdef HAVE_GETHRTIME
+ 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 ((prev_gethrtime - cur_gethrtime) > DELTA_FOR_SECONDS)
+ {
+ cur_time= time(0);
+ prev_gethrtime= cur_gethrtime;
+ }
+ pthread_mutex_unlock(&THR_LOCK_time);
+ return cur_time;
+#else
+ time_t t;
+ /* 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()
+{
+ ulonglong newtime;
+#if defined(__WIN__)
+ if (query_performance_frequency)
+ {
+ QueryPerformanceCounter(&newtime);
+ newtime/= (query_performance_frequency * 1000000);
+ }
+ else
+ newtime= (GetTickCount() * 1000; /* GetTickCount only returns milliseconds */
+#elif defined(HAVE_GETHRTIME)
+ return gethrtime()/1000;
+#else
+ 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;
+#endif /* defined(__WIN__) */
+ return newtime;
+}
+
+
+/*
+ Return time in seconds and timer in microseconds
+
+ 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
+ Same as my_micro_time()
+
+ RETURN
+ Value in microseconds from some undefined point in time
+*/
+
+ulonglong my_micro_time_and_time(time_t *time_arg)
+{
+ ulonglong newtime;
+#if defined(__WIN__)
+ if (query_performance_frequency)
+ {
+ QueryPerformanceCounter((LARGE_INTEGER *) &newtime);
+ newtime/= (query_performance_frequency * 1000000);
+ }
+ else
+ newtime= (GetTickCount() * 1000; /* GetTickCount only returns milliseconds */
+ (void) time(time_arg);
+#else
+ 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;
+#endif /* defined(__WIN__) */
+ return newtime;
+}
+
+
+/*
+ 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)))
+{
+#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__) */
+}
+
diff --git a/mysys/my_init.c b/mysys/my_init.c
index c1337205eb4..8281d7ced99 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -371,6 +371,28 @@ static void my_win_init(void)
/* chiude la chiave */
RegCloseKey(hSoftMysql) ;
+
+ /* The following is used by time functions */
+#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10)
+#define MS 10000000
+ {
+ FILETIME ft;
+ LARGE_INTEGER li, t_cnt;
+ DBUG_ASSERT(sizeof(LARGE_INTEGER) == sizeof(query_performance_frequency));
+ if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency))
+ 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 * MS +
+ t_cnt.QuadPart % query_performance_frequency * MS /
+ query_performance_frequency);
+ }
+ }
DBUG_VOID_RETURN ;
}
diff --git a/mysys/my_static.c b/mysys/my_static.c
index 472cf3b5084..92c959c4c6c 100644
--- a/mysys/my_static.c
+++ b/mysys/my_static.c
@@ -93,6 +93,11 @@ int (*error_handler_hook)(uint error,const char *str,myf MyFlags)=
int (*fatal_error_handler_hook)(uint error,const char *str,myf MyFlags)=
my_message_no_curses;
+#ifdef __WIN__
+/* from my_getsystime.c */
+ulonglong query_performance_frequency, query_performance_offset;
+#endif
+
/* How to disable options */
my_bool NEAR my_disable_locking=0;
my_bool NEAR my_disable_async_io=0;
diff --git a/mysys/my_static.h b/mysys/my_static.h
index 66e6ea1c280..0eca196c1c9 100644
--- a/mysys/my_static.h
+++ b/mysys/my_static.h
@@ -66,6 +66,8 @@ extern struct st_irem *sf_malloc_root;
extern struct st_my_file_info my_file_info_default[MY_NFILE];
+extern ulonglong query_performance_frequency, query_performance_offset;
+
#if defined(THREAD) && !defined(__WIN__)
extern sigset_t my_signals; /* signals blocked by mf_brkhant */
#endif
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index cc33ac3f21c..8b935c895c8 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -30,7 +30,7 @@ pthread_key(struct st_my_thread_var, THR_KEY_mysys);
#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_net, THR_LOCK_charset, THR_LOCK_threads, THR_LOCK_time;
pthread_cond_t THR_COND_threads;
uint THR_thread_count= 0;
uint my_thread_end_wait_time= 5;
@@ -146,6 +146,7 @@ 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();
@@ -202,6 +203,7 @@ void my_thread_global_end(void)
pthread_mutex_destroy(&THR_LOCK_myisam);
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)
{
diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h
index 709cfed969a..6e0959ae08c 100644
--- a/mysys/mysys_priv.h
+++ b/mysys/mysys_priv.h
@@ -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;
+extern pthread_mutex_t THR_LOCK_charset, THR_LOCK_time;
#else
#include <my_no_pthread.h>
#endif
diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c
index 81093be3678..2934e724724 100644
--- a/mysys/thr_alarm.c
+++ b/mysys/thr_alarm.c
@@ -157,7 +157,7 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
DBUG_ENTER("thr_alarm");
DBUG_PRINT("enter",("thread: %s sec: %d",my_thread_name(),sec));
- now=(ulong) time((time_t*) 0);
+ now=(ulong) my_time(0);
pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
pthread_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */
if (alarm_aborted > 0)
@@ -351,7 +351,7 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused)))
}
else
{
- ulong now=(ulong) time((time_t*) 0);
+ ulong now=(ulong) my_time(0);
ulong next=now+10-(now%10);
while ((alarm_data=(ALARM*) queue_top(&alarm_queue))->expire_time <= now)
{
@@ -480,7 +480,7 @@ void thr_alarm_info(ALARM_INFO *info)
info->max_used_alarms= max_used_alarms;
if ((info->active_alarms= alarm_queue.elements))
{
- ulong now=(ulong) time((time_t*) 0);
+ ulong now=(ulong) my_time(0);
long time_diff;
ALARM *alarm_data= (ALARM*) queue_top(&alarm_queue);
time_diff= (long) (alarm_data->expire_time - now);
@@ -528,7 +528,7 @@ static void *alarm_handler(void *arg __attribute__((unused)))
{
if (alarm_queue.elements)
{
- ulong sleep_time,now=time((time_t*) 0);
+ ulong sleep_time,now= my_time(0);
if (alarm_aborted)
sleep_time=now+1;
else
@@ -685,7 +685,7 @@ static void *test_thread(void *arg)
for (i=1 ; i <= 10 ; i++)
{
wait_time=param ? 11-i : i;
- start_time=time((time_t*) 0);
+ start_time= my_time(0);
if (thr_alarm(&got_alarm,wait_time,0))
{
printf("Thread: %s Alarms aborted\n",my_thread_name());
@@ -747,7 +747,7 @@ static void *test_thread(void *arg)
}
}
printf("Thread: %s Slept for %d (%d) sec\n",my_thread_name(),
- (int) (time((time_t*) 0)-start_time), wait_time); fflush(stdout);
+ (int) (my_time(0)-start_time), wait_time); fflush(stdout);
thr_end_alarm(&got_alarm);
fflush(stdout);
}