diff options
Diffstat (limited to 'storage/innobase/include/ut0dbg.h')
-rw-r--r-- | storage/innobase/include/ut0dbg.h | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/storage/innobase/include/ut0dbg.h b/storage/innobase/include/ut0dbg.h new file mode 100644 index 00000000..85856660 --- /dev/null +++ b/storage/innobase/include/ut0dbg.h @@ -0,0 +1,179 @@ +/***************************************************************************** + +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, 2019, MariaDB Corporation. + +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, Fifth Floor, 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. */ + +/*************************************************************//** +Report a failed assertion. */ +ATTRIBUTE_NORETURN ATTRIBUTE_COLD __attribute__((nonnull(2))) +void +ut_dbg_assertion_failed( +/*====================*/ + const char* expr, /*!< in: the failed assertion */ + const char* file, /*!< in: source file containing the assertion */ + unsigned line); /*!< in: line number of the assertion */ + +/** 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__, __LINE__); \ + } \ +} while (0) + +/** Abort execution. */ +#define ut_error \ + ut_dbg_assertion_failed(0, __FILE__, __LINE__) + +/** Debug assertion */ +#define ut_ad DBUG_SLOW_ASSERT +#if defined(UNIV_DEBUG) || !defined(DBUG_OFF) +/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */ +#define ut_d(EXPR) EXPR +#else +/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */ +#define ut_d(EXPR) +#endif + +#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 |