Replace ut_timer() with my_interval_timer()

The function pointer ut_timer() was only used by the
InnoDB defragmenting thread. Let InnoDB use a single monotonic
high-precision timer, my_interval_timer() [in nanoseconds],
occasionally wrapped by microsecond_interval_timer().

srv_defragment_interval: Change from "timer" units to nanoseconds.

This concludes the InnoDB time function cleanup that was
motivated by MDEV-14154. Only ut_time_ms() will remain for now,
wrapping my_interval_timer().
This commit is contained in:
Marko Mäkelä 2019-07-25 10:30:28 +03:00
parent e32f29b7f3
commit f6ea0389a4
14 changed files with 19 additions and 467 deletions

View File

@ -497,8 +497,7 @@ SET(INNOBASE_SOURCES
ut/ut0rnd.cc
ut/ut0ut.cc
ut/ut0vec.cc
ut/ut0wqueue.cc
ut/ut0timer.cc)
ut/ut0wqueue.cc)
IF(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64le")
enable_language(ASM)

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (C) 2013, 2014 Facebook, Inc. All Rights Reserved.
Copyright (C) 2014, 2015, MariaDB Corporation. All Rights Reserved.
Copyright (C) 2012, 2014 Facebook, Inc. All Rights Reserved.
Copyright (C) 2014, 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
@ -35,7 +35,6 @@ Modified 30/07/2014 Jan Lindström jan.lindstrom@mariadb.com
#include "ibuf0ibuf.h"
#include "lock0lock.h"
#include "srv0start.h"
#include "ut0timer.h"
#include <list>
@ -99,8 +98,7 @@ Initialize defragmentation. */
void
btr_defragment_init()
{
srv_defragment_interval = ut_microseconds_to_timer(
1000000.0 / srv_defragment_frequency);
srv_defragment_interval = 1000000000ULL / srv_defragment_frequency;
mutex_create(btr_defragment_mutex_key, &btr_defragment_mutex,
SYNC_ANY_LATCH);
}
@ -728,7 +726,7 @@ DECLARE_THREAD(btr_defragment_thread)(void*)
}
pcur = item->pcur;
ulonglong now = ut_timer_now();
ulonglong now = my_interval_timer();
ulonglong elapsed = now - item->last_processed;
if (elapsed < srv_defragment_interval) {
@ -738,11 +736,12 @@ DECLARE_THREAD(btr_defragment_thread)(void*)
defragmentation of all indices queue up on a single
thread, it's likely other indices that follow this one
don't need to sleep again. */
os_thread_sleep(((ulint)ut_timer_to_microseconds(
srv_defragment_interval - elapsed)));
os_thread_sleep(static_cast<ulint>
((srv_defragment_interval - elapsed)
/ 1000));
}
now = ut_timer_now();
now = my_interval_timer();
mtr_start(&mtr);
btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, &mtr);
cursor = btr_pcur_get_btr_cur(pcur);

View File

