00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00033 #include "ut0ut.h"
00034
00035 #ifdef UNIV_NONINL
00036 #include "ut0ut.ic"
00037 #endif
00038
00039 #include <stdarg.h>
00040 #include <string.h>
00041 #include <ctype.h>
00042
00043 #ifndef UNIV_HOTBACKUP
00044 # include "trx0trx.h"
00045 # if defined(BUILD_DRIZZLE)
00046 # include "drizzled/common.h"
00047 # if TIME_WITH_SYS_TIME
00048 # include <sys/time.h>
00049 # include <time.h>
00050 # else
00051 # if HAVE_SYS_TIME_H
00052 # include <sys/time.h>
00053 # else
00054 # include <time.h>
00055 # endif
00056 # endif
00057 # else
00058 # include "ha_prototypes.h"
00059 # include "mysql_com.h"
00060 # endif
00061 #endif
00062 #include <errno.h>
00063 #include <assert.h>
00064
00066 UNIV_INTERN ibool ut_always_false = FALSE;
00067
00068 #ifdef __WIN__
00069
00073 #define WIN_TO_UNIX_DELTA_USEC ((ib_int64_t) 11644473600000000ULL)
00074
00075
00076
00079 static
00080 int
00081 ut_gettimeofday(
00082
00083 struct timeval* tv,
00084 void* tz)
00085 {
00086 FILETIME ft;
00087 ib_int64_t tm;
00088
00089 if (!tv) {
00090 errno = EINVAL;
00091 return(-1);
00092 }
00093
00094 GetSystemTimeAsFileTime(&ft);
00095
00096 tm = (ib_int64_t) ft.dwHighDateTime << 32;
00097 tm |= ft.dwLowDateTime;
00098
00099 ut_a(tm >= 0);
00100
00101
00102 tm /= 10;
00103
00104
00105
00106 tm -= WIN_TO_UNIX_DELTA_USEC;
00107
00108 tv->tv_sec = (long) (tm / 1000000L);
00109 tv->tv_usec = (long) (tm % 1000000L);
00110
00111 return(0);
00112 }
00113 #else
00114
00116 #define ut_gettimeofday gettimeofday
00117 #endif
00118
00119
00124 UNIV_INTERN
00125 ulint
00126 ut_get_high32(
00127
00128 ulint a)
00129 {
00130 ib_int64_t i;
00131
00132 i = (ib_int64_t)a;
00133
00134 i = i >> 32;
00135
00136 return((ulint)i);
00137 }
00138
00139
00143 UNIV_INTERN
00144 ib_time_t
00145 ut_time(void)
00146
00147 {
00148 return(time(NULL));
00149 }
00150
00151 #ifndef UNIV_HOTBACKUP
00152
00158 UNIV_INTERN
00159 int
00160 ut_usectime(
00161
00162 ulint* sec,
00163 ulint* ms)
00164 {
00165 struct timeval tv;
00166 int ret;
00167 int errno_gettimeofday;
00168 int i;
00169
00170 for (i = 0; i < 10; i++) {
00171
00172 ret = ut_gettimeofday(&tv, NULL);
00173
00174 if (ret == -1) {
00175 errno_gettimeofday = errno;
00176 ut_print_timestamp(stderr);
00177 fprintf(stderr, " InnoDB: gettimeofday(): %s\n",
00178 strerror(errno_gettimeofday));
00179 os_thread_sleep(100000);
00180 errno = errno_gettimeofday;
00181 } else {
00182 break;
00183 }
00184 }
00185
00186 if (ret != -1) {
00187 *sec = (ulint) tv.tv_sec;
00188 *ms = (ulint) tv.tv_usec;
00189 }
00190
00191 return(ret);
00192 }
00193
00194
00199 UNIV_INTERN
00200 ullint
00201 ut_time_us(
00202
00203 ullint* tloc)
00204 {
00205 struct timeval tv;
00206 ullint us;
00207
00208 ut_gettimeofday(&tv, NULL);
00209
00210 us = (ullint) tv.tv_sec * 1000000 + tv.tv_usec;
00211
00212 if (tloc != NULL) {
00213 *tloc = us;
00214 }
00215
00216 return(us);
00217 }
00218
00219
00224 UNIV_INTERN
00225 ulint
00226 ut_time_ms(void)
00227
00228 {
00229 struct timeval tv;
00230
00231 ut_gettimeofday(&tv, NULL);
00232
00233 return((ulint) tv.tv_sec * 1000 + tv.tv_usec / 1000);
00234 }
00235 #endif
00236
00237
00240 UNIV_INTERN
00241 double
00242 ut_difftime(
00243
00244 ib_time_t time2,
00245 ib_time_t time1)
00246 {
00247 return(difftime(time2, time1));
00248 }
00249
00250
00252 UNIV_INTERN
00253 void
00254 ut_print_timestamp(
00255
00256 FILE* file)
00257 {
00258 #ifdef __WIN__
00259 SYSTEMTIME cal_tm;
00260
00261 GetLocalTime(&cal_tm);
00262
00263 fprintf(file,"%02d%02d%02d %2d:%02d:%02d",
00264 (int)cal_tm.wYear % 100,
00265 (int)cal_tm.wMonth,
00266 (int)cal_tm.wDay,
00267 (int)cal_tm.wHour,
00268 (int)cal_tm.wMinute,
00269 (int)cal_tm.wSecond);
00270 #else
00271 struct tm cal_tm;
00272 struct tm* cal_tm_ptr;
00273 time_t tm;
00274
00275 time(&tm);
00276
00277 #ifdef HAVE_LOCALTIME_R
00278 localtime_r(&tm, &cal_tm);
00279 cal_tm_ptr = &cal_tm;
00280 #else
00281 cal_tm_ptr = localtime(&tm);
00282 #endif
00283 fprintf(file,"%02d%02d%02d %2d:%02d:%02d",
00284 cal_tm_ptr->tm_year % 100,
00285 cal_tm_ptr->tm_mon + 1,
00286 cal_tm_ptr->tm_mday,
00287 cal_tm_ptr->tm_hour,
00288 cal_tm_ptr->tm_min,
00289 cal_tm_ptr->tm_sec);
00290 #endif
00291 }
00292
00293
00295 UNIV_INTERN
00296 void
00297 ut_sprintf_timestamp(
00298
00299 char* buf)
00300 {
00301 #ifdef __WIN__
00302 SYSTEMTIME cal_tm;
00303
00304 GetLocalTime(&cal_tm);
00305
00306 sprintf(buf, "%02d%02d%02d %2d:%02d:%02d",
00307 (int)cal_tm.wYear % 100,
00308 (int)cal_tm.wMonth,
00309 (int)cal_tm.wDay,
00310 (int)cal_tm.wHour,
00311 (int)cal_tm.wMinute,
00312 (int)cal_tm.wSecond);
00313 #else
00314 struct tm cal_tm;
00315 struct tm* cal_tm_ptr;
00316 time_t tm;
00317
00318 time(&tm);
00319
00320 #ifdef HAVE_LOCALTIME_R
00321 localtime_r(&tm, &cal_tm);
00322 cal_tm_ptr = &cal_tm;
00323 #else
00324 cal_tm_ptr = localtime(&tm);
00325 #endif
00326 sprintf(buf, "%02d%02d%02d %2d:%02d:%02d",
00327 cal_tm_ptr->tm_year % 100,
00328 cal_tm_ptr->tm_mon + 1,
00329 cal_tm_ptr->tm_mday,
00330 cal_tm_ptr->tm_hour,
00331 cal_tm_ptr->tm_min,
00332 cal_tm_ptr->tm_sec);
00333 #endif
00334 }
00335
00336 #ifdef UNIV_HOTBACKUP
00337
00340 UNIV_INTERN
00341 void
00342 ut_sprintf_timestamp_without_extra_chars(
00343
00344 char* buf)
00345 {
00346 #ifdef __WIN__
00347 SYSTEMTIME cal_tm;
00348
00349 GetLocalTime(&cal_tm);
00350
00351 sprintf(buf, "%02d%02d%02d_%2d_%02d_%02d",
00352 (int)cal_tm.wYear % 100,
00353 (int)cal_tm.wMonth,
00354 (int)cal_tm.wDay,
00355 (int)cal_tm.wHour,
00356 (int)cal_tm.wMinute,
00357 (int)cal_tm.wSecond);
00358 #else
00359 struct tm cal_tm;
00360 struct tm* cal_tm_ptr;
00361 time_t tm;
00362
00363 time(&tm);
00364
00365 #ifdef HAVE_LOCALTIME_R
00366 localtime_r(&tm, &cal_tm);
00367 cal_tm_ptr = &cal_tm;
00368 #else
00369 cal_tm_ptr = localtime(&tm);
00370 #endif
00371 sprintf(buf, "%02d%02d%02d_%2d_%02d_%02d",
00372 cal_tm_ptr->tm_year % 100,
00373 cal_tm_ptr->tm_mon + 1,
00374 cal_tm_ptr->tm_mday,
00375 cal_tm_ptr->tm_hour,
00376 cal_tm_ptr->tm_min,
00377 cal_tm_ptr->tm_sec);
00378 #endif
00379 }
00380
00381
00383 UNIV_INTERN
00384 void
00385 ut_get_year_month_day(
00386
00387 ulint* year,
00388 ulint* month,
00389 ulint* day)
00390 {
00391 #ifdef __WIN__
00392 SYSTEMTIME cal_tm;
00393
00394 GetLocalTime(&cal_tm);
00395
00396 *year = (ulint)cal_tm.wYear;
00397 *month = (ulint)cal_tm.wMonth;
00398 *day = (ulint)cal_tm.wDay;
00399 #else
00400 struct tm cal_tm;
00401 struct tm* cal_tm_ptr;
00402 time_t tm;
00403
00404 time(&tm);
00405
00406 #ifdef HAVE_LOCALTIME_R
00407 localtime_r(&tm, &cal_tm);
00408 cal_tm_ptr = &cal_tm;
00409 #else
00410 cal_tm_ptr = localtime(&tm);
00411 #endif
00412 *year = (ulint)cal_tm_ptr->tm_year + 1900;
00413 *month = (ulint)cal_tm_ptr->tm_mon + 1;
00414 *day = (ulint)cal_tm_ptr->tm_mday;
00415 #endif
00416 }
00417 #endif
00418
00419 #ifndef UNIV_HOTBACKUP
00420
00424 UNIV_INTERN
00425 ulint
00426 ut_delay(
00427
00428 ulint delay)
00429 {
00430 ulint i, j;
00431
00432 j = 0;
00433
00434 for (i = 0; i < delay * 50; i++) {
00435 j += i;
00436 UT_RELAX_CPU();
00437 }
00438
00439 if (ut_always_false) {
00440 ut_always_false = (ibool) j;
00441 }
00442
00443 return(j);
00444 }
00445 #endif
00446
00447
00449 UNIV_INTERN
00450 void
00451 ut_print_buf(
00452
00453 FILE* file,
00454 const void* buf,
00455 ulint len)
00456 {
00457 const byte* data;
00458 ulint i;
00459
00460 UNIV_MEM_ASSERT_RW(buf, len);
00461
00462 fprintf(file, " len %lu; hex ", len);
00463
00464 for (data = (const byte*)buf, i = 0; i < len; i++) {
00465 fprintf(file, "%02lx", (ulong)*data++);
00466 }
00467
00468 fputs("; asc ", file);
00469
00470 data = (const byte*)buf;
00471
00472 for (i = 0; i < len; i++) {
00473 int c = (int) *data++;
00474 putc(isprint(c) ? c : ' ', file);
00475 }
00476
00477 putc(';', file);
00478 }
00479
00480
00483 UNIV_INTERN
00484 ulint
00485 ut_2_power_up(
00486
00487 ulint n)
00488 {
00489 ulint res;
00490
00491 res = 1;
00492
00493 ut_ad(n > 0);
00494
00495 while (res < n) {
00496 res = res * 2;
00497 }
00498
00499 return(res);
00500 }
00501
00502
00504 UNIV_INTERN
00505 void
00506 ut_print_filename(
00507
00508 FILE* f,
00509 const char* name)
00510 {
00511 putc('\'', f);
00512 for (;;) {
00513 int c = *name++;
00514 switch (c) {
00515 case 0:
00516 goto done;
00517 case '\'':
00518 putc(c, f);
00519
00520 default:
00521 putc(c, f);
00522 }
00523 }
00524 done:
00525 putc('\'', f);
00526 }
00527 #ifndef UNIV_HOTBACKUP
00528
00533 UNIV_INTERN
00534 void
00535 ut_print_name(
00536
00537 FILE* f,
00538 trx_t* trx,
00539 ibool table_id,
00541 const char* name)
00542 {
00543 ut_print_namel(f, trx, table_id, name, strlen(name));
00544 }
00545
00546
00551 UNIV_INTERN
00552 void
00553 ut_print_namel(
00554
00555 FILE* f,
00556 trx_t* trx,
00557 ibool table_id,
00559 const char* name,
00560 ulint namelen)
00561 {
00562
00563
00564 char buf[3 * NAME_LEN];
00565 const char* bufend;
00566
00567 bufend = innobase_convert_name(buf, sizeof buf,
00568 name, namelen,
00569 trx ? trx->mysql_thd : NULL,
00570 table_id);
00571
00572 ssize_t ret= fwrite(buf, 1, bufend - buf, f);
00573 assert(ret==bufend-buf);
00574 }
00575
00576
00578 UNIV_INTERN
00579 void
00580 ut_copy_file(
00581
00582 FILE* dest,
00583 FILE* src)
00584 {
00585 long len = ftell(src);
00586 char buf[4096];
00587
00588 rewind(src);
00589 do {
00590 size_t maxs = len < (long) sizeof buf
00591 ? (size_t) len
00592 : sizeof buf;
00593 size_t size = fread(buf, 1, maxs, src);
00594 size_t ret= fwrite(buf, 1, size, dest);
00595 assert(ret==size);
00596 len -= (long) size;
00597 if (size < maxs) {
00598 break;
00599 }
00600 } while (len > 0);
00601 }
00602 #endif
00603
00604 #ifdef __WIN__
00605 # include <stdarg.h>
00606
00611 UNIV_INTERN
00612 int
00613 ut_snprintf(
00614
00615 char* str,
00616 size_t size,
00617 const char* fmt,
00618 ...)
00619 {
00620 int res;
00621 va_list ap1;
00622 va_list ap2;
00623
00624 va_start(ap1, fmt);
00625 va_start(ap2, fmt);
00626
00627 res = _vscprintf(fmt, ap1);
00628 ut_a(res != -1);
00629
00630 if (size > 0) {
00631 _vsnprintf(str, size, fmt, ap2);
00632
00633 if ((size_t) res >= size) {
00634 str[size - 1] = '\0';
00635 }
00636 }
00637
00638 va_end(ap1);
00639 va_end(ap2);
00640
00641 return(res);
00642 }
00643 #endif
00644
00645
00649 UNIV_INTERN
00650 const char*
00651 ut_strerr(
00652
00653 enum db_err num)
00654 {
00655 switch (num) {
00656 case DB_SUCCESS:
00657 return("Success");
00658 case DB_SUCCESS_LOCKED_REC:
00659 return("Success, record lock created");
00660 case DB_ERROR:
00661 return("Generic error");
00662 case DB_INTERRUPTED:
00663 return("Operation interrupted");
00664 case DB_OUT_OF_MEMORY:
00665 return("Cannot allocate memory");
00666 case DB_OUT_OF_FILE_SPACE:
00667 return("Out of disk space");
00668 case DB_LOCK_WAIT:
00669 return("Lock wait");
00670 case DB_DEADLOCK:
00671 return("Deadlock");
00672 case DB_ROLLBACK:
00673 return("Rollback");
00674 case DB_DUPLICATE_KEY:
00675 return("Duplicate key");
00676 case DB_QUE_THR_SUSPENDED:
00677 return("The queue thread has been suspended");
00678 case DB_MISSING_HISTORY:
00679 return("Required history data has been deleted");
00680 case DB_CLUSTER_NOT_FOUND:
00681 return("Cluster not found");
00682 case DB_TABLE_NOT_FOUND:
00683 return("Table not found");
00684 case DB_MUST_GET_MORE_FILE_SPACE:
00685 return("More file space needed");
00686 case DB_TABLE_IS_BEING_USED:
00687 return("Table is being used");
00688 case DB_TOO_BIG_RECORD:
00689 return("Record too big");
00690 case DB_LOCK_WAIT_TIMEOUT:
00691 return("Lock wait timeout");
00692 case DB_NO_REFERENCED_ROW:
00693 return("Referenced key value not found");
00694 case DB_ROW_IS_REFERENCED:
00695 return("Row is referenced");
00696 case DB_CANNOT_ADD_CONSTRAINT:
00697 return("Cannot add constraint");
00698 case DB_CORRUPTION:
00699 return("Data structure corruption");
00700 case DB_COL_APPEARS_TWICE_IN_INDEX:
00701 return("Column appears twice in index");
00702 case DB_CANNOT_DROP_CONSTRAINT:
00703 return("Cannot drop constraint");
00704 case DB_NO_SAVEPOINT:
00705 return("No such savepoint");
00706 case DB_TABLESPACE_ALREADY_EXISTS:
00707 return("Tablespace already exists");
00708 case DB_TABLESPACE_DELETED:
00709 return("No such tablespace");
00710 case DB_LOCK_TABLE_FULL:
00711 return("Lock structs have exhausted the buffer pool");
00712 case DB_FOREIGN_DUPLICATE_KEY:
00713 return("Foreign key activated with duplicate keys");
00714 case DB_FOREIGN_EXCEED_MAX_CASCADE:
00715 return("Foreign key cascade delete/update exceeds max depth");
00716 case DB_TOO_MANY_CONCURRENT_TRXS:
00717 return("Too many concurrent transactions");
00718 case DB_UNSUPPORTED:
00719 return("Unsupported");
00720 case DB_PRIMARY_KEY_IS_NULL:
00721 return("Primary key is NULL");
00722 case DB_STATS_DO_NOT_EXIST:
00723 return("Persistent statistics do not exist");
00724 case DB_FAIL:
00725 return("Failed, retry may succeed");
00726 case DB_OVERFLOW:
00727 return("Overflow");
00728 case DB_UNDERFLOW:
00729 return("Underflow");
00730 case DB_STRONG_FAIL:
00731 return("Failed, retry will not succeed");
00732 case DB_ZIP_OVERFLOW:
00733 return("Zip overflow");
00734 case DB_RECORD_NOT_FOUND:
00735 return("Record not found");
00736 case DB_CHILD_NO_INDEX:
00737 return("No index on referencing keys in referencing table");
00738 case DB_PARENT_NO_INDEX:
00739 return("No index on referenced keys in referenced table");
00740 case DB_END_OF_INDEX:
00741 return("End of index");
00742
00743
00744 }
00745
00746
00747
00748
00749 ut_error;
00750
00751
00752 return("Unknown error");
00753 }