~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/innobase/ut/ut0ut.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*******************************************************************
 
2
Various utilities for Innobase.
 
3
 
 
4
(c) 1994, 1995 Innobase Oy
 
5
 
 
6
Created 5/11/1994 Heikki Tuuri
 
7
********************************************************************/
 
8
 
 
9
#include "ut0ut.h"
 
10
 
 
11
#ifdef UNIV_NONINL
 
12
#include "ut0ut.ic"
 
13
#endif
 
14
 
 
15
#include <stdarg.h>
 
16
#include <string.h>
 
17
#include <ctype.h>
 
18
 
 
19
#include "ut0sort.h"
 
20
#include "trx0trx.h"
 
21
#include "ha_prototypes.h"
 
22
#include "mysql_com.h" /* NAME_LEN */
 
23
 
 
24
ibool   ut_always_false = FALSE;
 
25
 
 
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)
 
32
 
 
33
 
 
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 */
 
43
{
 
44
        FILETIME        ft;
 
45
        ib_longlong     tm;
 
46
 
 
47
        if (!tv) {
 
48
                errno = EINVAL;
 
49
                return(-1);
 
50
        }
 
51
 
 
52
        GetSystemTimeAsFileTime(&ft);
 
53
 
 
54
        tm = (ib_longlong) ft.dwHighDateTime << 32;
 
55
        tm |= ft.dwLowDateTime;
 
56
 
 
57
        ut_a(tm >= 0);  /* If tm wraps over to negative, the quotient / 10
 
58
                        does not work */
 
59
 
 
60
        tm /= 10;       /* Convert from 100 nsec periods to usec */
 
61
 
 
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;
 
65
 
 
66
        tv->tv_sec  = (long) (tm / 1000000L);
 
67
        tv->tv_usec = (long) (tm % 1000000L);
 
68
 
 
69
        return(0);
 
70
}
 
71
#else
 
72
#define ut_gettimeofday         gettimeofday
 
73
#endif
 
74
 
 
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. */
 
79
 
 
80
ulint
 
81
ut_get_high32(
 
82
/*==========*/
 
83
                        /* out: a >> 32 */
 
84
        ulint   a)      /* in: ulint */
 
85
{
 
86
        ib_longlong     i;
 
87
 
 
88
        i = (ib_longlong)a;
 
89
 
 
90
        i = i >> 32;
 
91
 
 
92
        return((ulint)i);
 
93
}
 
94
 
 
95
/************************************************************
 
96
The following function returns elapsed CPU time in milliseconds. */
 
97
 
 
98
ulint
 
99
ut_clock(void)
 
100
{
 
101
        return((clock() * 1000) / CLOCKS_PER_SEC);
 
102
}
 
103
 
 
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. */
 
107
 
 
108
ib_time_t
 
109
ut_time(void)
 
110
/*=========*/
 
111
{
 
112
        return(time(NULL));
 
113
}
 
114
 
 
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. */
 
120
 
 
121
int
 
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 */
 
127
{
 
128
        struct timeval  tv;
 
129
        int             ret;
 
130
        int             errno_gettimeofday;
 
131
        int             i;
 
132
 
 
133
        for (i = 0; i < 10; i++) {
 
134
 
 
135
                ret = ut_gettimeofday(&tv, NULL);
 
136
 
 
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;
 
146
                }
 
147
        }
 
148
 
 
149
        if (ret != -1) {
 
150
                *sec = (ulint) tv.tv_sec;
 
151
                *ms  = (ulint) tv.tv_usec;
 
152
        }
 
153
 
 
154
        return(ret);
 
155
}
 
156
 
 
157
/**************************************************************
 
158
Returns the difference of two times in seconds. */
 
159
 
 
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 */
 
166
{
 
167
        return(difftime(time2, time1));
 
168
}
 
169
 
 
170
/**************************************************************
 
171
Prints a timestamp to a file. */
 
172
 
 
173
void
 
174
ut_print_timestamp(
 
175
/*===============*/
 
176
        FILE*  file) /* in: file where to print */
 
177
{
 
178
#ifdef __WIN__
 
179
        SYSTEMTIME cal_tm;
 
180
 
 
181
        GetLocalTime(&cal_tm);
 
182
 
 
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;
 
194
 
 
195
        time(&tm);
 
196
 
 
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
 
211
}
 
212
 
 
213
/**************************************************************
 
214
Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */
 
215
 
 
216
void
 
217
ut_sprintf_timestamp(
 
218
/*=================*/
 
219
        char*   buf) /* in: buffer where to sprintf */
 
220
{
 
221
#ifdef __WIN__
 
222
        SYSTEMTIME cal_tm;
 
223
 
 
224
        GetLocalTime(&cal_tm);
 
225
 
 
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;
 
237
 
 
238
        time(&tm);
 
239
 
 
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
 
254
}
 
255
 
 
256
/**************************************************************
 
257
Sprintfs a timestamp to a buffer with no spaces and with ':' characters
 
258
replaced by '_'. */
 
259
 
 
260
void
 
261
ut_sprintf_timestamp_without_extra_chars(
 
262
/*=====================================*/
 
263
        char*   buf) /* in: buffer where to sprintf */
 
264
{
 
265
#ifdef __WIN__
 
266
        SYSTEMTIME cal_tm;
 
267
 
 
268
        GetLocalTime(&cal_tm);
 
269
 
 
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;
 
281
 
 
282
        time(&tm);
 
283
 
 
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
 
298
}
 
299
 
 
300
/**************************************************************
 
301
Returns current year, month, day. */
 
302
 
 
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 */
 