@ -95,7 +95,6 @@ MYSQL_PLUGIN_IMPORT extern char mysql_unpacked_real_data_home[];
#include "dict0stats_bg.h"
#include "ha_prototypes.h"
#include "ut0mem.h"
#include "ut0timer.h"
#include "ibuf0ibuf.h"
#include "dict0dict.h"
#include "srv0mon.h"
@ -18052,8 +18051,7 @@ innodb_defragment_frequency_update(
from check function */
{
srv_defragment_frequency = (*static_cast<const uint*>(save));
srv_defragment_interval = ut_microseconds_to_timer(
1000000.0 / srv_defragment_frequency);
srv_defragment_interval = 1000000000ULL / srv_defragment_frequency;
}
/****************************************************************//**

View File

@ -1,69 +0,0 @@
/*****************************************************************************
Copyright (c) 2013, 2014, Facebook, Inc. All Rights Reserved.
Copyright (c) 2014, 2018, 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/ut0timer.h
Timer routines
Created 30/07/2014 Jan Lindström jan.lindstrom@skysql.com
modified from https://github.com/facebook/mysql-5.6/commit/c75a413edeb96eb99bf11d7269bdfea06f96d6b6
*************************************************************************/
#ifndef ut0timer_h
#define ut0timer_h
#include "univ.i"
/* Current timer stats */
extern struct my_timer_unit_info ut_timer;
/**************************************************************//**
Function pointer to point selected timer function.
@return timer current value */
extern ulonglong (*ut_timer_now)(void);
/**************************************************************//**
Sets up the data required for use of my_timer_* functions.
Selects the best timer by high frequency, and tight resolution.
Points my_timer_now() to the selected timer function.
Initializes my_timer struct to contain the info for selected timer.*/
UNIV_INTERN
void ut_init_timer(void);
/**************************************************************//**
Convert native timer units in a ulonglong into microseconds in a double
@return time in microseconds */
UNIV_INLINE
double
ut_timer_to_microseconds(
/*=====================*/
ulonglong when); /*!< in: time where to calculate */
/**************************************************************//**
Convert microseconds in a double to native timer units in a ulonglong
@return time in microseconds */
UNIV_INLINE
ulonglong
ut_microseconds_to_timer(
/*=====================*/
ulonglong when); /*!< in: time where to calculate */
#ifndef UNIV_NONINL
#include "ut0timer.ic"
#endif
#endif

View File

@ -1,56 +0,0 @@
/*****************************************************************************
Copyright (c) 2013, 2014, Facebook, Inc. All Rights Reserved.
Copyright (c) 2014, 2018, 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/ut0timer.ic
Timer routines
Created 30/07/2014 Jan Lindström jan.lindstrom@skysql.com
modified from https://github.com/facebook/mysql-5.6/commit/c75a413edeb96eb99bf11d7269bdfea06f96d6b6
*************************************************************************/
/**************************************************************//**
Convert native timer units in a ulonglong into microseconds in a double
@return time in microseconds */
UNIV_INLINE
double
ut_timer_to_microseconds(
/*=====================*/
ulonglong when) /*!< in: time where to calculate */
{
double ret = (double)(when);
ret *= 1000000.0;
ret /= (double)(ut_timer.frequency);
return ret;
}
/**************************************************************//**
Convert microseconds in a double to native timer units in a ulonglong
@return time in microseconds */
UNIV_INLINE
ulonglong
ut_microseconds_to_timer(
/*=====================*/
ulonglong when) /*!< in: time where to calculate */
{
double ret = (double)when;
ret *= (double)(ut_timer.frequency);
ret /= 1000000.0;
return (ulonglong)ret;
}

View File

@ -43,7 +43,6 @@ Created 2/16/1996 Heikki Tuuri
#include "pars0pars.h"
#include "row0ftsort.h"
#include "ut0mem.h"
#include "ut0timer.h"
#include "mem0mem.h"
#include "data0data.h"
#include "data0type.h"
@ -1669,9 +1668,6 @@ innobase_start_or_create_for_mysql()
os_fast_mutex_free(&srv_os_test_mutex);
/* This should be initialized early */
ut_init_timer();
if (srv_force_recovery == SRV_FORCE_NO_LOG_REDO) {
srv_read_only_mode = 1;
}

View File

@ -1,90 +0,0 @@
/*****************************************************************************
Copyright (c) 2013, 2014, Facebook, Inc. All Rights Reserved.
Copyright (c) 2014, SkySQL Ab. 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, Fifth Floor, Boston, MA 02110-1335 USA
*****************************************************************************/
/********************************************************************//**
@file ut/ut0timer.cc
Timer rountines
Created 30/07/2014 Jan Lindström jan.lindstrom@skysql.com
modified from https://github.com/facebook/mysql-5.6/commit/c75a413edeb96eb99bf11d7269bdfea06f96d6b6
*************************************************************************/
#include "data0type.h"
#include <my_rdtsc.h>
#include <ut0timer.h>
/**************************************************************//**
Initial timer definition
@return 0 */
static
ulonglong
ut_timer_none(void)
/*===============*/
{
return 0;
}
/**************************************************************//**
Function pointer to point selected timer function.
@return timer current value */
ulonglong (*ut_timer_now)(void) = &ut_timer_none;
struct my_timer_unit_info ut_timer;
extern MYSQL_PLUGIN_IMPORT MY_TIMER_INFO sys_timer_info;
/**************************************************************//**
Sets up the data required for use of my_timer_* functions.
Selects the best timer by high frequency, and tight resolution.
Points my_timer_now() to the selected timer function.
Initializes my_timer struct to contain the info for selected timer.*/
UNIV_INTERN
void
ut_init_timer(void)
/*===============*/
{
if (sys_timer_info.cycles.frequency > 1000000 &&
sys_timer_info.cycles.resolution == 1) {
ut_timer = sys_timer_info.cycles;
ut_timer_now = &my_timer_cycles;
} else if (sys_timer_info.nanoseconds.frequency > 1000000 &&
sys_timer_info.nanoseconds.resolution == 1) {
ut_timer = sys_timer_info.nanoseconds;
ut_timer_now = &my_timer_nanoseconds;
} else if (sys_timer_info.microseconds.frequency >= 1000000 &&
sys_timer_info.microseconds.resolution == 1) {
ut_timer = sys_timer_info.microseconds;
ut_timer_now = &my_timer_microseconds;
} else if (sys_timer_info.milliseconds.frequency >= 1000 &&
sys_timer_info.milliseconds.resolution == 1) {
ut_timer = sys_timer_info.milliseconds;
ut_timer_now = &my_timer_milliseconds;
} else if (sys_timer_info.ticks.frequency >= 1000 &&
/* Will probably be false */
sys_timer_info.ticks.resolution == 1) {
ut_timer = sys_timer_info.ticks;
ut_timer_now = &my_timer_ticks;
} else {
/* None are acceptable, so leave it as "None", and fill in struct */
ut_timer.frequency = 1; /* Avoid div-by-zero */
ut_timer.overhead = 0; /* Since it doesn't do anything */
ut_timer.resolution = 10; /* Another sign it's bad */
ut_timer.routine = 0; /* None */
}
}

View File

@ -493,8 +493,7 @@ SET(INNOBASE_SOURCES
ut/ut0rnd.cc
ut/ut0ut.cc
ut/ut0vec.cc
ut/ut0wqueue.cc
ut/ut0timer.cc)
ut/ut0wqueue.cc)
IF(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64le")
enable_language(ASM)

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (C) 2012, 2014 Facebook, Inc. All Rights Reserved.
Copyright (C) 2014, 2015, MariaDB Corporation. All Rights Reserved.
Copyright (C) 2014, 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
@ -35,8 +35,6 @@ Modified 30/07/2014 Jan Lindström jan.lindstrom@mariadb.com
#include "ibuf0ibuf.h"
#include "lock0lock.h"
#include "srv0start.h"
#include "srv0srv.h"
#include "ut0timer.h"
#include <list>
@ -100,8 +98,7 @@ Initialize defragmentation. */
void
btr_defragment_init()
{
srv_defragment_interval = ut_microseconds_to_timer(
1000000.0 / srv_defragment_frequency);
srv_defragment_interval = 1000000000ULL / srv_defragment_frequency;
mutex_create(btr_defragment_mutex_key, &btr_defragment_mutex,
SYNC_ANY_LATCH);
}
@ -729,7 +726,7 @@ DECLARE_THREAD(btr_defragment_thread)(void*)
}
pcur = item->pcur;
ulonglong now = ut_timer_now();
ulonglong now = my_interval_timer();
ulonglong elapsed = now - item->last_processed;
if (elapsed < srv_defragment_interval) {
@ -739,11 +736,12 @@ DECLARE_THREAD(btr_defragment_thread)(void*)
defragmentation of all indices queue up on a single
thread, it's likely other indices that follow this one
don't need to sleep again. */
os_thread_sleep(((ulint)ut_timer_to_microseconds(
srv_defragment_interval - elapsed)));
os_thread_sleep(static_cast<ulint>
((srv_defragment_interval - elapsed)
/ 1000));
}
now = ut_timer_now();
now = my_interval_timer();
mtr_start(&mtr);
btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, &mtr);
cursor = btr_pcur_get_btr_cur(pcur);

