1
/*****************************************************************************
3
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
4
Copyright (c) 2009, Sun Microsystems, Inc.
6
Portions of this file contain modifications contributed and copyrighted by
7
Sun Microsystems, Inc. Those modifications are gratefully acknowledged and
8
are described briefly in the InnoDB documentation. The contributions by
9
Sun Microsystems are incorporated with their permission, and subject to the
10
conditions contained in the file COPYING.Sun_Microsystems.
12
This program is free software; you can redistribute it and/or modify it under
13
the terms of the GNU General Public License as published by the Free Software
14
Foundation; version 2 of the License.
16
This program is distributed in the hope that it will be useful, but WITHOUT
17
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License along with
21
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22
Place, Suite 330, Boston, MA 02111-1307 USA
24
*****************************************************************************/
26
/***************************************************************//**
28
Various utilities for Innobase.
30
Created 5/11/1994 Heikki Tuuri
31
********************************************************************/
43
#ifndef UNIV_HOTBACKUP
45
# include "ha_prototypes.h"
46
# include "mysql_com.h" /* NAME_LEN */
47
#endif /* UNIV_HOTBACKUP */
49
/** A constant to prevent the compiler from optimizing ut_delay() away. */
50
UNIV_INTERN ibool ut_always_false = FALSE;
53
/*****************************************************************//**
54
NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix
55
epoch starts from 1970/1/1. For selection of constant see:
56
http://support.microsoft.com/kb/167296/ */
57
#define WIN_TO_UNIX_DELTA_USEC ((ib_int64_t) 11644473600000000ULL)
60
/*****************************************************************//**
61
This is the Windows version of gettimeofday(2).
62
@return 0 if all OK else -1 */
67
struct timeval* tv, /*!< out: Values are relative to Unix epoch */
68
void* tz) /*!< in: not used */
78
GetSystemTimeAsFileTime(&ft);
80
tm = (ib_int64_t) ft.dwHighDateTime << 32;
81
tm |= ft.dwLowDateTime;
83
ut_a(tm >= 0); /* If tm wraps over to negative, the quotient / 10
86
tm /= 10; /* Convert from 100 nsec periods to usec */
88
/* If we don't convert to the Unix epoch the value for
89
struct timeval::tv_sec will overflow.*/
90
tm -= WIN_TO_UNIX_DELTA_USEC;
92
tv->tv_sec = (long) (tm / 1000000L);
93
tv->tv_usec = (long) (tm % 1000000L);
98
/** An alias for gettimeofday(2). On Microsoft Windows, we have to
99
reimplement this function. */
100
#define ut_gettimeofday gettimeofday
103
/********************************************************//**
104
Gets the high 32 bits in a ulint. That is makes a shift >> 32,
105
but since there seem to be compiler bugs in both gcc and Visual C++,
106
we do this by a special conversion.
112
ulint a) /*!< in: ulint */
123
/**********************************************************//**
124
Returns system time. We do not specify the format of the time returned:
125
the only way to manipulate it is to use the function ut_difftime.
126
@return system time */
135
#ifndef UNIV_HOTBACKUP
136
/**********************************************************//**
138
Upon successful completion, the value 0 is returned; otherwise the
139
value -1 is returned and the global variable errno is set to indicate the
141
@return 0 on success, -1 otherwise */
146
ulint* sec, /*!< out: seconds since the Epoch */
147
ulint* ms) /*!< out: microseconds since the Epoch+*sec */
151
int errno_gettimeofday;
154
for (i = 0; i < 10; i++) {
156
ret = ut_gettimeofday(&tv, NULL);
159
errno_gettimeofday = errno;
160
ut_print_timestamp(stderr);
161
fprintf(stderr, " InnoDB: gettimeofday(): %s\n",
162
strerror(errno_gettimeofday));
163
os_thread_sleep(100000); /* 0.1 sec */
164
errno = errno_gettimeofday;
171
*sec = (ulint) tv.tv_sec;
172
*ms = (ulint) tv.tv_usec;
178
/**********************************************************//**
179
Returns the number of microseconds since epoch. Similar to
180
time(3), the return value is also stored in *tloc, provided
181
that tloc is non-NULL.
182
@return us since epoch */
187
ullint* tloc) /*!< out: us since epoch, if non-NULL */
192
ut_gettimeofday(&tv, NULL);
194
us = (ullint) tv.tv_sec * 1000000 + tv.tv_usec;
203
/**********************************************************//**
204
Returns the number of milliseconds since some epoch. The
205
value may wrap around. It should only be used for heuristic
207
@return ms since epoch */
215
ut_gettimeofday(&tv, NULL);
217
return((ulint) tv.tv_sec * 1000 + tv.tv_usec / 1000);
219
#endif /* !UNIV_HOTBACKUP */
221
/**********************************************************//**
222
Returns the difference of two times in seconds.
223
@return time2 - time1 expressed in seconds */
228
ib_time_t time2, /*!< in: time */
229
ib_time_t time1) /*!< in: time */
231
return(difftime(time2, time1));
234
/**********************************************************//**
235
Prints a timestamp to a file. */
240
FILE* file) /*!< in: file where to print */
245
GetLocalTime(&cal_tm);
247
fprintf(file,"%02d%02d%02d %2d:%02d:%02d",
248
(int)cal_tm.wYear % 100,
253
(int)cal_tm.wSecond);
256
struct tm* cal_tm_ptr;
261
#ifdef HAVE_LOCALTIME_R
262
localtime_r(&tm, &cal_tm);
263
cal_tm_ptr = &cal_tm;
265
cal_tm_ptr = localtime(&tm);
267
fprintf(file,"%02d%02d%02d %2d:%02d:%02d",
268
cal_tm_ptr->tm_year % 100,
269
cal_tm_ptr->tm_mon + 1,
277
/**********************************************************//**
278
Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */
281
ut_sprintf_timestamp(
282
/*=================*/
283
char* buf) /*!< in: buffer where to sprintf */
288
GetLocalTime(&cal_tm);
290
sprintf(buf, "%02d%02d%02d %2d:%02d:%02d",
291
(int)cal_tm.wYear % 100,
296
(int)cal_tm.wSecond);
299
struct tm* cal_tm_ptr;
304
#ifdef HAVE_LOCALTIME_R
305
localtime_r(&tm, &cal_tm);
306
cal_tm_ptr = &cal_tm;
308
cal_tm_ptr = localtime(&tm);
310
sprintf(buf, "%02d%02d%02d %2d:%02d:%02d",
311
cal_tm_ptr->tm_year % 100,
312
cal_tm_ptr->tm_mon + 1,
320
#ifdef UNIV_HOTBACKUP
321
/**********************************************************//**
322
Sprintfs a timestamp to a buffer with no spaces and with ':' characters
326
ut_sprintf_timestamp_without_extra_chars(
327
/*=====================================*/
328
char* buf) /*!< in: buffer where to sprintf */
333
GetLocalTime(&cal_tm);
335
sprintf(buf, "%02d%02d%02d_%2d_%02d_%02d",
336
(int)cal_tm.wYear % 100,
341
(int)cal_tm.wSecond);
344
struct tm* cal_tm_ptr;
349
#ifdef HAVE_LOCALTIME_R
350
localtime_r(&tm, &cal_tm);
351
cal_tm_ptr = &cal_tm;
353
cal_tm_ptr = localtime(&tm);
355
sprintf(buf, "%02d%02d%02d_%2d_%02d_%02d",
356
cal_tm_ptr->tm_year % 100,
357
cal_tm_ptr->tm_mon + 1,
365
/**********************************************************//**
366
Returns current year, month, day. */
369
ut_get_year_month_day(
370
/*==================*/
371
ulint* year, /*!< out: current year */
372
ulint* month, /*!< out: month */
373
ulint* day) /*!< out: day */
378
GetLocalTime(&cal_tm);
380
*year = (ulint)cal_tm.wYear;
381
*month = (ulint)cal_tm.wMonth;
382
*day = (ulint)cal_tm.wDay;
385
struct tm* cal_tm_ptr;
390
#ifdef HAVE_LOCALTIME_R
391
localtime_r(&tm, &cal_tm);
392
cal_tm_ptr = &cal_tm;
394
cal_tm_ptr = localtime(&tm);
396
*year = (ulint)cal_tm_ptr->tm_year + 1900;
397
*month = (ulint)cal_tm_ptr->tm_mon + 1;
398
*day = (ulint)cal_tm_ptr->tm_mday;
401
#endif /* UNIV_HOTBACKUP */
403
#ifndef UNIV_HOTBACKUP
404
/*************************************************************//**
405
Runs an idle loop on CPU. The argument gives the desired delay
406
in microseconds on 100 MHz Pentium + Visual C++.
407
@return dummy value */
412
ulint delay) /*!< in: delay in microseconds on 100 MHz Pentium */
418
for (i = 0; i < delay * 50; i++) {
423
if (ut_always_false) {
424
ut_always_false = (ibool) j;
429
#endif /* !UNIV_HOTBACKUP */
431
/*************************************************************//**
432
Prints the contents of a memory buffer in hex and ascii. */
437
FILE* file, /*!< in: file where to print */
438
const void* buf, /*!< in: memory buffer */
439
ulint len) /*!< in: length of the buffer */
444
UNIV_MEM_ASSERT_RW(buf, len);
446
fprintf(file, " len %lu; hex ", len);
448
for (data = (const byte*)buf, i = 0; i < len; i++) {
449
fprintf(file, "%02lx", (ulong)*data++);
452
fputs("; asc ", file);
454
data = (const byte*)buf;
456
for (i = 0; i < len; i++) {
457
int c = (int) *data++;
458
putc(isprint(c) ? c : ' ', file);
464
/*************************************************************//**
465
Calculates fast the number rounded up to the nearest power of 2.
466
@return first power of 2 which is >= n */
471
ulint n) /*!< in: number != 0 */
486
/**********************************************************************//**
487
Outputs a NUL-terminated file name, quoted with apostrophes. */
492
FILE* f, /*!< in: output stream */
493
const char* name) /*!< in: name to print */
511
#ifndef UNIV_HOTBACKUP
512
/**********************************************************************//**
513
Outputs a fixed-length string, quoted as an SQL identifier.
514
If the string contains a slash '/', the string will be
515
output as two identifiers separated by a period (.),
516
as in SQL database_name.identifier. */
521
FILE* f, /*!< in: output stream */
522
trx_t* trx, /*!< in: transaction */
523
ibool table_id,/*!< in: TRUE=print a table name,
524
FALSE=print other identifier */
525
const char* name) /*!< in: name to print */
527
ut_print_namel(f, trx, table_id, name, strlen(name));
530
/**********************************************************************//**
531
Outputs a fixed-length string, quoted as an SQL identifier.
532
If the string contains a slash '/', the string will be
533
output as two identifiers separated by a period (.),
534
as in SQL database_name.identifier. */
539
FILE* f, /*!< in: output stream */
540
trx_t* trx, /*!< in: transaction (NULL=no quotes) */
541
ibool table_id,/*!< in: TRUE=print a table name,
542
FALSE=print other identifier */
543
const char* name, /*!< in: name to print */
544
ulint namelen)/*!< in: length of name */
546
/* 2 * NAME_LEN for database and table name,
547
and some slack for the #mysql50# prefix and quotes */
548
char buf[3 * NAME_LEN];
551
bufend = innobase_convert_name(buf, sizeof buf,
553
trx ? trx->mysql_thd : NULL,
556
fwrite(buf, 1, bufend - buf, f);
559
/**********************************************************************//**
565
FILE* dest, /*!< in: output file */
566
FILE* src) /*!< in: input file to be appended to output */
568
long len = ftell(src);
573
size_t maxs = len < (long) sizeof buf
576
size_t size = fread(buf, 1, maxs, src);
577
fwrite(buf, 1, size, dest);
584
#endif /* !UNIV_HOTBACKUP */
588
/**********************************************************************//**
589
A substitute for snprintf(3), formatted output conversion into
591
@return number of characters that would have been printed if the size
592
were unlimited, not including the terminating '\0'. */
597
char* str, /*!< out: string */
598
size_t size, /*!< in: str size */
599
const char* fmt, /*!< in: format */
600
...) /*!< in: format values */
609
res = _vscprintf(fmt, ap1);
613
_vsnprintf(str, size, fmt, ap2);
615
if ((size_t) res >= size) {
616
str[size - 1] = '\0';