309
{
 
310
#ifdef __WIN__
 
311
        SYSTEMTIME cal_tm;
 
312
 
 
313
        GetLocalTime(&cal_tm);
 
314
 
 
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;
 
322
 
 
323
        time(&tm);
 
324
 
 
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
 
335
}
 
336
 
 
337
/*****************************************************************
 
338
Runs an idle loop on CPU. The argument gives the desired delay
 
339
in microseconds on 100 MHz Pentium + Visual C++. */
 
340
 
 
341
ulint
 
342
ut_delay(
 
343
/*=====*/
 
344
                        /* out: dummy value */
 
345
        ulint   delay)  /* in: delay in microseconds on 100 MHz Pentium */
 
346
{
 
347
        ulint   i, j;
 
348
 
 
349
        j = 0;
 
350
 
 
351
        for (i = 0; i < delay * 50; i++) {
 
352
                j += i;
 
353
        }
 
354
 
 
355
        if (ut_always_false) {
 
356
                ut_always_false = (ibool) j;
 
357
        }
 
358
 
 
359
        return(j);
 
360
}
 
361
 
 
362
/*****************************************************************
 
363
Prints the contents of a memory buffer in hex and ascii. */
 
364
 
 
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 */
 
371
{
 
372
        const byte*     data;
 
373
        ulint           i;
 
374
 
 
375
        UNIV_MEM_ASSERT_RW(buf, len);
 
376
 
 
377
        fprintf(file, " len %lu; hex ", len);
 
378
 
 
379
        for (data = (const byte*)buf, i = 0; i < len; i++) {
 
380
                fprintf(file, "%02lx", (ulong)*data++);
 
381
        }
 
382
 
 
383
        fputs("; asc ", file);
 
384
 
 
385
        data = (const byte*)buf;
 
386
 
 
387
        for (i = 0; i < len; i++) {
 
388
                int     c = (int) *data++;
 
389
                putc(isprint(c) ? c : ' ', file);
 
390
        }
 
391
 
 
392
        putc(';', file);
 
393
}
 
394
 
 
395
/****************************************************************
 
396
Sort function for ulint arrays. */
 
397
 
 
398
void
 
399
ut_ulint_sort(ulint* arr, ulint* aux_arr, ulint low, ulint high)
 
400
/*============================================================*/
 
401
{
 
402
        UT_SORT_FUNCTION_BODY(ut_ulint_sort, arr, aux_arr, low, high,
 
403
                              ut_ulint_cmp);
 
404
}
 
405
 
 
406
/*****************************************************************
 
407
Calculates fast the number rounded up to the nearest power of 2. */
 
408
 
 
409
ulint
 
410
ut_2_power_up(
 
411
/*==========*/
 
412
                        /* out: first power of 2 which is >= n */
 
413
        ulint   n)      /* in: number != 0 */
 
414
{
 
415
        ulint   res;
 
416
 
 
417
        res = 1;
 
418
 
 
419
        ut_ad(n > 0);
 
420
 
 
421
        while (res < n) {
 
422
                res = res * 2;
 
423
        }
 
424
 
 
425
        return(res);
 
426
}
 
427
 
 
428
/**************************************************************************
 
429
Outputs a NUL-terminated file name, quoted with apostrophes. */
 
430
 
 
431
void
 
432
ut_print_filename(
 
433
/*==============*/
 
434
        FILE*           f,      /* in: output stream */
 
435
        const char*     name)   /* in: name to print */
 
436
{
 
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);
 
448
                }
 
449
        }
 
450
done:
 
451
        putc('\'', f);
 
452
}
 
453
 
 
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. */
 
459
 
 
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 */
 
468
{
 
469
        ut_print_namel(f, trx, table_id, name, strlen(name));
 
470
}
 
471
 
 
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. */
 
477
 
 
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 */
 
487
{
 
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;
 
492
 
 
493
        bufend = innobase_convert_name(buf, sizeof buf,
 
494
                                       name, namelen,
 
495
                                       trx ? trx->mysql_thd : NULL,
 
496
                                       table_id);
 
497
 
 
498
        fwrite(buf, 1, bufend - buf, f);
 
499
}
 
500
 
 
501
/**************************************************************************
 
502
Catenate files. */
 
503
 
 
504
void
 
505
ut_copy_file(
 
506
/*=========*/
 
507
        FILE*   dest,   /* in: output file */
 
508
        FILE*   src)    /* in: input file to be appended to output */
 
509
{
 
510
        long    len = ftell(src);
 
511
        char    buf[4096];
 
512
 
 
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;
 
523
                }
 
524
        } while (len > 0);
 
525
}
 
526
 
 
527
/**************************************************************************
 
528
snprintf(). */
 
529
 
 
530
#ifdef __WIN__
 
531
#include <stdarg.h>
 
532
int
 
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 */
 
542
{
 
543
        int     res;
 
544
        va_list ap1;
 
545
        va_list ap2;
 
546
 
 
547
        va_start(ap1, fmt);
 
548
        va_start(ap2, fmt);
 
549
 
 
550
        res = _vscprintf(fmt, ap1);
 
551
        ut_a(res != -1);
 
552
 
 
553
        if (size > 0) {
 
554
                _vsnprintf(str, size, fmt, ap2);
 
555
 
 
556
                if ((size_t) res >= size) {
 
557
                        str[size - 1] = '\0';
 
558
                }
 
559
        }
 
560
 
 
561
        va_end(ap1);
 
562
        va_end(ap2);
 
563
 
 
564
        return(res);
 
565
}
 
566
#endif /* __WIN__ */