View File

@ -92,7 +92,6 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include "dict0stats_bg.h"
#include "ha_prototypes.h"
#include "ut0mem.h"
#include "ut0timer.h"
#include "ibuf0ibuf.h"
#include "dict0dict.h"
#include "srv0mon.h"
@ -18772,8 +18771,7 @@ innodb_defragment_frequency_update(
from check function */
{
srv_defragment_frequency = (*static_cast<const uint*>(save));
srv_defragment_interval = ut_microseconds_to_timer(
1000000.0 / srv_defragment_frequency);
srv_defragment_interval = 1000000000ULL / srv_defragment_frequency;
}
/****************************************************************//**

View File

@ -1,69 +0,0 @@
/*****************************************************************************
Copyright (c) 2013, 2014, Facebook, Inc. All Rights Reserved.
Copyright (c) 2014, 2018, 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/ut0timer.h
Timer routines
Created 30/07/2014 Jan Lindström jan.lindstrom@skysql.com
modified from https://github.com/facebook/mysql-5.6/commit/c75a413edeb96eb99bf11d7269bdfea06f96d6b6
*************************************************************************/
#ifndef ut0timer_h
#define ut0timer_h
#include "univ.i"
/* Current timer stats */
extern struct my_timer_unit_info ut_timer;
/**************************************************************//**
Function pointer to point selected timer function.
@return timer current value */
extern ulonglong (*ut_timer_now)(void);
/**************************************************************//**
Sets up the data required for use of my_timer_* functions.
Selects the best timer by high frequency, and tight resolution.
Points my_timer_now() to the selected timer function.
Initializes my_timer struct to contain the info for selected timer.*/
UNIV_INTERN
void ut_init_timer(void);
/**************************************************************//**
Convert native timer units in a ulonglong into microseconds in a double
@return time in microseconds */
UNIV_INLINE
double
ut_timer_to_microseconds(
/*=====================*/
ulonglong when); /*!< in: time where to calculate */
/**************************************************************//**
Convert microseconds in a double to native timer units in a ulonglong
@return time in microseconds */
UNIV_INLINE
ulonglong
ut_microseconds_to_timer(
/*=====================*/
ulonglong when); /*!< in: time where to calculate */
#ifndef UNIV_NONINL
#include "ut0timer.ic"
#endif
#endif

View File

@ -1,56 +0,0 @@
/*****************************************************************************
Copyright (c) 2013, 2014, Facebook, Inc. All Rights Reserved.
Copyright (c) 2014, 2018, 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/ut0timer.ic
Timer routines
Created 30/07/2014 Jan Lindström jan.lindstrom@skysql.com
modified from https://github.com/facebook/mysql-5.6/commit/c75a413edeb96eb99bf11d7269bdfea06f96d6b6
*************************************************************************/
/**************************************************************//**
Convert native timer units in a ulonglong into microseconds in a double
@return time in microseconds */
UNIV_INLINE
double
ut_timer_to_microseconds(
/*=====================*/
ulonglong when) /*!< in: time where to calculate */
{
double ret = (double)(when);
ret *= 1000000.0;
ret /= (double)(ut_timer.frequency);
return ret;
}
/**************************************************************//**
Convert microseconds in a double to native timer units in a ulonglong
@return time in microseconds */
UNIV_INLINE
ulonglong
ut_microseconds_to_timer(
/*=====================*/
ulonglong when) /*!< in: time where to calculate */
{
double ret = (double)when;
ret *= (double)(ut_timer.frequency);
ret /= 1000000.0;
return (ulonglong)ret;
}

View File

@ -71,7 +71,6 @@ Created 2/16/1996 Heikki Tuuri
#include "srv0srv.h"
#include "buf0flu.h"
#include "btr0defragment.h"
#include "ut0timer.h"
#include "btr0scrub.h"
#include "mysql/service_wsrep.h" /* wsrep_recovery */
@ -1743,9 +1742,6 @@ innobase_start_or_create_for_mysql()
os_fast_mutex_free(&srv_os_test_mutex);
/* This should be initialized early */
ut_init_timer();
if (srv_force_recovery == SRV_FORCE_NO_LOG_REDO) {
srv_read_only_mode = 1;
}

View File

@ -1,91 +0,0 @@
/*****************************************************************************
Copyright (c) 2013, 2014, Facebook, Inc. All Rights Reserved.
Copyright (c) 2014, SkySQL Ab. 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, Fifth Floor, Boston, MA 02110-1335 USA
*****************************************************************************/
/********************************************************************//**
@file ut/ut0timer.cc
Timer rountines
Created 30/07/2014 Jan Lindström jan.lindstrom@skysql.com
modified from https://github.com/facebook/mysql-5.6/commit/c75a413edeb96eb99bf11d7269bdfea06f96d6b6
*************************************************************************/
#include "data0type.h"
#include <my_rdtsc.h>
#include <ut0timer.h>
/**************************************************************//**
Initial timer definition
@return 0 */
static
ulonglong
ut_timer_none(void)
/*===============*/
{
return 0;
}
/**************************************************************//**
Function pointer to point selected timer function.
@return timer current value */
ulonglong (*ut_timer_now)(void) = &ut_timer_none;
struct my_timer_unit_info ut_timer;
extern MYSQL_PLUGIN_IMPORT MY_TIMER_INFO sys_timer_info;
/**************************************************************//**
Sets up the data required for use of my_timer_* functions.
Selects the best timer by high frequency, and tight resolution.
Points my_timer_now() to the selected timer function.
Initializes my_timer struct to contain the info for selected timer.*/
UNIV_INTERN
void
ut_init_timer(void)
/*===============*/
{
if (sys_timer_info.cycles.frequency > 1000000 &&
sys_timer_info.cycles.resolution == 1) {
ut_timer = sys_timer_info.cycles;
ut_timer_now = &my_timer_cycles;
} else if (sys_timer_info.nanoseconds.frequency > 1000000 &&
sys_timer_info.nanoseconds.resolution == 1) {
ut_timer = sys_timer_info.nanoseconds;
ut_timer_now = &my_timer_nanoseconds;
} else if (sys_timer_info.microseconds.frequency >= 1000000 &&
sys_timer_info.microseconds.resolution == 1) {
ut_timer = sys_timer_info.microseconds;
ut_timer_now = &my_timer_microseconds;
} else if (sys_timer_info.milliseconds.frequency >= 1000 &&
sys_timer_info.milliseconds.resolution == 1) {
ut_timer = sys_timer_info.milliseconds;
ut_timer_now = &my_timer_milliseconds;
} else if (sys_timer_info.ticks.frequency >= 1000 &&
/* Will probably be false */
sys_timer_info.ticks.resolution == 1) {
ut_timer = sys_timer_info.ticks;
ut_timer_now = &my_timer_ticks;
} else {
/* None are acceptable, so leave it as "None", and fill in struct */
ut_timer.frequency = 1; /* Avoid div-by-zero */
ut_timer.overhead = 0; /* Since it doesn't do anything */
ut_timer.resolution = 10; /* Another sign it's bad */
ut_timer.routine = 0; /* None */
}
}