mariadb/storage/innobase/include/ut0dbg.h
Jan Lindström fec844aca8 Merge InnoDB 5.7 from mysql-5.7.14.
Contains also:
       MDEV-10549 mysqld: sql/handler.cc:2692: int handler::ha_index_first(uchar*): Assertion `table_share->tmp_table != NO_TMP_TABLE || m_lock_type != 2' failed. (branch bb-10.2-jan)
       Unlike MySQL, InnoDB still uses THR_LOCK in MariaDB

       MDEV-10548 Some of the debug sync waits do not work with InnoDB 5.7 (branch bb-10.2-jan)
       enable tests that were fixed in MDEV-10549

       MDEV-10548 Some of the debug sync waits do not work with InnoDB 5.7 (branch bb-10.2-jan)
       fix main.innodb_mysql_sync - re-enable online alter for partitioned innodb tables
2016-09-08 15:49:03 +03:00

186 lines
4.8 KiB
C++

/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
/*****************************************************************//**
@file include/ut0dbg.h
Debug utilities for Innobase
Created 1/30/1994 Heikki Tuuri
**********************************************************************/
#ifndef ut0dbg_h
#define ut0dbg_h
#ifdef UNIV_INNOCHECKSUM
#define ut_a assert
#define ut_ad assert
#define ut_error assert(0)
#else /* !UNIV_INNOCHECKSUM */
/* Do not include univ.i because univ.i includes this. */
#include "os0thread.h"
/*************************************************************//**
Report a failed assertion. */
void
ut_dbg_assertion_failed(
/*====================*/
const char* expr, /*!< in: the failed assertion */
const char* file, /*!< in: source file containing the assertion */
ulint line) /*!< in: line number of the assertion */
UNIV_COLD MY_ATTRIBUTE((nonnull(2), noreturn));
/** Abort execution if EXPR does not evaluate to nonzero.
@param EXPR assertion expression that should hold */
#define ut_a(EXPR) do { \
if (UNIV_UNLIKELY(!(ulint) (EXPR))) { \
ut_dbg_assertion_failed(#EXPR, \
__FILE__, (ulint) __LINE__); \
} \
} while (0)
/** Abort execution. */
#define ut_error \
ut_dbg_assertion_failed(0, __FILE__, (ulint) __LINE__)
#ifdef UNIV_DEBUG
/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
#define ut_ad(EXPR) ut_a(EXPR)
/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
#define ut_d(EXPR) EXPR
#else
/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
#define ut_ad(EXPR)
/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
#define ut_d(EXPR)
#endif
/** Silence warnings about an unused variable by doing a null assignment.
@param A the unused variable */
#define UT_NOT_USED(A) A = A
#if defined(HAVE_SYS_TIME_H) && defined(HAVE_SYS_RESOURCE_H)
#define HAVE_UT_CHRONO_T
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
/** A "chronometer" used to clock snippets of code.
Example usage:
ut_chrono_t ch("this loop");
for (;;) { ... }
ch.show();
would print the timings of the for() loop, prefixed with "this loop:" */
class ut_chrono_t {
public:
/** Constructor.
@param[in] name chrono's name, used when showing the values */
ut_chrono_t(
const char* name)
:
m_name(name),
m_show_from_destructor(true)
{
reset();
}
/** Resets the chrono (records the current time in it). */
void
reset()
{
gettimeofday(&m_tv, NULL);
getrusage(RUSAGE_SELF, &m_ru);
}
/** Shows the time elapsed and usage statistics since the last reset. */
void
show()
{
struct rusage ru_now;
struct timeval tv_now;
struct timeval tv_diff;
getrusage(RUSAGE_SELF, &ru_now);
gettimeofday(&tv_now, NULL);
#ifndef timersub
#define timersub(a, b, r) \
do { \
(r)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
(r)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
if ((r)->tv_usec < 0) { \
(r)->tv_sec--; \
(r)->tv_usec += 1000000; \
} \
} while (0)
#endif /* timersub */
#define CHRONO_PRINT(type, tvp) \
fprintf(stderr, "%s: %s% 5ld.%06ld sec\n", \
m_name, type, \
static_cast<long>((tvp)->tv_sec), \
static_cast<long>((tvp)->tv_usec))
timersub(&tv_now, &m_tv, &tv_diff);
CHRONO_PRINT("real", &tv_diff);
timersub(&ru_now.ru_utime, &m_ru.ru_utime, &tv_diff);
CHRONO_PRINT("user", &tv_diff);
timersub(&ru_now.ru_stime, &m_ru.ru_stime, &tv_diff);
CHRONO_PRINT("sys ", &tv_diff);
}
/** Cause the timings not to be printed from the destructor. */
void end()
{
m_show_from_destructor = false;
}
/** Destructor. */
~ut_chrono_t()
{
if (m_show_from_destructor) {
show();
}
}
private:
/** Name of this chronometer. */
const char* m_name;
/** True if the current timings should be printed by the destructor. */
bool m_show_from_destructor;
/** getrusage() result as of the last reset(). */
struct rusage m_ru;
/** gettimeofday() result as of the last reset(). */
struct timeval m_tv;
};
#endif /* HAVE_SYS_TIME_H && HAVE_SYS_RESOURCE_H */
#endif /* !UNIV_INNOCHECKSUM */
#endif