mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-04 04:46:15 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			179 lines
		
	
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			179 lines
		
	
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*****************************************************************************
 | 
						|
 | 
						|
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
 |