mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / innobase / ut / ut0ut.c
blob3b26d83bbb9efea9efe010702f94f317194efc9b
1 /*******************************************************************
2 Various utilities for Innobase.
4 (c) 1994, 1995 Innobase Oy
6 Created 5/11/1994 Heikki Tuuri
7 ********************************************************************/
9 #include "ut0ut.h"
11 #ifdef UNIV_NONINL
12 #include "ut0ut.ic"
13 #endif
15 #include <stdarg.h>
16 #include <string.h>
17 #include <ctype.h>
19 #include "ut0sort.h"
20 #include "trx0trx.h"
21 #include "ha_prototypes.h"
22 #include "mysql_com.h" /* NAME_LEN */
24 ibool ut_always_false = FALSE;
26 #ifdef __WIN__
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).*/
36 static
37 int
38 ut_gettimeofday(
39 /*============*/
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 */
44 FILETIME ft;
45 ib_longlong tm;
47 if (!tv) {
48 errno = EINVAL;
49 return(-1);
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
58 does not work */
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);
69 return(0);
71 #else
72 #define ut_gettimeofday gettimeofday
73 #endif
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. */
80 ulint
81 ut_get_high32(
82 /*==========*/
83 /* out: a >> 32 */
84 ulint a) /* in: ulint */
86 ib_longlong i;
88 i = (ib_longlong)a;
90 i = i >> 32;
92 return((ulint)i);
95 /************************************************************
96 The following function returns elapsed CPU time in milliseconds. */
98 ulint
99 ut_clock(void)
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. */
108 ib_time_t
109 ut_time(void)
110 /*=========*/
112 return(time(NULL));
115 /**************************************************************
116 Returns system time.
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
119 error. */
122 ut_usectime(
123 /*========*/
124 /* out: 0 on success, -1 otherwise */
125 ulint* sec, /* out: seconds since the Epoch */
126 ulint* ms) /* out: microseconds since the Epoch+*sec */
128 struct timeval tv;
129 int ret;
130 int errno_gettimeofday;
131 int i;
133 for (i = 0; i < 10; i++) {
135 ret = ut_gettimeofday(&tv, NULL);
137 if (ret == -1) {
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;
144 } else {
145 break;
149 if (ret != -1) {
150 *sec = (ulint) tv.tv_sec;
151 *ms = (ulint) tv.tv_usec;
154 return(ret);
157 /**************************************************************
158 Returns the difference of two times in seconds. */
160 double
161 ut_difftime(
162 /*========*/
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. */
173 void
174 ut_print_timestamp(
175 /*===============*/
176 FILE* file) /* in: file where to print */
178 #ifdef __WIN__
179 SYSTEMTIME cal_tm;
181 GetLocalTime(&cal_tm);
183 fprintf(file,"%02d%02d%02d %2d:%02d:%02d",
184 (int)cal_tm.wYear % 100,
185 (int)cal_tm.wMonth,
186 (int)cal_tm.wDay,
187 (int)cal_tm.wHour,
188 (int)cal_tm.wMinute,
189 (int)cal_tm.wSecond);
190 #else
191 struct tm cal_tm;
192 struct tm* cal_tm_ptr;
193 time_t tm;
195 time(&tm);
197 #ifdef HAVE_LOCALTIME_R
198 localtime_r(&tm, &cal_tm);
199 cal_tm_ptr = &cal_tm;
200 #else
201 cal_tm_ptr = localtime(&tm);
202 #endif
203 fprintf(file,"%02d%02d%02d %2d:%02d:%02d",
204 cal_tm_ptr->tm_year % 100,
205 cal_tm_ptr->tm_mon + 1,
206 cal_tm_ptr->tm_mday,
207 cal_tm_ptr->tm_hour,
208 cal_tm_ptr->tm_min,
209 cal_tm_ptr->tm_sec);
210 #endif
213 /**************************************************************
214 Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */
216 void
217 ut_sprintf_timestamp(
218 /*=================*/
219 char* buf) /* in: buffer where to sprintf */
221 #ifdef __WIN__
222 SYSTEMTIME cal_tm;
224 GetLocalTime(&cal_tm);
226 sprintf(buf, "%02d%02d%02d %2d:%02d:%02d",
227 (int)cal_tm.wYear % 100,
228 (int)cal_tm.wMonth,
229 (int)cal_tm.wDay,
230 (int)cal_tm.wHour,
231 (int)cal_tm.wMinute,
232 (int)cal_tm.wSecond);
233 #else
234 struct tm cal_tm;
235 struct tm* cal_tm_ptr;
236 time_t tm;
238 time(&tm);
240 #ifdef HAVE_LOCALTIME_R
241 localtime_r(&tm, &cal_tm);
242 cal_tm_ptr = &cal_tm;
243 #else
244 cal_tm_ptr = localtime(&tm);
245 #endif
246 sprintf(buf, "%02d%02d%02d %2d:%02d:%02d",
247 cal_tm_ptr->tm_year % 100,
248 cal_tm_ptr->tm_mon + 1,
249 cal_tm_ptr->tm_mday,
250 cal_tm_ptr->tm_hour,
251 cal_tm_ptr->tm_min,
252 cal_tm_ptr->tm_sec);
253 #endif
256 /**************************************************************
257 Sprintfs a timestamp to a buffer with no spaces and with ':' characters
258 replaced by '_'. */
260 void
261 ut_sprintf_timestamp_without_extra_chars(
262 /*=====================================*/
263 char* buf) /* in: buffer where to sprintf */
265 #ifdef __WIN__
266 SYSTEMTIME cal_tm;
268 GetLocalTime(&cal_tm);
270 sprintf(buf, "%02d%02d%02d_%2d_%02d_%02d",
271 (int)cal_tm.wYear % 100,
272 (int)cal_tm.wMonth,
273 (int)cal_tm.wDay,
274 (int)cal_tm.wHour,
275 (int)cal_tm.wMinute,
276 (int)cal_tm.wSecond);
277 #else
278 struct tm cal_tm;
279 struct tm* cal_tm_ptr;
280 time_t tm;
282 time(&tm);
284 #ifdef HAVE_LOCALTIME_R
285 localtime_r(&tm, &cal_tm);
286 cal_tm_ptr = &cal_tm;
287 #else
288 cal_tm_ptr = localtime(&tm);
289 #endif
290 sprintf(buf, "%02d%02d%02d_%2d_%02d_%02d",
291 cal_tm_ptr->tm_year % 100,
292 cal_tm_ptr->tm_mon + 1,
293 cal_tm_ptr->tm_mday,
294 cal_tm_ptr->tm_hour,
295 cal_tm_ptr->tm_min,
296 cal_tm_ptr->tm_sec);
297 #endif
300 /**************************************************************
301 Returns current year, month, day. */
303 void
304 ut_get_year_month_day(
305 /*==================*/
306 ulint* year, /* out: current year */
307 ulint* month, /* out: month */
308 ulint* day) /* out: day */
310 #ifdef __WIN__
311 SYSTEMTIME cal_tm;
313 GetLocalTime(&cal_tm);
315 *year = (ulint)cal_tm.wYear;
316 *month = (ulint)cal_tm.wMonth;
317 *day = (ulint)cal_tm.wDay;
318 #else
319 struct tm cal_tm;
320 struct tm* cal_tm_ptr;
321 time_t tm;
323 time(&tm);
325 #ifdef HAVE_LOCALTIME_R
326 localtime_r(&tm, &cal_tm);
327 cal_tm_ptr = &cal_tm;
328 #else
329 cal_tm_ptr = localtime(&tm);
330 #endif
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;
334 #endif
337 /*****************************************************************
338 Runs an idle loop on CPU. The argument gives the desired delay
339 in microseconds on 100 MHz Pentium + Visual C++. */
341 ulint
342 ut_delay(
343 /*=====*/
344 /* out: dummy value */
345 ulint delay) /* in: delay in microseconds on 100 MHz Pentium */
347 ulint i, j;
349 j = 0;
351 for (i = 0; i < delay * 50; i++) {
352 j += i;
355 if (ut_always_false) {
356 ut_always_false = (ibool) j;
359 return(j);
362 /*****************************************************************
363 Prints the contents of a memory buffer in hex and ascii. */
365 void
366 ut_print_buf(
367 /*=========*/
368 FILE* file, /* in: file where to print */
369 const void* buf, /* in: memory buffer */
370 ulint len) /* in: length of the buffer */
372 const byte* data;
373 ulint i;
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);
392 putc(';', file);
395 /****************************************************************
396 Sort function for ulint arrays. */
398 void
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,
403 ut_ulint_cmp);
406 /*****************************************************************
407 Calculates fast the number rounded up to the nearest power of 2. */
409 ulint
410 ut_2_power_up(
411 /*==========*/
412 /* out: first power of 2 which is >= n */
413 ulint n) /* in: number != 0 */
415 ulint res;
417 res = 1;
419 ut_ad(n > 0);
421 while (res < n) {
422 res = res * 2;
425 return(res);
428 /**************************************************************************
429 Outputs a NUL-terminated file name, quoted with apostrophes. */
431 void
432 ut_print_filename(
433 /*==============*/
434 FILE* f, /* in: output stream */
435 const char* name) /* in: name to print */
437 putc('\'', f);
438 for (;;) {
439 int c = *name++;
440 switch (c) {
441 case 0:
442 goto done;
443 case '\'':
444 putc(c, f);
445 /* fall through */
446 default:
447 putc(c, f);
450 done:
451 putc('\'', f);
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. */
460 void
461 ut_print_name(
462 /*==========*/
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. */
478 void
479 ut_print_namel(
480 /*===========*/
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];
491 const char* bufend;
493 bufend = innobase_convert_name(buf, sizeof buf,
494 name, namelen,
495 trx ? trx->mysql_thd : NULL,
496 table_id);
498 fwrite(buf, 1, bufend - buf, f);
501 /**************************************************************************
502 Catenate files. */
504 void
505 ut_copy_file(
506 /*=========*/
507 FILE* dest, /* in: output file */
508 FILE* src) /* in: input file to be appended to output */
510 long len = ftell(src);
511 char buf[4096];
513 rewind(src);
514 do {
515 size_t maxs = len < (long) sizeof buf
516 ? (size_t) len
517 : sizeof buf;
518 size_t size = fread(buf, 1, maxs, src);
519 fwrite(buf, 1, size, dest);
520 len -= (long) size;
521 if (size < maxs) {
522 break;
524 } while (len > 0);
527 /**************************************************************************
528 snprintf(). */
530 #ifdef __WIN__
531 #include <stdarg.h>
533 ut_snprintf(
534 /* out: number of characters that would
535 have been printed if the size were
536 unlimited, not including the terminating
537 '\0'. */
538 char* str, /* out: string */
539 size_t size, /* in: str size */
540 const char* fmt, /* in: format */
541 ...) /* in: format values */
543 int res;
544 va_list ap1;
545 va_list ap2;
547 va_start(ap1, fmt);
548 va_start(ap2, fmt);
550 res = _vscprintf(fmt, ap1);
551 ut_a(res != -1);
553 if (size > 0) {
554 _vsnprintf(str, size, fmt, ap2);
556 if ((size_t) res >= size) {
557 str[size - 1] = '\0';
561 va_end(ap1);
562 va_end(ap2);
564 return(res);
566 #endif /* __WIN__ */