1 /*******************************************************************
2 Various utilities for Innobase.
4 (c) 1994, 1995 Innobase Oy
6 Created 5/11/1994 Heikki Tuuri
7 ********************************************************************/
21 #include "ha_prototypes.h"
22 #include "mysql_com.h" /* NAME_LEN */
24 ibool ut_always_false
= FALSE
;
27 /*********************************************************************
28 NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix
29 epoch starts from 1970/1/1. For selection of constant see:
30 http://support.microsoft.com/kb/167296/ */
31 #define WIN_TO_UNIX_DELTA_USEC ((ib_longlong) 11644473600000000ULL)
34 /*********************************************************************
35 This is the Windows version of gettimeofday(2).*/
40 /* out: 0 if all OK else -1 */
41 struct timeval
* tv
, /* out: Values are relative to Unix epoch */
42 void* tz
) /* in: not used */
52 GetSystemTimeAsFileTime(&ft
);
54 tm
= (ib_longlong
) ft
.dwHighDateTime
<< 32;
55 tm
|= ft
.dwLowDateTime
;
57 ut_a(tm
>= 0); /* If tm wraps over to negative, the quotient / 10
60 tm
/= 10; /* Convert from 100 nsec periods to usec */
62 /* If we don't convert to the Unix epoch the value for
63 struct timeval::tv_sec will overflow.*/
64 tm
-= WIN_TO_UNIX_DELTA_USEC
;
66 tv
->tv_sec
= (long) (tm
/ 1000000L);
67 tv
->tv_usec
= (long) (tm
% 1000000L);
72 #define ut_gettimeofday gettimeofday
75 /************************************************************
76 Gets the high 32 bits in a ulint. That is makes a shift >> 32,
77 but since there seem to be compiler bugs in both gcc and Visual C++,
78 we do this by a special conversion. */
84 ulint a
) /* in: ulint */
95 /************************************************************
96 The following function returns elapsed CPU time in milliseconds. */
101 return((clock() * 1000) / CLOCKS_PER_SEC
);
104 /**************************************************************
105 Returns system time. We do not specify the format of the time returned:
106 the only way to manipulate it is to use the function ut_difftime. */
115 /**************************************************************
117 Upon successful completion, the value 0 is returned; otherwise the
118 value -1 is returned and the global variable errno is set to indicate the
124 /* out: 0 on success, -1 otherwise */
125 ulint
* sec
, /* out: seconds since the Epoch */
126 ulint
* ms
) /* out: microseconds since the Epoch+*sec */
130 int errno_gettimeofday
;
133 for (i
= 0; i
< 10; i
++) {
135 ret
= ut_gettimeofday(&tv
, NULL
);
138 errno_gettimeofday
= errno
;
139 ut_print_timestamp(stderr
);
140 fprintf(stderr
, " InnoDB: gettimeofday(): %s\n",
141 strerror(errno_gettimeofday
));
142 os_thread_sleep(100000); /* 0.1 sec */
143 errno
= errno_gettimeofday
;
150 *sec
= (ulint
) tv
.tv_sec
;
151 *ms
= (ulint
) tv
.tv_usec
;
157 /**************************************************************
158 Returns the difference of two times in seconds. */
163 /* out: time2 - time1 expressed in seconds */
164 ib_time_t time2
, /* in: time */
165 ib_time_t time1
) /* in: time */
167 return(difftime(time2
, time1
));
170 /**************************************************************
171 Prints a timestamp to a file. */
176 FILE* file
) /* in: file where to print */
181 GetLocalTime(&cal_tm
);
183 fprintf(file
,"%02d%02d%02d %2d:%02d:%02d",
184 (int)cal_tm
.wYear
% 100,
189 (int)cal_tm
.wSecond
);
192 struct tm
* cal_tm_ptr
;
197 #ifdef HAVE_LOCALTIME_R
198 localtime_r(&tm
, &cal_tm
);
199 cal_tm_ptr
= &cal_tm
;
201 cal_tm_ptr
= localtime(&tm
);
203 fprintf(file
,"%02d%02d%02d %2d:%02d:%02d",
204 cal_tm_ptr
->tm_year
% 100,
205 cal_tm_ptr
->tm_mon
+ 1,
213 /**************************************************************
214 Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */
217 ut_sprintf_timestamp(
218 /*=================*/
219 char* buf
) /* in: buffer where to sprintf */
224 GetLocalTime(&cal_tm
);
226 sprintf(buf
, "%02d%02d%02d %2d:%02d:%02d",
227 (int)cal_tm
.wYear
% 100,
232 (int)cal_tm
.wSecond
);
235 struct tm
* cal_tm_ptr
;
240 #ifdef HAVE_LOCALTIME_R
241 localtime_r(&tm
, &cal_tm
);
242 cal_tm_ptr
= &cal_tm
;
244 cal_tm_ptr
= localtime(&tm
);
246 sprintf(buf
, "%02d%02d%02d %2d:%02d:%02d",
247 cal_tm_ptr
->tm_year
% 100,
248 cal_tm_ptr
->tm_mon
+ 1,
256 /**************************************************************
257 Sprintfs a timestamp to a buffer with no spaces and with ':' characters
261 ut_sprintf_timestamp_without_extra_chars(
262 /*=====================================*/
263 char* buf
) /* in: buffer where to sprintf */
268 GetLocalTime(&cal_tm
);
270 sprintf(buf
, "%02d%02d%02d_%2d_%02d_%02d",
271 (int)cal_tm
.wYear
% 100,
276 (int)cal_tm
.wSecond
);
279 struct tm
* cal_tm_ptr
;
284 #ifdef HAVE_LOCALTIME_R
285 localtime_r(&tm
, &cal_tm
);
286 cal_tm_ptr
= &cal_tm
;
288 cal_tm_ptr
= localtime(&tm
);
290 sprintf(buf
, "%02d%02d%02d_%2d_%02d_%02d",
291 cal_tm_ptr
->tm_year
% 100,
292 cal_tm_ptr
->tm_mon
+ 1,
300 /**************************************************************
301 Returns current year, month, day. */
304 ut_get_year_month_day(
305 /*==================*/
306 ulint
* year
, /* out: current year */
307 ulint
* month
, /* out: month */
308 ulint
* day
) /* out: day */
313 GetLocalTime(&cal_tm
);
315 *year
= (ulint
)cal_tm
.wYear
;
316 *month
= (ulint
)cal_tm
.wMonth
;
317 *day
= (ulint
)cal_tm
.wDay
;
320 struct tm
* cal_tm_ptr
;
325 #ifdef HAVE_LOCALTIME_R
326 localtime_r(&tm
, &cal_tm
);
327 cal_tm_ptr
= &cal_tm
;
329 cal_tm_ptr
= localtime(&tm
);
331 *year
= (ulint
)cal_tm_ptr
->tm_year
+ 1900;
332 *month
= (ulint
)cal_tm_ptr
->tm_mon
+ 1;
333 *day
= (ulint
)cal_tm_ptr
->tm_mday
;
337 /*****************************************************************
338 Runs an idle loop on CPU. The argument gives the desired delay
339 in microseconds on 100 MHz Pentium + Visual C++. */
344 /* out: dummy value */
345 ulint delay
) /* in: delay in microseconds on 100 MHz Pentium */
351 for (i
= 0; i
< delay
* 50; i
++) {
355 if (ut_always_false
) {
356 ut_always_false
= (ibool
) j
;
362 /*****************************************************************
363 Prints the contents of a memory buffer in hex and ascii. */
368 FILE* file
, /* in: file where to print */
369 const void* buf
, /* in: memory buffer */
370 ulint len
) /* in: length of the buffer */
375 UNIV_MEM_ASSERT_RW(buf
, len
);
377 fprintf(file
, " len %lu; hex ", len
);
379 for (data
= (const byte
*)buf
, i
= 0; i
< len
; i
++) {
380 fprintf(file
, "%02lx", (ulong
)*data
++);
383 fputs("; asc ", file
);
385 data
= (const byte
*)buf
;
387 for (i
= 0; i
< len
; i
++) {
388 int c
= (int) *data
++;
389 putc(isprint(c
) ? c
: ' ', file
);
395 /****************************************************************
396 Sort function for ulint arrays. */
399 ut_ulint_sort(ulint
* arr
, ulint
* aux_arr
, ulint low
, ulint high
)
400 /*============================================================*/
402 UT_SORT_FUNCTION_BODY(ut_ulint_sort
, arr
, aux_arr
, low
, high
,
406 /*****************************************************************
407 Calculates fast the number rounded up to the nearest power of 2. */
412 /* out: first power of 2 which is >= n */
413 ulint n
) /* in: number != 0 */
428 /**************************************************************************
429 Outputs a NUL-terminated file name, quoted with apostrophes. */
434 FILE* f
, /* in: output stream */
435 const char* name
) /* in: name to print */
454 /**************************************************************************
455 Outputs a fixed-length string, quoted as an SQL identifier.
456 If the string contains a slash '/', the string will be
457 output as two identifiers separated by a period (.),
458 as in SQL database_name.identifier. */
463 FILE* f
, /* in: output stream */
464 trx_t
* trx
, /* in: transaction */
465 ibool table_id
,/* in: TRUE=print a table name,
466 FALSE=print other identifier */
467 const char* name
) /* in: name to print */
469 ut_print_namel(f
, trx
, table_id
, name
, strlen(name
));
472 /**************************************************************************
473 Outputs a fixed-length string, quoted as an SQL identifier.
474 If the string contains a slash '/', the string will be
475 output as two identifiers separated by a period (.),
476 as in SQL database_name.identifier. */
481 FILE* f
, /* in: output stream */
482 trx_t
* trx
, /* in: transaction (NULL=no quotes) */
483 ibool table_id
,/* in: TRUE=print a table name,
484 FALSE=print other identifier */
485 const char* name
, /* in: name to print */
486 ulint namelen
)/* in: length of name */
488 /* 2 * NAME_LEN for database and table name,
489 and some slack for the #mysql50# prefix and quotes */
490 char buf
[3 * NAME_LEN
];
493 bufend
= innobase_convert_name(buf
, sizeof buf
,
495 trx
? trx
->mysql_thd
: NULL
,
498 fwrite(buf
, 1, bufend
- buf
, f
);
501 /**************************************************************************
507 FILE* dest
, /* in: output file */
508 FILE* src
) /* in: input file to be appended to output */
510 long len
= ftell(src
);
515 size_t maxs
= len
< (long) sizeof buf
518 size_t size
= fread(buf
, 1, maxs
, src
);
519 fwrite(buf
, 1, size
, dest
);
527 /**************************************************************************
534 /* out: number of characters that would
535 have been printed if the size were
536 unlimited, not including the terminating
538 char* str
, /* out: string */
539 size_t size
, /* in: str size */
540 const char* fmt
, /* in: format */
541 ...) /* in: format values */
550 res
= _vscprintf(fmt
, ap1
);
554 _vsnprintf(str
, size
, fmt
, ap2
);
556 if ((size_t) res
>= size
) {
557 str
[size
- 1] = '\0';