summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-12-04 18:07:25 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2020-12-15 17:56:17 +0200
commitdb006a9a43b6e68c4b92d2762043fa76b313623c (patch)
tree0fb86f11c7d61fc57256a8115cb5aa6e92249737 /storage/innobase
parent38fd7b7d9170369b16ff553f01669182e70bc9b5 (diff)
downloadmariadb-git-db006a9a43b6e68c4b92d2762043fa76b313623c.tar.gz
MDEV-21452: Remove os_event_t, MUTEX_EVENT, TTASEventMutex, sync_array
We will default to MUTEXTYPE=sys (using OSTrackMutex) for those ib_mutex_t that have not been replaced yet. The view INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS is removed. The parameter innodb_sync_array_size is removed. FIXME: innodb_fatal_semaphore_wait_threshold will no longer be enforced. We should enforce it for lock_sys.mutex and dict_sys.mutex somehow! innodb_sync_debug=ON might still cover ib_mutex_t.
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/CMakeLists.txt5
-rw-r--r--storage/innobase/handler/ha_innodb.cc10
-rw-r--r--storage/innobase/handler/i_s.cc157
-rw-r--r--storage/innobase/handler/i_s.h44
-rw-r--r--storage/innobase/include/ib0mutex.h163
-rw-r--r--storage/innobase/include/os0event.h131
-rw-r--r--storage/innobase/include/srv0srv.h3
-rw-r--r--storage/innobase/include/sync0arr.h127
-rw-r--r--storage/innobase/include/sync0arr.ic82
-rw-r--r--storage/innobase/include/sync0types.h2
-rw-r--r--storage/innobase/include/ut0mutex.h4
-rw-r--r--storage/innobase/include/ut0new.h2
-rw-r--r--storage/innobase/innodb.cmake6
-rw-r--r--storage/innobase/os/os0event.cc515
-rw-r--r--storage/innobase/srv/srv0srv.cc41
-rw-r--r--storage/innobase/srv/srv0start.cc28
-rw-r--r--storage/innobase/sync/sync0arr.cc960
-rw-r--r--storage/innobase/sync/sync0debug.cc7
18 files changed, 14 insertions, 2273 deletions
diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
index 530124e16aa..5a5c268763a 100644
--- a/storage/innobase/CMakeLists.txt
+++ b/storage/innobase/CMakeLists.txt
@@ -187,7 +187,6 @@ SET(INNOBASE_SOURCES
include/mtr0mtr.h
include/mtr0mtr.ic
include/mtr0types.h
- include/os0event.h
include/os0file.h
include/os0file.ic
include/os0thread.h
@@ -239,8 +238,6 @@ SET(INNOBASE_SOURCES
include/srv0mon.ic
include/srv0srv.h
include/srv0start.h
- include/sync0arr.h
- include/sync0arr.ic
include/sync0debug.h
include/sync0policy.h
include/sux_lock.h
@@ -294,7 +291,6 @@ SET(INNOBASE_SOURCES
mem/mem0mem.cc
mtr/mtr0mtr.cc
os/os0file.cc
- os/os0event.cc
os/os0thread.cc
page/page0cur.cc
page/page0page.cc
@@ -328,7 +324,6 @@ SET(INNOBASE_SOURCES
srv/srv0srv.cc
srv/srv0start.cc
sync/srw_lock.cc
- sync/sync0arr.cc
sync/sync0debug.cc
sync/sync0sync.cc
trx/trx0i_s.cc
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 9393761974a..e38cccf0f34 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -18444,14 +18444,6 @@ static MYSQL_SYSVAR_UINT(purge_threads, srv_n_purge_threads,
"Number of tasks for purging transaction history",
NULL, NULL, 4, 1, innodb_purge_threads_MAX, 0);
-static MYSQL_SYSVAR_ULONG(sync_array_size, srv_sync_array_size,
- PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
- "Size of the mutex/lock wait array.",
- NULL, NULL,
- 1, /* Default setting */
- 1, /* Minimum value */
- 1024, 0); /* Maximum value */
-
static MYSQL_SYSVAR_UINT(fast_shutdown, srv_fast_shutdown,
PLUGIN_VAR_OPCMDARG,
"Speeds up the shutdown process of the InnoDB storage engine. Possible"
@@ -19471,7 +19463,6 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(undo_log_truncate),
MYSQL_SYSVAR(undo_directory),
MYSQL_SYSVAR(undo_tablespaces),
- MYSQL_SYSVAR(sync_array_size),
MYSQL_SYSVAR(compression_failure_threshold_pct),
MYSQL_SYSVAR(compression_pad_pct_max),
MYSQL_SYSVAR(default_row_format),
@@ -19554,7 +19545,6 @@ i_s_innodb_sys_foreign,
i_s_innodb_sys_foreign_cols,
i_s_innodb_sys_tablespaces,
i_s_innodb_sys_virtual,
-i_s_innodb_sys_semaphore_waits,
i_s_innodb_tablespaces_encryption
maria_declare_plugin_end;
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index 6eaacfd800a..6314bdc940d 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -22,7 +22,6 @@ this program; if not, write to the Free Software Foundation, Inc.,
InnoDB INFORMATION SCHEMA tables interface to MySQL.
Created July 18, 2007 Vasil Dimov
-Modified Dec 29, 2014 Jan Lindström (Added sys_semaphore_waits)
*******************************************************/
#include "univ.i"
@@ -54,7 +53,6 @@ Modified Dec 29, 2014 Jan Lindström (Added sys_semaphore_waits)
#include "fts0priv.h"
#include "btr0btr.h"
#include "page0zip.h"
-#include "sync0arr.h"
#include "fil0fil.h"
#include "fil0crypt.h"
#include "dict0crea.h"
@@ -171,20 +169,6 @@ time_t MYSQL_TYPE_DATETIME
---------------------------------
*/
-/** Implemented on sync0arr.cc */
-/*******************************************************************//**
-Function to populate INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS table.
-Loop through each item on sync array, and extract the column
-information and fill the INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS table.
-@return 0 on success */
-UNIV_INTERN
-int
-sync_arr_fill_sys_semphore_waits_table(
-/*===================================*/
- THD* thd, /*!< in: thread */
- TABLE_LIST* tables, /*!< in/out: tables to fill */
- Item* ); /*!< in: condition (not used) */
-
/*******************************************************************//**
Common function to fill any of the dynamic tables:
INFORMATION_SCHEMA.innodb_trx
@@ -245,6 +229,7 @@ field_store_time_t(
/*******************************************************************//**
Auxiliary function to store char* value in MYSQL_TYPE_STRING field.
@return 0 on success */
+static
int
field_store_string(
/*===============*/
@@ -6879,143 +6864,3 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_tablespaces_encryption =
STRUCT_FLD(version_info, INNODB_VERSION_STR),
STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE)
};
-
-namespace Show {
-/* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS */
-static ST_FIELD_INFO innodb_sys_semaphore_waits_fields_info[] =
-{
- // SYS_SEMAPHORE_WAITS_THREAD_ID 0
- Column("THREAD_ID", ULonglong(), NOT_NULL),
-
- // SYS_SEMAPHORE_WAITS_OBJECT_NAME 1
- Column("OBJECT_NAME", Varchar(OS_FILE_MAX_PATH), NULLABLE),
-
- // SYS_SEMAPHORE_WAITS_FILE 2
- Column("FILE", Varchar(OS_FILE_MAX_PATH), NULLABLE),
-
- // SYS_SEMAPHORE_WAITS_LINE 3
- Column("LINE", ULong(), NOT_NULL),
-
- // SYS_SEMAPHORE_WAITS_WAIT_TIME 4
- Column("WAIT_TIME", ULonglong(), NOT_NULL),
-
- // SYS_SEMAPHORE_WAITS_WAIT_OBJECT 5
- Column("WAIT_OBJECT", ULonglong(), NOT_NULL),
-
- // SYS_SEMAPHORE_WAITS_WAIT_TYPE 6
- Column("WAIT_TYPE", Varchar(16), NULLABLE),
-
- // SYS_SEMAPHORE_WAITS_HOLDER_THREAD_ID 7
- Column("HOLDER_THREAD_ID", ULonglong(), NOT_NULL),
-
- // SYS_SEMAPHORE_WAITS_HOLDER_FILE 8
- Column("HOLDER_FILE", Varchar(OS_FILE_MAX_PATH), NULLABLE),
-
- // SYS_SEMAPHORE_WAITS_HOLDER_LINE 9
- Column("HOLDER_LINE", ULong(), NOT_NULL),
-
- // SYS_SEMAPHORE_WAITS_CREATED_FILE 10
- Column("CREATED_FILE", Varchar(OS_FILE_MAX_PATH), NULLABLE),
-
- // SYS_SEMAPHORE_WAITS_CREATED_LINE 11
- Column("CREATED_LINE", ULong(), NOT_NULL),
-
- // SYS_SEMAPHORE_WAITS_WRITER_THREAD 12
- Column("WRITER_THREAD", ULonglong(), NOT_NULL),
-
- // SYS_SEMAPHORE_WAITS_RESERVATION_MODE 13
- Column("RESERVATION_MODE", Varchar(16), NULLABLE),
-
- // SYS_SEMAPHORE_WAITS_READERS 14
- Column("READERS", ULong(), NOT_NULL),
-
- // SYS_SEMAPHORE_WAITS_WAITERS_FLAG 15
- Column("WAITERS_FLAG", ULonglong(), NOT_NULL),
-
- // SYS_SEMAPHORE_WAITS_LOCK_WORD 16
- Column("LOCK_WORD", ULonglong(), NOT_NULL),
-
- // SYS_SEMAPHORE_WAITS_LAST_WRITER_FILE 17
- Column("LAST_WRITER_FILE", Varchar(OS_FILE_MAX_PATH), NULLABLE),
-
- // SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE 18
- Column("LAST_WRITER_LINE", ULong(), NOT_NULL),
-
- // SYS_SEMAPHORE_WAITS_OS_WAIT_COUNT 19
- Column("OS_WAIT_COUNT", ULong(), NOT_NULL),
-
- CEnd()
-};
-} // namespace Show
-
-
-
-/*******************************************************************//**
-Bind the dynamic table INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS
-@return 0 on success */
-static
-int
-innodb_sys_semaphore_waits_init(
-/*============================*/
- void* p) /*!< in/out: table schema object */
-{
- ST_SCHEMA_TABLE* schema;
-
- DBUG_ENTER("innodb_sys_semaphore_waits_init");
-
- schema = (ST_SCHEMA_TABLE*) p;
-
- schema->fields_info = Show::innodb_sys_semaphore_waits_fields_info;
- schema->fill_table = sync_arr_fill_sys_semphore_waits_table;
-
- DBUG_RETURN(0);
-}
-
-UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_semaphore_waits =
-{
- /* the plugin type (a MYSQL_XXX_PLUGIN value) */
- /* int */
- STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
-
- /* pointer to type-specific plugin descriptor */
- /* void* */
- STRUCT_FLD(info, &i_s_info),
-
- /* plugin name */
- /* const char* */
- STRUCT_FLD(name, "INNODB_SYS_SEMAPHORE_WAITS"),
-
- /* plugin author (for SHOW PLUGINS) */
- /* const char* */
- STRUCT_FLD(author, maria_plugin_author),
-
- /* general descriptive text (for SHOW PLUGINS) */
- /* const char* */
- STRUCT_FLD(descr, "InnoDB SYS_SEMAPHORE_WAITS"),
-
- /* the plugin license (PLUGIN_LICENSE_XXX) */
- /* int */
- STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
-
- /* the function to invoke when plugin is loaded */
- /* int (*)(void*); */
- STRUCT_FLD(init, innodb_sys_semaphore_waits_init),
-
- /* the function to invoke when plugin is unloaded */
- /* int (*)(void*); */
- STRUCT_FLD(deinit, i_s_common_deinit),
-
- /* plugin version (for SHOW PLUGINS) */
- /* unsigned int */
- STRUCT_FLD(version, INNODB_VERSION_SHORT),
-
- /* struct st_mysql_show_var* */
- STRUCT_FLD(status_vars, NULL),
-
- /* struct st_mysql_sys_var** */
- STRUCT_FLD(system_vars, NULL),
-
- /* Maria extension */
- STRUCT_FLD(version_info, INNODB_VERSION_STR),
- STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE),
-};
diff --git a/storage/innobase/handler/i_s.h b/storage/innobase/handler/i_s.h
index 9947721407a..395bc3e7909 100644
--- a/storage/innobase/handler/i_s.h
+++ b/storage/innobase/handler/i_s.h
@@ -61,7 +61,6 @@ extern struct st_maria_plugin i_s_innodb_sys_foreign_cols;
extern struct st_maria_plugin i_s_innodb_sys_tablespaces;
extern struct st_maria_plugin i_s_innodb_sys_virtual;
extern struct st_maria_plugin i_s_innodb_tablespaces_encryption;
-extern struct st_maria_plugin i_s_innodb_sys_semaphore_waits;
/** The latest successfully looked up innodb_fts_aux_table */
extern table_id_t innodb_ft_aux_table_id;
@@ -99,47 +98,4 @@ do { \
#define STRUCT_FLD(name, value) value
#endif
-/* Don't use a static const variable here, as some C++ compilers (notably
-HPUX aCC: HP ANSI C++ B3910B A.03.65) can't handle it. */
-#define END_OF_ST_FIELD_INFO \
- {STRUCT_FLD(field_name, NULL), \
- STRUCT_FLD(field_length, 0), \
- STRUCT_FLD(field_type, MYSQL_TYPE_NULL), \
- STRUCT_FLD(value, 0), \
- STRUCT_FLD(field_flags, 0), \
- STRUCT_FLD(old_name, ""), \
- STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}
-
-/** Fields on INFORMATION_SCHEMA.SYS_SEMAMPHORE_WAITS table */
-#define SYS_SEMAPHORE_WAITS_THREAD_ID 0
-#define SYS_SEMAPHORE_WAITS_OBJECT_NAME 1
-#define SYS_SEMAPHORE_WAITS_FILE 2
-#define SYS_SEMAPHORE_WAITS_LINE 3
-#define SYS_SEMAPHORE_WAITS_WAIT_TIME 4
-#define SYS_SEMAPHORE_WAITS_WAIT_OBJECT 5
-#define SYS_SEMAPHORE_WAITS_WAIT_TYPE 6
-#define SYS_SEMAPHORE_WAITS_HOLDER_THREAD_ID 7
-#define SYS_SEMAPHORE_WAITS_HOLDER_FILE 8
-#define SYS_SEMAPHORE_WAITS_HOLDER_LINE 9
-#define SYS_SEMAPHORE_WAITS_CREATED_FILE 10
-#define SYS_SEMAPHORE_WAITS_CREATED_LINE 11
-#define SYS_SEMAPHORE_WAITS_WRITER_THREAD 12
-#define SYS_SEMAPHORE_WAITS_RESERVATION_MODE 13
-#define SYS_SEMAPHORE_WAITS_READERS 14
-#define SYS_SEMAPHORE_WAITS_WAITERS_FLAG 15
-#define SYS_SEMAPHORE_WAITS_LOCK_WORD 16
-#define SYS_SEMAPHORE_WAITS_LAST_WRITER_FILE 17
-#define SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE 18
-#define SYS_SEMAPHORE_WAITS_OS_WAIT_COUNT 19
-
-/*******************************************************************//**
-Auxiliary function to store char* value in MYSQL_TYPE_STRING field.
-@return 0 on success */
-int
-field_store_string(
-/*===============*/
- Field* field, /*!< in/out: target field for storage */
- const char* str); /*!< in: NUL-terminated utf-8 string,
- or NULL */
-
#endif /* i_s_h */
diff --git a/storage/innobase/include/ib0mutex.h b/storage/innobase/include/ib0mutex.h
index 781b688e0b1..b83a1aac419 100644
--- a/storage/innobase/include/ib0mutex.h
+++ b/storage/innobase/include/ib0mutex.h
@@ -30,8 +30,6 @@ Created 2013-03-26 Sunny Bains.
#define ib0mutex_h
#include "my_cpu.h"
-#include "os0event.h"
-#include "sync0arr.h"
/** OS mutex for tracking lock/unlock for debugging */
template <template <typename> class Policy>
@@ -363,167 +361,6 @@ private:
std::atomic<uint32_t> m_lock_word;
};
-template <template <typename> class Policy>
-struct TTASEventMutex {
-
- typedef Policy<TTASEventMutex> MutexPolicy;
-
- TTASEventMutex()
- UNIV_NOTHROW
- :
- m_lock_word(MUTEX_STATE_UNLOCKED),
- m_event()
- {
- /* Check that lock_word is aligned. */
- ut_ad(!((ulint) &m_lock_word % sizeof(ulint)));
- }
-
- ~TTASEventMutex()
- UNIV_NOTHROW
- {
- ut_ad(state() == MUTEX_STATE_UNLOCKED);
- }
-
- /** Called when the mutex is "created". Note: Not from the constructor
- but when the mutex is initialised.
- @param[in] id Mutex ID */
- void init(latch_id_t id, const char*, uint32_t) UNIV_NOTHROW
- {
- ut_a(m_event == 0);
- ut_ad(state() == MUTEX_STATE_UNLOCKED);
-
- m_event = os_event_create(sync_latch_get_name(id));
- }
-
- /** This is the real desctructor. This mutex can be created in BSS and
- its desctructor will be called on exit(). We can't call
- os_event_destroy() at that stage. */
- void destroy()
- UNIV_NOTHROW
- {
- ut_ad(state() == MUTEX_STATE_UNLOCKED);
-
- /* We have to free the event before InnoDB shuts down. */
- os_event_destroy(m_event);
- m_event = 0;
- }
-
- /** Try and lock the mutex. Note: POSIX returns 0 on success.
- @return true on success */
- bool try_lock()
- UNIV_NOTHROW
- {
- uint32_t oldval = MUTEX_STATE_UNLOCKED;
- return m_lock_word.compare_exchange_strong(
- oldval,
- MUTEX_STATE_LOCKED,
- std::memory_order_acquire,
- std::memory_order_relaxed);
- }
-
- /** Release the mutex. */
- void exit()
- UNIV_NOTHROW
- {
- if (m_lock_word.exchange(MUTEX_STATE_UNLOCKED,
- std::memory_order_release)
- == MUTEX_STATE_WAITERS) {
- os_event_set(m_event);
- sync_array_object_signalled();
- }
- }
-
- /** Acquire the mutex.
- @param[in] max_spins max number of spins
- @param[in] max_delay max delay per spin
- @param[in] filename from where called
- @param[in] line within filename */
- void enter(
- uint32_t max_spins,
- uint32_t max_delay,
- const char* filename,
- uint32_t line)
- UNIV_NOTHROW
- {
- uint32_t n_spins = 0;
- uint32_t n_waits = 0;
- const uint32_t step = max_spins;
-
- while (!try_lock()) {
- if (n_spins++ == max_spins) {
- max_spins += step;
- n_waits++;
- os_thread_yield();
-
- sync_cell_t* cell;
- sync_array_t *sync_arr = sync_array_get_and_reserve_cell(
- this,
- filename, line, &cell);
-
- uint32_t oldval = MUTEX_STATE_LOCKED;
- m_lock_word.compare_exchange_strong(
- oldval,
- MUTEX_STATE_WAITERS,
- std::memory_order_relaxed,
- std::memory_order_relaxed);
-
- if (oldval == MUTEX_STATE_UNLOCKED) {
- sync_array_free_cell(sync_arr, cell);
- } else {
- sync_array_wait_event(sync_arr, cell);
- }
- } else {
- ut_delay(max_delay);
- }
- }
-
- m_policy.add(n_spins, n_waits);
- }
-
- /** @return the lock state. */
- int32 state() const
- UNIV_NOTHROW
- {
- return m_lock_word.load(std::memory_order_relaxed);
- }
-
- /** The event that the mutex will wait in sync0arr.cc
- @return even instance */
- os_event_t event()
- UNIV_NOTHROW
- {
- return(m_event);
- }
-
- /** @return non-const version of the policy */
- MutexPolicy& policy()
- UNIV_NOTHROW
- {
- return(m_policy);
- }
-
- /** @return const version of the policy */
- const MutexPolicy& policy() const
- UNIV_NOTHROW
- {
- return(m_policy);
- }
-
-private:
- /** Disable copying */
- TTASEventMutex(const TTASEventMutex&);
- TTASEventMutex& operator=(const TTASEventMutex&);
-
- /** mutex state */
- std::atomic<uint32_t> m_lock_word;
-
- /** Used by sync0arr.cc for the wait queue */
- os_event_t m_event;
-
- /** Policy data */
- MutexPolicy m_policy;
-};
-
/** Mutex interface for all policy mutexes. This class handles the interfacing
with the Performance Schema instrumentation. */
template <typename MutexImpl>
diff --git a/storage/innobase/include/os0event.h b/storage/innobase/include/os0event.h
deleted file mode 100644
index 52f6500ae63..00000000000
--- a/storage/innobase/include/os0event.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*****************************************************************************
-Copyright (c) 1995, 2014, 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, Fifth Floor, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-/**************************************************//**
-@file include/os0event.h
-The interface to the operating system condition variables
-
-Created 2012-09-23 Sunny Bains (split from os0sync.h)
-*******************************************************/
-
-#ifndef os0event_h
-#define os0event_h
-
-#include "univ.i"
-
-// Forward declaration.
-struct os_event;
-typedef struct os_event* os_event_t;
-
-/** Denotes an infinite delay for os_event_wait_time() */
-#define OS_SYNC_INFINITE_TIME ULINT_UNDEFINED
-
-/** Return value of os_event_wait_time() when the time is exceeded */
-#define OS_SYNC_TIME_EXCEEDED 1
-
-/**
-Creates an event semaphore, i.e., a semaphore which may just have two states:
-signaled and nonsignaled. The created event is manual reset: it must be reset
-explicitly by calling os_event_reset().
-@return the event handle */
-os_event_t os_event_create(const char*);
-
-/**
-Sets an event semaphore to the signaled state: lets waiting threads
-proceed. */
-void
-os_event_set(
-/*=========*/
- os_event_t event); /*!< in/out: event to set */
-
-/**
-Check if the event is set.
-@return true if set */
-bool
-os_event_is_set(
-/*============*/
- const os_event_t event); /*!< in: event to set */
-
-/**
-Resets an event semaphore to the nonsignaled state. Waiting threads will
-stop to wait for the event.
-The return value should be passed to os_even_wait_low() if it is desired
-that this thread should not wait in case of an intervening call to
-os_event_set() between this os_event_reset() and the
-os_event_wait_low() call. See comments for os_event_wait_low(). */
-int64_t
-os_event_reset(
-/*===========*/
- os_event_t event); /*!< in/out: event to reset */
-
-/**
-Frees an event object. */
-void
-os_event_destroy(
-/*=============*/
- os_event_t& event); /*!< in/own: event to free */
-
-/**
-Waits for an event object until it is in the signaled state.
-
-Typically, if the event has been signalled after the os_event_reset()
-we'll return immediately because event->is_set == TRUE.
-There are, however, situations (e.g.: sync_array code) where we may
-lose this information. For example:
-
-thread A calls os_event_reset()
-thread B calls os_event_set() [event->is_set == TRUE]
-thread C calls os_event_reset() [event->is_set == FALSE]
-thread A calls os_event_wait() [infinite wait!]
-thread C calls os_event_wait() [infinite wait!]
-
-Where such a scenario is possible, to avoid infinite wait, the
-value returned by os_event_reset() should be passed in as
-reset_sig_count. */
-void
-os_event_wait_low(
-/*==============*/
- os_event_t event, /*!< in/out: event to wait */
- int64_t reset_sig_count);/*!< in: zero or the value
- returned by previous call of
- os_event_reset(). */
-
-/** Blocking infinite wait on an event, until signealled.
-@param e - event to wait on. */
-#define os_event_wait(e) os_event_wait_low((e), 0)
-
-/**
-Waits for an event object until it is in the signaled state or
-a timeout is exceeded. In Unix the timeout is always infinite.
-@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
-ulint
-os_event_wait_time_low(
-/*===================*/
- os_event_t event, /*!< in/out: event to wait */
- ulint time_in_usec, /*!< in: timeout in
- microseconds, or
- OS_SYNC_INFINITE_TIME */
- int64_t reset_sig_count); /*!< in: zero or the value
- returned by previous call of
- os_event_reset(). */
-
-/** Blocking timed wait on an event.
-@param e - event to wait on.
-@param t - timeout in microseconds */
-#define os_event_wait_time(e, t) os_event_wait_time_low((e), (t), 0)
-
-#endif /* !os0event_h */
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index 8554a48018f..5aedd122a0f 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -45,6 +45,7 @@ Created 10/10/1995 Heikki Tuuri
#include "que0types.h"
#include "trx0types.h"
#include "fil0fil.h"
+#include "ut0counter.h"
#include "mysql/psi/mysql_stage.h"
#include "mysql/psi/psi.h"
@@ -184,7 +185,7 @@ struct srv_stats_t
};
/** We are prepared for a situation that we have this many threads waiting for
-a semaphore inside InnoDB. srv_start() sets the value. */
+a transactional lock inside InnoDB. srv_start() sets the value. */
extern ulint srv_max_n_threads;
extern const char* srv_main_thread_op_info;
diff --git a/storage/innobase/include/sync0arr.h b/storage/innobase/include/sync0arr.h
deleted file mode 100644
index 48ee967aa3e..00000000000
--- a/storage/innobase/include/sync0arr.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2020, 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/sync0arr.h
-The wait array used in synchronization primitives
-
-Created 9/5/1995 Heikki Tuuri
-*******************************************************/
-
-#ifndef sync0arr_h
-#define sync0arr_h
-
-#include "univ.i"
-
-/** Synchronization wait array cell */
-struct sync_cell_t;
-
-/** Synchronization wait array */
-struct sync_array_t;
-
-/******************************************************************//**
-Get an instance of the sync wait array and reserve a wait array cell
-in the instance for waiting for an object. The event of the cell is
-reset to nonsignalled state.
-If reserving cell of the instance fails, try to get another new
-instance until we can reserve an empty cell of it.
-@return the sync array found, never NULL. */
-UNIV_INLINE
-sync_array_t*
-sync_array_get_and_reserve_cell(
- void* object, /*!< in: pointer to the object to wait for */
- const char* file, /*!< in: file where requested */
- unsigned line, /*!< in: line where requested */
- sync_cell_t** cell); /*!< out: the cell reserved, never NULL */
-/******************************************************************//**
-Reserves a wait array cell for waiting for an object.
-The event of the cell is reset to nonsignalled state. */
-sync_cell_t*
-sync_array_reserve_cell(
- sync_array_t* arr, /*!< in: wait array */
- void* object, /*!< in: pointer to the object to wait for */
- const char* file, /*!< in: file where requested */
- unsigned line); /*!< in: line where requested */
-
-/******************************************************************//**
-This function should be called when a thread starts to wait on
-a wait array cell. In the debug version this function checks
-if the wait for a semaphore will result in a deadlock, in which
-case prints info and asserts. */
-void
-sync_array_wait_event(
- sync_array_t* arr, /*!< in: wait array */
- sync_cell_t*& cell); /*!< in: the reserved cell */
-
-/******************************************************************//**
-Frees the cell. NOTE! sync_array_wait_event frees the cell
-automatically! */
-void
-sync_array_free_cell(
- sync_array_t* arr, /*!< in: wait array */
- sync_cell_t*& cell); /*!< in: the reserved cell */
-
-/** count of how many times an object has been signalled */
-extern ulint sg_count;
-#define sync_array_object_signalled() ++sg_count
-
-/**********************************************************************//**
-Prints warnings of long semaphore waits to stderr.
-@return TRUE if fatal semaphore wait threshold was exceeded */
-ibool
-sync_array_print_long_waits(
- os_thread_id_t* waiter, /*!< out: longest waiting thread */
- const void** sema); /*!< out: longest-waited-for semaphore */
-
-/**********************************************************************//**
-Prints info of the wait array. */
-void
-sync_array_print(
- FILE* file); /*!< in: file where to print */
-
-/** Create the primary system wait arrays */
-void sync_array_init();
-
-/** Destroy the sync array wait sub-system. */
-void sync_array_close();
-
-/**********************************************************************//**
-Get an instance of the sync wait array. */
-UNIV_INLINE
-sync_array_t*
-sync_array_get();
-/**********************************************************************//**
-Prints info of the wait array without using any mutexes/semaphores. */
-UNIV_INTERN
-void
-sync_array_print_innodb(void);
-
-/*****************************************************************//**
-Gets the nth cell in array.
-@return cell */
-UNIV_INTERN
-sync_cell_t*
-sync_array_get_nth_cell(
-/*====================*/
- sync_array_t* arr, /*!< in: sync array */
- ulint n); /*!< in: index */
-
-#include "sync0arr.ic"
-
-#endif /* sync0arr_h */
diff --git a/storage/innobase/include/sync0arr.ic b/storage/innobase/include/sync0arr.ic
deleted file mode 100644
index 503206b7170..00000000000
--- a/storage/innobase/include/sync0arr.ic
+++ /dev/null
@@ -1,82 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2020, 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/sync0arr.ic
-The wait array for synchronization primitives
-
-Inline code
-
-Created 9/5/1995 Heikki Tuuri
-*******************************************************/
-
-extern ulint sync_array_size;
-extern sync_array_t** sync_wait_array;
-
-#include "ut0counter.h"
-
-/**********************************************************************//**
-Get an instance of the sync wait array.
-@return an instance of the sync wait array. */
-
-UNIV_INLINE
-sync_array_t*
-sync_array_get()
-/*============*/
-{
- if (sync_array_size <= 1) {
- return(sync_wait_array[0]);
- }
-
- return(sync_wait_array[get_rnd_value() % sync_array_size]);
-}
-
-/******************************************************************//**
-Get an instance of the sync wait array and reserve a wait array cell
-in the instance for waiting for an object. The event of the cell is
-reset to nonsignalled state.
-If reserving cell of the instance fails, try to get another new
-instance until we can reserve an empty cell of it.
-@return the sync array reserved, never NULL. */
-UNIV_INLINE
-sync_array_t*
-sync_array_get_and_reserve_cell(
- void* object, /*!< in: pointer to the object to wait for */
- const char* file, /*!< in: file where requested */
- unsigned line, /*!< in: line where requested */
- sync_cell_t** cell) /*!< out: the cell reserved, never NULL */
-{
- sync_array_t* sync_arr = NULL;
-
- *cell = NULL;
- for (ulint i = 0; i < sync_array_size && *cell == NULL; ++i) {
- /* Although the sync_array is get in a random way currently,
- we still try at most sync_array_size times, in case any
- of the sync_array we get is full */
- sync_arr = sync_array_get();
- *cell = sync_array_reserve_cell(sync_arr, object, file, line);
- }
-
- /* This won't be true every time, for the loop above may execute
- more than srv_sync_array_size times to reserve a cell.
- But an assertion here makes the code more solid. */
- ut_a(*cell != NULL);
-
- return(sync_arr);
-}
diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h
index 20dc9494c20..f8df704c9d9 100644
--- a/storage/innobase/include/sync0types.h
+++ b/storage/innobase/include/sync0types.h
@@ -178,8 +178,6 @@ LatchDebug internals in sync0debug.cc */
enum latch_level_t {
SYNC_UNKNOWN = 0,
- SYNC_MUTEX = 1,
-
RW_LOCK_SX,
RW_LOCK_X_WAIT,
RW_LOCK_S,
diff --git a/storage/innobase/include/ut0mutex.h b/storage/innobase/include/ut0mutex.h
index cb43583c21d..89c903b48f1 100644
--- a/storage/innobase/include/ut0mutex.h
+++ b/storage/innobase/include/ut0mutex.h
@@ -41,7 +41,6 @@ UT_MUTEX_TYPE(TTASFutexMutex, GenericPolicy, FutexMutex);
UT_MUTEX_TYPE(TTASMutex, GenericPolicy, SpinMutex);
UT_MUTEX_TYPE(OSTrackMutex, GenericPolicy, SysMutex);
-UT_MUTEX_TYPE(TTASEventMutex, GenericPolicy, SyncArrayMutex);
#ifdef MUTEX_FUTEX
/** The default mutex type. */
@@ -50,9 +49,6 @@ typedef FutexMutex ib_mutex_t;
#elif defined(MUTEX_SYS)
typedef SysMutex ib_mutex_t;
#define MUTEX_TYPE "Uses system mutexes"
-#elif defined(MUTEX_EVENT)
-typedef SyncArrayMutex ib_mutex_t;
-#define MUTEX_TYPE "Uses event mutexes"
#else
#error "ib_mutex_t type is unknown"
#endif /* MUTEX_FUTEX */
diff --git a/storage/innobase/include/ut0new.h b/storage/innobase/include/ut0new.h
index 57c94a57020..3fc7664c34e 100644
--- a/storage/innobase/include/ut0new.h
+++ b/storage/innobase/include/ut0new.h
@@ -868,7 +868,6 @@ constexpr const char* const auto_event_names[] =
"lexyy",
"lock0lock",
"mem0mem",
- "os0event",
"os0file",
"pars0lex",
"rem0rec",
@@ -879,7 +878,6 @@ constexpr const char* const auto_event_names[] =
"row0mysql",
"row0sel",
"srv0start",
- "sync0arr",
"sync0debug",
"sync0start",
"sync0types",
diff --git a/storage/innobase/innodb.cmake b/storage/innobase/innodb.cmake
index 385e87f828e..83232a4d66c 100644
--- a/storage/innobase/innodb.cmake
+++ b/storage/innobase/innodb.cmake
@@ -137,11 +137,9 @@ IF(HAVE_C99_INITIALIZERS)
ADD_DEFINITIONS(-DHAVE_C99_INITIALIZERS)
ENDIF()
-SET(MUTEXTYPE "event" CACHE STRING "Mutex type: event, sys or futex")
+SET(MUTEXTYPE "sys" CACHE STRING "Mutex type: sys or futex")
-IF(MUTEXTYPE MATCHES "event")
- ADD_DEFINITIONS(-DMUTEX_EVENT)
-ELSEIF(MUTEXTYPE MATCHES "futex" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
+IF(MUTEXTYPE MATCHES "futex" AND DEFINED HAVE_IB_LINUX_FUTEX)
ADD_DEFINITIONS(-DMUTEX_FUTEX)
ELSE()
ADD_DEFINITIONS(-DMUTEX_SYS)
diff --git a/storage/innobase/os/os0event.cc b/storage/innobase/os/os0event.cc
deleted file mode 100644
index f18633ccd45..00000000000
--- a/storage/innobase/os/os0event.cc
+++ /dev/null
@@ -1,515 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 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 os/os0event.cc
-The interface to the operating system condition variables.
-
-Created 2012-09-23 Sunny Bains
-*******************************************************/
-
-#include "os0event.h"
-#include "ut0mutex.h"
-#include <my_sys.h>
-
-#ifdef _WIN32
-#include <windows.h>
-#include <synchapi.h>
-/** Native condition variable. */
-typedef CONDITION_VARIABLE os_cond_t;
-#else
-/** Native condition variable */
-typedef pthread_cond_t os_cond_t;
-#endif /* _WIN32 */
-
-/** InnoDB condition variable. */
-struct os_event {
- os_event() UNIV_NOTHROW;
-
- ~os_event() UNIV_NOTHROW;
-
- /**
- Destroys a condition variable */
- void destroy() UNIV_NOTHROW
- {
-#ifndef _WIN32
- int ret = pthread_cond_destroy(&cond_var);
- ut_a(ret == 0);
-#endif /* !_WIN32 */
-
- mutex.destroy();
- }
-
- /** Set the event */
- void set() UNIV_NOTHROW
- {
- mutex.enter();
-
- if (!m_set) {
- broadcast();
- }
-
- mutex.exit();
- }
-
- int64_t reset() UNIV_NOTHROW
- {
- mutex.enter();
-
- if (m_set) {
- m_set = false;
- }
-
- int64_t ret = signal_count;
-
- mutex.exit();
-
- return(ret);
- }
-
- /**
- Waits for an event object until it is in the signaled state.
-
- Typically, if the event has been signalled after the os_event_reset()
- we'll return immediately because event->m_set == true.
- There are, however, situations (e.g.: sync_array code) where we may
- lose this information. For example:
-
- thread A calls os_event_reset()
- thread B calls os_event_set() [event->m_set == true]
- thread C calls os_event_reset() [event->m_set == false]
- thread A calls os_event_wait() [infinite wait!]
- thread C calls os_event_wait() [infinite wait!]
-
- Where such a scenario is possible, to avoid infinite wait, the
- value returned by reset() should be passed in as
- reset_sig_count. */
- void wait_low(int64_t reset_sig_count) UNIV_NOTHROW;
-
- /**
- Waits for an event object until it is in the signaled state or
- a timeout is exceeded.
- @param time_in_usec - timeout in microseconds,
- or OS_SYNC_INFINITE_TIME
- @param reset_sig_count- zero or the value returned by
- previous call of os_event_reset().
- @return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
- ulint wait_time_low(
- ulint time_in_usec,
- int64_t reset_sig_count) UNIV_NOTHROW;
-
- /** @return true if the event is in the signalled state. */
- bool is_set() const UNIV_NOTHROW
- {
- mutex.enter();
- bool is_set = m_set;
- mutex.exit();
- return is_set;
- }
-
-private:
- /**
- Initialize a condition variable */
- void init() UNIV_NOTHROW
- {
-
- mutex.init();
-
-#ifdef _WIN32
- InitializeConditionVariable(&cond_var);
-#else
- {
- int ret;
-
- ret = pthread_cond_init(&cond_var, NULL);
- ut_a(ret == 0);
- }
-#endif /* _WIN32 */
- }
-
- /**
- Wait on condition variable */
- void wait() UNIV_NOTHROW
- {
-#ifdef _WIN32
- if (!SleepConditionVariableCS(&cond_var, mutex, INFINITE)) {
- ut_error;
- }
-#else
- {
- int ret;
-
- ret = pthread_cond_wait(&cond_var, mutex);
- ut_a(ret == 0);
- }
-#endif /* _WIN32 */
- }
-
- /**
- Wakes all threads waiting for condition variable */
- void broadcast() UNIV_NOTHROW
- {
- m_set = true;
- ++signal_count;
-
-#ifdef _WIN32
- WakeAllConditionVariable(&cond_var);
-#else
- {
- int ret;
-
- ret = pthread_cond_broadcast(&cond_var);
- ut_a(ret == 0);
- }
-#endif /* _WIN32 */
- }
-
- /**
- Wakes one thread waiting for condition variable */
- void signal() UNIV_NOTHROW
- {
-#ifdef _WIN32
- WakeConditionVariable(&cond_var);
-#else
- {
- int ret;
-
- ret = pthread_cond_signal(&cond_var);
- ut_a(ret == 0);
- }
-#endif /* _WIN32 */
- }
-
- /**
- Do a timed wait on condition variable.
- @param abstime - timeout
- @param time_in_ms - timeout in milliseconds.
- @return true if timed out, false otherwise */
- bool timed_wait(
-#ifndef _WIN32
- const timespec* abstime
-#else
- DWORD time_in_ms
-#endif /* !_WIN32 */
- );
-
-private:
- bool m_set; /*!< this is true when the
- event is in the signaled
- state, i.e., a thread does
- not stop if it tries to wait
- for this event */
- int64_t signal_count; /*!< this is incremented
- each time the event becomes
- signaled */
- mutable OSMutex mutex; /*!< this mutex protects
- the next fields */
-
-
- os_cond_t cond_var; /*!< condition variable is
- used in waiting for the event */
-
-protected:
- // Disable copying
- os_event(const os_event&);
- os_event& operator=(const os_event&);
-};
-
-/**
-Do a timed wait on condition variable.
-@param abstime - absolute time to wait
-@param time_in_ms - timeout in milliseconds
-@return true if timed out */
-bool
-os_event::timed_wait(
-#ifndef _WIN32
- const timespec* abstime
-#else
- DWORD time_in_ms
-#endif /* !_WIN32 */
-)
-{
-#ifdef _WIN32
- BOOL ret;
-
- ret = SleepConditionVariableCS(&cond_var, mutex, time_in_ms);
-
- if (!ret) {
- DWORD err = GetLastError();
-
- /* FQDN=msdn.microsoft.com
- @see http://$FQDN/en-us/library/ms686301%28VS.85%29.aspx,
-
- "Condition variables are subject to spurious wakeups
- (those not associated with an explicit wake) and stolen wakeups
- (another thread manages to run before the woken thread)."
- Check for both types of timeouts.
- Conditions are checked by the caller.*/
- if (err == WAIT_TIMEOUT || err == ERROR_TIMEOUT) {
- return(true);
- }
- }
-
- ut_a(ret);
-
- return(false);
-#else
- int ret;
-
- ret = pthread_cond_timedwait(&cond_var, mutex, abstime);
-
- switch (ret) {
- case 0:
- case ETIMEDOUT:
- /* We play it safe by checking for EINTR even though
- according to the POSIX documentation it can't return EINTR. */
- case EINTR:
- break;
-
- default:
- ib::error() << "pthread_cond_timedwait() returned: " << ret
- << ": abstime={" << abstime->tv_sec << ","
- << abstime->tv_nsec << "}";
- ut_error;
- }
-
- return(ret == ETIMEDOUT);
-#endif /* _WIN32 */
-}
-
-/**
-Waits for an event object until it is in the signaled state.
-
-Typically, if the event has been signalled after the os_event_reset()
-we'll return immediately because event->m_set == true.
-There are, however, situations (e.g.: sync_array code) where we may
-lose this information. For example:
-
-thread A calls os_event_reset()
-thread B calls os_event_set() [event->m_set == true]
-thread C calls os_event_reset() [event->m_set == false]
-thread A calls os_event_wait() [infinite wait!]
-thread C calls os_event_wait() [infinite wait!]
-
-Where such a scenario is possible, to avoid infinite wait, the
-value returned by reset() should be passed in as
-reset_sig_count. */
-void
-os_event::wait_low(
- int64_t reset_sig_count) UNIV_NOTHROW
-{
- mutex.enter();
-
- if (!reset_sig_count) {
- reset_sig_count = signal_count;
- }
-
- while (!m_set && signal_count == reset_sig_count) {
-
- wait();
-
- /* Spurious wakeups may occur: we have to check if the
- event really has been signaled after we came here to wait. */
- }
-
- mutex.exit();
-}
-
-/**
-Waits for an event object until it is in the signaled state or
-a timeout is exceeded.
-@param time_in_usec - timeout in microseconds, or OS_SYNC_INFINITE_TIME
-@param reset_sig_count - zero or the value returned by previous call
- of os_event_reset().
-@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
-ulint
-os_event::wait_time_low(
- ulint time_in_usec,
- int64_t reset_sig_count) UNIV_NOTHROW
-{
- bool timed_out = false;
-
-#ifdef _WIN32
- DWORD time_in_ms;
-
- if (time_in_usec != OS_SYNC_INFINITE_TIME) {
- time_in_ms = DWORD(time_in_usec / 1000);
- } else {
- time_in_ms = INFINITE;
- }
-#else
- struct timespec abstime;
-
- if (time_in_usec != OS_SYNC_INFINITE_TIME) {
- ulonglong usec = ulonglong(time_in_usec) + my_hrtime().val;
- abstime.tv_sec = static_cast<time_t>(usec / 1000000);
- abstime.tv_nsec = static_cast<uint>((usec % 1000000) * 1000);
- } else {
- abstime.tv_nsec = 999999999;
- abstime.tv_sec = (time_t) ULINT_MAX;
- }
-
- ut_a(abstime.tv_nsec <= 999999999);
-
-#endif /* _WIN32 */
-
- mutex.enter();
-
- if (!reset_sig_count) {
- reset_sig_count = signal_count;
- }
-
- do {
- if (m_set || signal_count != reset_sig_count) {
-
- break;
- }
-
-#ifndef _WIN32
- timed_out = timed_wait(&abstime);
-#else
- timed_out = timed_wait(time_in_ms);
-#endif /* !_WIN32 */
-
- } while (!timed_out);
-
- mutex.exit();
-
- return(timed_out ? OS_SYNC_TIME_EXCEEDED : 0);
-}
-
-/** Constructor */
-os_event::os_event() UNIV_NOTHROW
-{
- init();
-
- m_set = false;
-
- /* We return this value in os_event_reset(),
- which can then be be used to pass to the
- os_event_wait_low(). The value of zero is
- reserved in os_event_wait_low() for the case
- when the caller does not want to pass any
- signal_count value. To distinguish between
- the two cases we initialize signal_count
- to 1 here. */
-
- signal_count = 1;
-}
-
-/** Destructor */
-os_event::~os_event() UNIV_NOTHROW
-{
- destroy();
-}
-
-/**
-Creates an event semaphore, i.e., a semaphore which may just have two
-states: signaled and nonsignaled. The created event is manual reset: it
-must be reset explicitly by calling sync_os_reset_event.
-@return the event handle */
-os_event_t os_event_create(const char*)
-{
- return(UT_NEW_NOKEY(os_event()));
-}
-
-/**
-Check if the event is set.
-@return true if set */
-bool
-os_event_is_set(
-/*============*/
- const os_event_t event) /*!< in: event to test */
-{
- return(event->is_set());
-}
-
-/**
-Sets an event semaphore to the signaled state: lets waiting threads
-proceed. */
-void
-os_event_set(
-/*=========*/
- os_event_t event) /*!< in/out: event to set */
-{
- event->set();
-}
-
-/**
-Resets an event semaphore to the nonsignaled state. Waiting threads will
-stop to wait for the event.
-The return value should be passed to os_even_wait_low() if it is desired
-that this thread should not wait in case of an intervening call to
-os_event_set() between this os_event_reset() and the
-os_event_wait_low() call. See comments for os_event_wait_low().
-@return current signal_count. */
-int64_t
-os_event_reset(
-/*===========*/
- os_event_t event) /*!< in/out: event to reset */
-{
- return(event->reset());
-}
-
-/**
-Waits for an event object until it is in the signaled state or
-a timeout is exceeded.
-@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
-ulint
-os_event_wait_time_low(
-/*===================*/
- os_event_t event, /*!< in/out: event to wait */
- ulint time_in_usec, /*!< in: timeout in
- microseconds, or
- OS_SYNC_INFINITE_TIME */
- int64_t reset_sig_count) /*!< in: zero or the value
- returned by previous call of
- os_event_reset(). */
-{
- return(event->wait_time_low(time_in_usec, reset_sig_count));
-}
-
-/**
-Waits for an event object until it is in the signaled state.
-
-Where such a scenario is possible, to avoid infinite wait, the
-value returned by os_event_reset() should be passed in as
-reset_sig_count. */
-void
-os_event_wait_low(
-/*==============*/
- os_event_t event, /*!< in: event to wait */
- int64_t reset_sig_count) /*!< in: zero or the value
- returned by previous call of
- os_event_reset(). */
-{
- event->wait_low(reset_sig_count);
-}
-
-/**
-Frees an event object. */
-void
-os_event_destroy(
-/*=============*/
- os_event_t& event) /*!< in/own: event to free */
-
-{
- UT_DELETE(event);
- event = NULL;
-}
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index d176a69bee6..bb9b62dcde1 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -838,11 +838,11 @@ srv_printf_innodb_monitor(
"-----------------\n", file);
srv_print_master_thread_info(file);
+ /* This section is intentionally left blank, for tools like "innotop" */
fputs("----------\n"
"SEMAPHORES\n"
"----------\n", file);
-
- sync_array_print(file);
+ /* End of intentionally blank section */
/* Conceptually, srv_innodb_monitor_mutex has a very high latching
order level in sync0sync.h, while dict_foreign_err_mutex has a very
@@ -1347,21 +1347,11 @@ static void srv_monitor()
srv_refresh_innodb_monitor_stats(current_time);
}
-/*********************************************************************//**
-A task which prints warnings about semaphore waits which have lasted
-too long. These can be used to track bugs which cause hangs.
-*/
+/** Periodic task which prints the info output by various InnoDB monitors.*/
void srv_monitor_task(void*)
{
/* number of successive fatal timeouts observed */
- static ulint fatal_cnt;
static lsn_t old_lsn = recv_sys.recovered_lsn;
- /* longest waiting thread for a semaphore */
- os_thread_id_t waiter;
- static os_thread_id_t old_waiter = os_thread_get_curr_id();
- /* the semaphore that is being waited for */
- const void* sema = NULL;
- static const void* old_sema = NULL;
ut_ad(!srv_read_only_mode);
@@ -1383,31 +1373,6 @@ void srv_monitor_task(void*)
eviction policy. */
buf_LRU_stat_update();
- if (sync_array_print_long_waits(&waiter, &sema)
- && sema == old_sema && os_thread_eq(waiter, old_waiter)) {
-#if defined(WITH_WSREP) && defined(WITH_INNODB_DISALLOW_WRITES)
- if (UNIV_UNLIKELY(innodb_disallow_writes)) {
- fprintf(stderr,
- "WSREP: avoiding InnoDB self crash due to "
- "long semaphore wait of > %lu seconds\n"
- "Server is processing SST donor operation, "
- "fatal_cnt now: " ULINTPF,
- srv_fatal_semaphore_wait_threshold, fatal_cnt);
- return;
- }
-#endif /* WITH_WSREP */
- if (fatal_cnt++) {
- ib::fatal() << "Semaphore wait has lasted > "
- << srv_fatal_semaphore_wait_threshold
- << " seconds. We intentionally crash the"
- " server because it appears to be hung.";
- }
- } else {
- fatal_cnt = 0;
- old_waiter = waiter;
- old_sema = sema;
- }
-
srv_monitor();
}
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index fa9484d8545..b8a1a4e2cfc 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -100,7 +100,7 @@ Created 2/16/1996 Heikki Tuuri
#include "ut0crc32.h"
/** We are prepared for a situation that we have this many threads waiting for
-a semaphore inside InnoDB. srv_start() sets the value. */
+a transactional lock inside InnoDB. srv_start() sets the value. */
ulint srv_max_n_threads;
/** Log sequence number at shutdown */
@@ -1109,27 +1109,11 @@ dberr_t srv_start(bool create_new_db)
mysql_stage_register("innodb", srv_stages,
static_cast<int>(UT_ARR_SIZE(srv_stages)));
- /* Set the maximum number of threads which can wait for a semaphore
- inside InnoDB: this is the 'sync wait array' size */
-
- srv_max_n_threads = 1 /* io_ibuf_thread */
- + 1 /* io_log_thread */
- + 1 /* srv_print_monitor_task */
- + 1 /* srv_purge_coordinator_thread */
- + 1 /* buf_dump_thread */
- + 1 /* dict_stats_thread */
- + 1 /* fts_optimize_thread */
- + 1 /* trx_rollback_all_recovered */
- + 128 /* added as margin, for use of
- InnoDB Memcached etc. */
- + 1/* buf_flush_page_cleaner */
- + max_connections
- + srv_n_read_io_threads
- + srv_n_write_io_threads
- + srv_n_purge_threads
- /* FTS Parallel Sort */
- + fts_sort_pll_degree * FTS_NUM_AUX_INDEX
- * max_connections;
+ srv_max_n_threads =
+ 1 /* dict_stats_thread */
+ + 1 /* fts_optimize_thread */
+ + 128 /* safety margin */
+ + max_connections;
srv_boot();
diff --git a/storage/innobase/sync/sync0arr.cc b/storage/innobase/sync/sync0arr.cc
deleted file mode 100644
index c8c5e5280f2..00000000000
--- a/storage/innobase/sync/sync0arr.cc
+++ /dev/null
@@ -1,960 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2008, Google Inc.
-Copyright (c) 2013, 2020, MariaDB Corporation.
-
-Portions of this file contain modifications contributed and copyrighted by
-Google, Inc. Those modifications are gratefully acknowledged and are described
-briefly in the InnoDB documentation. The contributions by Google are
-incorporated with their permission, and subject to the conditions contained in
-the file COPYING.Google.
-
-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 sync/sync0arr.cc
-The wait array used in synchronization primitives
-
-Created 9/5/1995 Heikki Tuuri
-*******************************************************/
-
-#include "sync0arr.h"
-#include <mysqld_error.h>
-#include <mysql/plugin.h>
-#include <hash.h>
-#include <myisampack.h>
-#include <sql_acl.h>
-#include <mysys_err.h>
-#include <my_sys.h>
-#include "srv0srv.h"
-#include "srv0start.h"
-#include "i_s.h"
-#include <sql_plugin.h>
-#include <innodb_priv.h>
-
-#include "lock0lock.h"
-
-/*
- WAIT ARRAY
- ==========
-
-The wait array consists of cells each of which has an an event object created
-for it. The threads waiting for a mutex, for example, can reserve a cell
-in the array and suspend themselves to wait for the event to become signaled.
-When using the wait array, remember to make sure that some thread holding
-the synchronization object will eventually know that there is a waiter in
-the array and signal the object, to prevent infinite wait. Why we chose
-to implement a wait array? First, to make mutexes fast, we had to code
-our own implementation of them, which only in usually uncommon cases
-resorts to using slow operating system primitives. Then we had the choice of
-assigning a unique OS event for each mutex, which would be simpler, or
-using a global wait array. In some operating systems, the global wait
-array solution is more efficient and flexible, because we can do with
-a very small number of OS events, say 200. In NT 3.51, allocating events
-seems to be a quadratic algorithm, because 10 000 events are created fast,
-but 100 000 events takes a couple of minutes to create.
-
-As of 5.0.30 the above mentioned design is changed. Since now OS can handle
-millions of wait events efficiently, we no longer have this concept of each
-cell of wait array having one event. Instead, now the event that a thread
-wants to wait on is embedded in the wait object (mutex or rw_lock). We still
-keep the global wait array for the sake of diagnostics and also to avoid
-infinite wait The error_monitor thread scans the global wait array to signal
-any waiting threads who have missed the signal. */
-
-typedef TTASEventMutex<GenericPolicy> WaitMutex;
-
-/** A cell where an individual thread may wait suspended until a resource
-is released. The suspending is implemented using an operating system
-event semaphore. */
-
-struct sync_cell_t {
- WaitMutex* mutex; /*!< pointer to the object the
- thread is waiting for; if NULL
- the cell is free for use */
- const char* file; /*!< in debug version file where
- requested */
- ulint line; /*!< in debug version line where
- requested, or ULINT_UNDEFINED */
- os_thread_id_t thread_id; /*!< thread id of this waiting
- thread */
- bool waiting; /*!< TRUE if the thread has already
- called sync_array_event_wait
- on this cell */
- int64_t signal_count; /*!< We capture the signal_count
- of the mutex when we
- reset the event. This value is
- then passed on to os_event_wait
- and we wait only if the event
- has not been signalled in the
- period between the reset and
- wait call. */
- /** time(NULL) when the wait cell was reserved.
- FIXME: sync_array_print_long_waits_low() may display bogus
- warnings when the system time is adjusted to the past! */
- time_t reservation_time;
-};
-
-/* NOTE: It is allowed for a thread to wait for an event allocated for
-the array without owning the protecting mutex (depending on the case:
-OS or database mutex), but all changes (set or reset) to the state of
-the event must be made while owning the mutex. */
-
-/** Synchronization array */
-struct sync_array_t {
-
- /** Constructor
- Creates a synchronization wait array. It is protected by a mutex
- which is automatically reserved when the functions operating on it
- are called.
- @param[in] num_cells Number of cells to create */
- sync_array_t(ulint num_cells)
- UNIV_NOTHROW;
-
- /** Destructor */
- ~sync_array_t()
- UNIV_NOTHROW;
-
- ulint n_reserved; /*!< number of currently reserved
- cells in the wait array */
- ulint n_cells; /*!< number of cells in the
- wait array */
- sync_cell_t* array; /*!< pointer to wait array */
- SysMutex mutex; /*!< System mutex protecting the
- data structure. As this data
- structure is used in constructing
- the database mutex, to prevent
- infinite recursion in implementation,
- we fall back to an OS mutex. */
- ulint res_count; /*!< count of cell reservations
- since creation of the array */
- ulint next_free_slot; /*!< the next free cell in the array */
- ulint first_free_slot;/*!< the last slot that was freed */
-};
-
-/** User configured sync array size */
-ulong srv_sync_array_size = 1;
-
-/** Locally stored copy of srv_sync_array_size */
-ulint sync_array_size;
-
-/** The global array of wait cells for implementation of the database's own
-mutexes and read-write locks */
-sync_array_t** sync_wait_array;
-
-/** count of how many times an object has been signalled */
-ulint sg_count;
-
-#define sync_array_exit(a) mutex_exit(&(a)->mutex)
-#define sync_array_enter(a) mutex_enter(&(a)->mutex)
-
-#ifdef UNIV_DEBUG
-/******************************************************************//**
-This function is called only in the debug version. Detects a deadlock
-of one or more threads because of waits of semaphores.
-@return TRUE if deadlock detected */
-static
-bool
-sync_array_detect_deadlock(
-/*=======================*/
- sync_array_t* arr, /*!< in: wait array; NOTE! the caller must
- own the mutex to array */
- sync_cell_t* start, /*!< in: cell where recursive search started */
- sync_cell_t* cell, /*!< in: cell to search */
- ulint depth); /*!< in: recursion depth */
-#endif /* UNIV_DEBUG */
-
-/** Constructor
-Creates a synchronization wait array. It is protected by a mutex
-which is automatically reserved when the functions operating on it
-are called.
-@param[in] num_cells Number of cells to create */
-sync_array_t::sync_array_t(ulint num_cells)
- UNIV_NOTHROW
- :
- n_reserved(),
- n_cells(num_cells),
- array(UT_NEW_ARRAY_NOKEY(sync_cell_t, num_cells)),
- mutex(),
- res_count(),
- next_free_slot(),
- first_free_slot(ULINT_UNDEFINED)
-{
- ut_a(num_cells > 0);
-
- memset(array, 0x0, sizeof(sync_cell_t) * n_cells);
-
- /* Then create the mutex to protect the wait array */
- mutex_create(LATCH_ID_SYNC_ARRAY_MUTEX, &mutex);
-}
-
-/** Validate the integrity of the wait array. Check
-that the number of reserved cells equals the count variable.
-@param[in,out] arr sync wait array */
-static
-void
-sync_array_validate(sync_array_t* arr)
-{
- ulint i;
- ulint count = 0;
-
- sync_array_enter(arr);
-
- for (i = 0; i < arr->n_cells; i++) {
- sync_cell_t* cell;
-
- cell = sync_array_get_nth_cell(arr, i);
-
- if (cell->mutex) {
- count++;
- }
- }
-
- ut_a(count == arr->n_reserved);
-
- sync_array_exit(arr);
-}
-
-/** Destructor */
-sync_array_t::~sync_array_t()
- UNIV_NOTHROW
-{
- ut_a(n_reserved == 0);
-
- sync_array_validate(this);
-
- /* Release the mutex protecting the wait array */
-
- mutex_free(&mutex);
-
- UT_DELETE_ARRAY(array);
-}
-
-/*****************************************************************//**
-Gets the nth cell in array.
-@return cell */
-UNIV_INTERN
-sync_cell_t*
-sync_array_get_nth_cell(
-/*====================*/
- sync_array_t* arr, /*!< in: sync array */
- ulint n) /*!< in: index */
-{
- ut_a(n < arr->n_cells);
-
- return(arr->array + n);
-}
-
-/******************************************************************//**
-Frees the resources in a wait array. */
-static
-void
-sync_array_free(
-/*============*/
- sync_array_t* arr) /*!< in, own: sync wait array */
-{
- UT_DELETE(arr);
-}
-
-/******************************************************************//**
-Reserves a wait array cell for waiting for an object.
-The event of the cell is reset to nonsignalled state.
-@return sync cell to wait on */
-sync_cell_t*
-sync_array_reserve_cell(
- sync_array_t* arr, /*!< in: wait array */
- void* object, /*!< in: pointer to the object to wait for */
- const char* file, /*!< in: file where requested */
- unsigned line) /*!< in: line where requested */
-{
- sync_cell_t* cell;
-
- sync_array_enter(arr);
-
- if (arr->first_free_slot != ULINT_UNDEFINED) {
- /* Try and find a slot in the free list */
- ut_ad(arr->first_free_slot < arr->next_free_slot);
- cell = sync_array_get_nth_cell(arr, arr->first_free_slot);
- arr->first_free_slot = cell->line;
- } else if (arr->next_free_slot < arr->n_cells) {
- /* Try and find a slot after the currently allocated slots */
- cell = sync_array_get_nth_cell(arr, arr->next_free_slot);
- ++arr->next_free_slot;
- } else {
- sync_array_exit(arr);
-
- // We should return NULL and if there is more than
- // one sync array, try another sync array instance.
- return(NULL);
- }
-
- ++arr->res_count;
-
- ut_ad(arr->n_reserved < arr->n_cells);
- ut_ad(arr->next_free_slot <= arr->n_cells);
-
- ++arr->n_reserved;
-
- /* Reserve the cell. */
- ut_ad(!cell->mutex);
-
- cell->mutex = static_cast<WaitMutex*>(object);
-
- cell->waiting = false;
-
- cell->file = file;
- cell->line = line;
-
- sync_array_exit(arr);
-
- cell->thread_id = os_thread_get_curr_id();
-
- cell->reservation_time = time(NULL);
-
- /* Make sure the event is reset and also store the value of
- signal_count at which the event was reset. */
- cell->signal_count = os_event_reset(cell->mutex->event());
-
- return(cell);
-}
-
-/******************************************************************//**
-Frees the cell. NOTE! sync_array_wait_event frees the cell
-automatically! */
-void
-sync_array_free_cell(
-/*=================*/
- sync_array_t* arr, /*!< in: wait array */
- sync_cell_t*& cell) /*!< in/out: the cell in the array */
-{
- sync_array_enter(arr);
-
- ut_a(cell->mutex);
-
- cell->waiting = false;
- cell->signal_count = 0;
- cell->mutex = NULL;
-
- /* Setup the list of free slots in the array */
- cell->line = arr->first_free_slot;
-
- arr->first_free_slot = cell - arr->array;
-
- ut_a(arr->n_reserved > 0);
- arr->n_reserved--;
-
- if (arr->next_free_slot > arr->n_cells / 2 && arr->n_reserved == 0) {
-#ifdef UNIV_DEBUG
- for (ulint i = 0; i < arr->next_free_slot; ++i) {
- cell = sync_array_get_nth_cell(arr, i);
-
- ut_ad(!cell->waiting);
- ut_ad(!cell->mutex);
- ut_ad(cell->signal_count == 0);
- }
-#endif /* UNIV_DEBUG */
- arr->next_free_slot = 0;
- arr->first_free_slot = ULINT_UNDEFINED;
- }
- sync_array_exit(arr);
-
- cell = 0;
-}
-
-/******************************************************************//**
-This function should be called when a thread starts to wait on
-a wait array cell. In the debug version this function checks
-if the wait for a semaphore will result in a deadlock, in which
-case prints info and asserts. */
-void
-sync_array_wait_event(
-/*==================*/
- sync_array_t* arr, /*!< in: wait array */
- sync_cell_t*& cell) /*!< in: index of the reserved cell */
-{
- sync_array_enter(arr);
-
- ut_ad(!cell->waiting);
- ut_ad(cell->mutex);
- ut_ad(os_thread_get_curr_id() == cell->thread_id);
-
- cell->waiting = true;
-
-#ifdef UNIV_DEBUG
- if (sync_array_detect_deadlock(arr, cell, cell, 0)) {
-
- ib::fatal() << "########################################"
- " Deadlock Detected!";
- }
-#endif /* UNIV_DEBUG */
- sync_array_exit(arr);
-
- tpool::tpool_wait_begin();
-
- os_event_wait_low(cell->mutex->event(), cell->signal_count);
-
- tpool::tpool_wait_end();
-
- sync_array_free_cell(arr, cell);
-
- cell = 0;
-}
-
-/******************************************************************//**
-Reports info of a wait array cell. */
-static
-void
-sync_array_cell_print(
-/*==================*/
- FILE* file, /*!< in: file where to print */
- sync_cell_t* cell) /*!< in: sync cell */
-{
- fprintf(file,
- "--Thread " ULINTPF " has waited at %s line " ULINTPF
- " for %.2f seconds the semaphore:\n",
- ulint(cell->thread_id),
- innobase_basename(cell->file), cell->line,
- difftime(time(NULL), cell->reservation_time));
-
- WaitMutex* mutex = cell->mutex;
- const WaitMutex::MutexPolicy& policy = mutex->policy();
-#ifdef UNIV_DEBUG
- const char* name = policy.context.get_enter_filename();
- if (name == NULL) {
- /* The mutex might have been released. */
- name = "NULL";
- }
-#endif /* UNIV_DEBUG */
-
- fprintf(file,
- "Mutex at %p, %s, lock var %x\n"
-#ifdef UNIV_DEBUG
- "Last time reserved in file %s line %u"
-#endif /* UNIV_DEBUG */
- "\n",
- (void*) mutex,
- policy.to_string().c_str(),
- mutex->state()
-#ifdef UNIV_DEBUG
- ,name, policy.context.get_enter_line()
-#endif /* UNIV_DEBUG */
- );
-
- if (!cell->waiting) {
- fputs("wait has ended\n", file);
- }
-}
-
-#ifdef UNIV_DEBUG
-/******************************************************************//**
-Looks for a cell with the given thread id.
-@return pointer to cell or NULL if not found */
-static
-sync_cell_t*
-sync_array_find_thread(
-/*===================*/
- sync_array_t* arr, /*!< in: wait array */
- os_thread_id_t thread) /*!< in: thread id */
-{
- ulint i;
-
- for (i = 0; i < arr->n_cells; i++) {
- sync_cell_t* cell;
-
- cell = sync_array_get_nth_cell(arr, i);
-
- if (cell->mutex
- && os_thread_eq(cell->thread_id, thread)) {
-
- return(cell); /* Found */
- }
- }
-
- return(NULL); /* Not found */
-}
-
-/******************************************************************//**
-Recursion step for deadlock detection.
-@return TRUE if deadlock detected */
-static
-ibool
-sync_array_deadlock_step(
-/*=====================*/
- sync_array_t* arr, /*!< in: wait array; NOTE! the caller must
- own the mutex to array */
- sync_cell_t* start, /*!< in: cell where recursive search
- started */
- os_thread_id_t thread, /*!< in: thread to look at */
- ulint pass, /*!< in: pass value */
- ulint depth) /*!< in: recursion depth */
-{
- sync_cell_t* new_cell;
-
- if (pass != 0) {
- /* If pass != 0, then we do not know which threads are
- responsible of releasing the lock, and no deadlock can
- be detected. */
-
- return(FALSE);
- }
-
- new_cell = sync_array_find_thread(arr, thread);
-
- if (new_cell == start) {
- /* Deadlock */
- fputs("########################################\n"
- "DEADLOCK of threads detected!\n", stderr);
-
- return(TRUE);
-
- } else if (new_cell) {
- return(sync_array_detect_deadlock(
- arr, start, new_cell, depth + 1));
- }
- return(FALSE);
-}
-
-/******************************************************************//**
-This function is called only in the debug version. Detects a deadlock
-of one or more threads because of waits of semaphores.
-@return TRUE if deadlock detected */
-static
-bool
-sync_array_detect_deadlock(
-/*=======================*/
- sync_array_t* arr, /*!< in: wait array; NOTE! the caller must
- own the mutex to array */
- sync_cell_t* start, /*!< in: cell where recursive search started */
- sync_cell_t* cell, /*!< in: cell to search */
- ulint depth) /*!< in: recursion depth */
-{
- os_thread_id_t thread;
- ibool ret;
-
- ut_a(arr);
- ut_a(start);
- ut_a(cell);
- ut_ad(cell->mutex);
- ut_ad(os_thread_get_curr_id() == start->thread_id);
- ut_ad(depth < 100);
-
- depth++;
-
- if (!cell->waiting) {
- /* No deadlock here */
- return(false);
- }
-
- WaitMutex* mutex = cell->mutex;
- const WaitMutex::MutexPolicy& policy = mutex->policy();
-
- if (mutex->state() != MUTEX_STATE_UNLOCKED) {
- thread = policy.context.get_thread_id();
-
- /* Note that mutex->thread_id above may be
- also OS_THREAD_ID_UNDEFINED, because the
- thread which held the mutex maybe has not
- yet updated the value, or it has already
- released the mutex: in this case no deadlock
- can occur, as the wait array cannot contain
- a thread with ID_UNDEFINED value. */
- ret = sync_array_deadlock_step(
- arr, start, thread, 0, depth);
-
- if (ret) {
- const char* name;
-
- name = policy.context.get_enter_filename();
-
- if (name == NULL) {
- /* The mutex might have been
- released. */
- name = "NULL";
- }
-
- ib::info()
- << "Mutex " << mutex << " owned by"
- " thread " << thread
- << " file " << name << " line "
- << policy.context.get_enter_line();
-
- sync_array_cell_print(stderr, cell);
-
- return(true);
- }
- }
-
- /* No deadlock */
- return(false);
-}
-#endif /* UNIV_DEBUG */
-
-/**********************************************************************//**
-Prints warnings of long semaphore waits to stderr.
-@return TRUE if fatal semaphore wait threshold was exceeded */
-static
-bool
-sync_array_print_long_waits_low(
-/*============================*/
- sync_array_t* arr, /*!< in: sync array instance */
- os_thread_id_t* waiter, /*!< out: longest waiting thread */
- const void** sema, /*!< out: longest-waited-for semaphore */
- ibool* noticed)/*!< out: TRUE if long wait noticed */
-{
- double fatal_timeout = static_cast<double>(
- srv_fatal_semaphore_wait_threshold);
- ibool fatal = FALSE;
- double longest_diff = 0;
- ulint i;
-
- /* For huge tables, skip the check during CHECK TABLE etc... */
- if (btr_validate_index_running) {
- return(false);
- }
-
-#if defined HAVE_valgrind && !__has_feature(memory_sanitizer)
- /* Increase the timeouts if running under valgrind because it executes
- extremely slowly. HAVE_valgrind does not necessary mean that
- we are running under valgrind but we have no better way to tell.
- See Bug#58432 innodb.innodb_bug56143 fails under valgrind
- for an example */
-# define SYNC_ARRAY_TIMEOUT 2400
- fatal_timeout *= 10;
-#else
-# define SYNC_ARRAY_TIMEOUT 240
-#endif
- const time_t now = time(NULL);
-
- for (ulint i = 0; i < arr->n_cells; i++) {
- sync_cell_t* cell = sync_array_get_nth_cell(arr, i);
-
- if (!cell->mutex || !cell->waiting) {
-
- continue;
- }
-
- double diff = difftime(now, cell->reservation_time);
-
- if (diff > SYNC_ARRAY_TIMEOUT) {
- ib::warn() << "A long semaphore wait:";
- sync_array_cell_print(stderr, cell);
- *noticed = TRUE;
- }
-
- if (diff > fatal_timeout) {
- fatal = TRUE;
- }
-
- if (diff > longest_diff) {
- longest_diff = diff;
- *sema = cell->mutex;
- *waiter = cell->thread_id;
- }
- }
-
- /* We found a long semaphore wait, print all threads that are
- waiting for a semaphore. */
- if (*noticed) {
- for (i = 0; i < arr->n_cells; i++) {
- sync_cell_t* cell = sync_array_get_nth_cell(arr, i);
-
- if (!cell->mutex || !cell->waiting) {
- continue;
- }
-
- ib::info() << "A semaphore wait:";
- sync_array_cell_print(stderr, cell);
- }
- }
-
-#undef SYNC_ARRAY_TIMEOUT
-
- return(fatal);
-}
-
-/**********************************************************************//**
-Prints warnings of long semaphore waits to stderr.
-@return TRUE if fatal semaphore wait threshold was exceeded */
-ibool
-sync_array_print_long_waits(
-/*========================*/
- os_thread_id_t* waiter, /*!< out: longest waiting thread */
- const void** sema) /*!< out: longest-waited-for semaphore */
-{
- ulint i;
- ibool fatal = FALSE;
- ibool noticed = FALSE;
-
- for (i = 0; i < sync_array_size; ++i) {
-
- sync_array_t* arr = sync_wait_array[i];
-
- sync_array_enter(arr);
-
- if (sync_array_print_long_waits_low(
- arr, waiter, sema, &noticed)) {
-
- fatal = TRUE;
- }
-
- sync_array_exit(arr);
- }
-
- if (noticed) {
- /* If some crucial semaphore is reserved, then also the InnoDB
- Monitor can hang, and we do not get diagnostics. Since in
- many cases an InnoDB hang is caused by a pwrite() or a pread()
- call hanging inside the operating system, let us print right
- now the values of pending calls of these. */
-
- fprintf(stderr,
- "InnoDB: Pending reads " UINT64PF
- ", writes " UINT64PF "\n",
- MONITOR_VALUE(MONITOR_OS_PENDING_READS),
- MONITOR_VALUE(MONITOR_OS_PENDING_WRITES));
-
- lock_wait_timeout_task(nullptr);
- }
-
- return(fatal);
-}
-
-/**********************************************************************//**
-Prints info of the wait array. */
-static
-void
-sync_array_print_info_low(
-/*======================*/
- FILE* file, /*!< in: file where to print */
- sync_array_t* arr) /*!< in: wait array */
-{
- ulint i;
- ulint count = 0;
-
- fprintf(file,
- "OS WAIT ARRAY INFO: reservation count " ULINTPF "\n",
- arr->res_count);
-
- for (i = 0; count < arr->n_reserved; ++i) {
- sync_cell_t* cell = sync_array_get_nth_cell(arr, i);
-
- if (cell->mutex) {
- count++;
- sync_array_cell_print(file, cell);
- }
- }
-}
-
-/**********************************************************************//**
-Prints info of the wait array. */
-static
-void
-sync_array_print_info(
-/*==================*/
- FILE* file, /*!< in: file where to print */
- sync_array_t* arr) /*!< in: wait array */
-{
- sync_array_enter(arr);
-
- sync_array_print_info_low(file, arr);
-
- sync_array_exit(arr);
-}
-
-/** Create the primary system wait arrays */
-void sync_array_init()
-{
- ut_a(sync_wait_array == NULL);
- ut_a(srv_sync_array_size > 0);
- ut_a(srv_max_n_threads > 0);
-
- sync_array_size = srv_sync_array_size;
-
- sync_wait_array = UT_NEW_ARRAY_NOKEY(sync_array_t*, sync_array_size);
-
- ulint n_slots = 1 + (srv_max_n_threads - 1) / sync_array_size;
-
- for (ulint i = 0; i < sync_array_size; ++i) {
-
- sync_wait_array[i] = UT_NEW_NOKEY(sync_array_t(n_slots));
- }
-}
-
-/** Destroy the sync array wait sub-system. */
-void sync_array_close()
-{
- for (ulint i = 0; i < sync_array_size; ++i) {
- sync_array_free(sync_wait_array[i]);
- }
-
- UT_DELETE_ARRAY(sync_wait_array);
- sync_wait_array = NULL;
-}
-
-/**********************************************************************//**
-Print info about the sync array(s). */
-void
-sync_array_print(
-/*=============*/
- FILE* file) /*!< in/out: Print to this stream */
-{
- for (ulint i = 0; i < sync_array_size; ++i) {
- sync_array_print_info(file, sync_wait_array[i]);
- }
-
- fprintf(file,
- "OS WAIT ARRAY INFO: signal count " ULINTPF "\n", sg_count);
-
-}
-
-/**********************************************************************//**
-Prints info of the wait array without using any mutexes/semaphores. */
-UNIV_INTERN
-void
-sync_array_print_innodb(void)
-/*=========================*/
-{
- ulint i;
- sync_array_t* arr = sync_array_get();
-
- fputs("InnoDB: Semaphore wait debug output started for InnoDB:\n", stderr);
-
- for (i = 0; i < arr->n_cells; i++) {
- sync_cell_t* cell = sync_array_get_nth_cell(arr, i);
-
- if (!cell->mutex || !cell->waiting) {
- continue;
- }
-
- fputs("InnoDB: Warning: semaphore wait:\n",
- stderr);
- sync_array_cell_print(stderr, cell);
- }
-
- fputs("InnoDB: Semaphore wait debug output ended:\n", stderr);
-
-}
-
-/**********************************************************************//**
-Get number of items on sync array. */
-UNIV_INTERN
-ulint
-sync_arr_get_n_items(void)
-/*======================*/
-{
- sync_array_t* sync_arr = sync_array_get();
- return (ulint) sync_arr->n_cells;
-}
-
-/******************************************************************//**
-Get specified item from sync array if it is reserved. Set given
-pointer to array item if it is reserved.
-@return true if item is reserved, false othervise */
-UNIV_INTERN
-ibool
-sync_arr_get_item(
-/*==============*/
- ulint i, /*!< in: requested item */
- sync_cell_t **cell) /*!< out: cell contents if item
- reserved */
-{
- sync_array_t* sync_arr;
- sync_cell_t* wait_cell;
- void* wait_object;
- ibool found = FALSE;
-
- sync_arr = sync_array_get();
- wait_cell = sync_array_get_nth_cell(sync_arr, i);
-
- if (wait_cell) {
- wait_object = wait_cell->mutex;
-
- if(wait_object != NULL && wait_cell->waiting) {
- found = TRUE;
- *cell = wait_cell;
- }
- }
-
- return found;
-}
-
-/*******************************************************************//**
-Function to populate INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS table.
-Loop through each item on sync array, and extract the column
-information and fill the INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS table.
-@return 0 on success */
-UNIV_INTERN
-int
-sync_arr_fill_sys_semphore_waits_table(
-/*===================================*/
- THD* thd, /*!< in: thread */
- TABLE_LIST* tables, /*!< in/out: tables to fill */
- Item* ) /*!< in: condition (not used) */
-{
- Field** fields;
- ulint n_items;
-
- DBUG_ENTER("i_s_sys_semaphore_waits_fill_table");
- RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
-
- /* deny access to user without PROCESS_ACL privilege */
- if (check_global_access(thd, PROCESS_ACL)) {
- DBUG_RETURN(0);
- }
-
- fields = tables->table->field;
- n_items = sync_arr_get_n_items();
-
- for(ulint i=0; i < n_items;i++) {
- sync_cell_t *cell=NULL;
- if (sync_arr_get_item(i, &cell)) {
- /* JAN: FIXME
- OK(fields[SYS_SEMAPHORE_WAITS_THREAD_ID]->store(,
- ulint(cell->thread), true));
- */
- OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_FILE], innobase_basename(cell->file)));
- OK(fields[SYS_SEMAPHORE_WAITS_LINE]->store(cell->line, true));
- fields[SYS_SEMAPHORE_WAITS_LINE]->set_notnull();
- OK(fields[SYS_SEMAPHORE_WAITS_WAIT_TIME]->store(
- difftime(time(NULL),
- cell->reservation_time)));
-
- if (WaitMutex* mutex = cell->mutex) {
- // JAN: FIXME
- // OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_OBJECT_NAME], mutex->cmutex_name));
- OK(fields[SYS_SEMAPHORE_WAITS_WAIT_OBJECT]->store((longlong)mutex, true));
- OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_WAIT_TYPE], "MUTEX"));
- //OK(fields[SYS_SEMAPHORE_WAITS_HOLDER_THREAD_ID]->store(mutex->thread_id, true));
- //OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_HOLDER_FILE], innobase_basename(mutex->file_name)));
- //OK(fields[SYS_SEMAPHORE_WAITS_HOLDER_LINE]->store(mutex->line, true));
- //fields[SYS_SEMAPHORE_WAITS_HOLDER_LINE]->set_notnull();
- //OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_CREATED_FILE], innobase_basename(mutex->cfile_name)));
- //OK(fields[SYS_SEMAPHORE_WAITS_CREATED_LINE]->store(mutex->cline, true));
- //fields[SYS_SEMAPHORE_WAITS_CREATED_LINE]->set_notnull();
- //OK(fields[SYS_SEMAPHORE_WAITS_WAITERS_FLAG]->store(mutex->waiters, true));
- //OK(fields[SYS_SEMAPHORE_WAITS_LOCK_WORD]->store(mutex->lock_word, true));
- //OK(field_store_string(fields[SYS_SEMAPHORE_WAITS_LAST_WRITER_FILE], innobase_basename(mutex->file_name)));
- //OK(fields[SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE]->store(mutex->line, true));
- //fields[SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE]->set_notnull();
- //OK(fields[SYS_SEMAPHORE_WAITS_OS_WAIT_COUNT]->store(mutex->count_os_wait, true));
- }
-
- OK(schema_table_store_record(thd, tables->table));
- }
- }
-
- DBUG_RETURN(0);
-}
diff --git a/storage/innobase/sync/sync0debug.cc b/storage/innobase/sync/sync0debug.cc
index 6424db6dc61..cdef44a6652 100644
--- a/storage/innobase/sync/sync0debug.cc
+++ b/storage/innobase/sync/sync0debug.cc
@@ -388,7 +388,6 @@ LatchDebug::LatchDebug()
m_mutex.init();
LEVEL_MAP_INSERT(SYNC_UNKNOWN);
- LEVEL_MAP_INSERT(SYNC_MUTEX);
LEVEL_MAP_INSERT(RW_LOCK_SX);
LEVEL_MAP_INSERT(RW_LOCK_X_WAIT);
LEVEL_MAP_INSERT(RW_LOCK_S);
@@ -668,7 +667,6 @@ LatchDebug::check_order(
basic_check(latches, level, SYNC_DICT);
break;
- case SYNC_MUTEX:
case SYNC_UNKNOWN:
case RW_LOCK_X:
case RW_LOCK_X_WAIT:
@@ -1030,8 +1028,6 @@ sync_check_init()
sync_latch_meta_init();
- sync_array_init();
-
ut_d(sync_check_enable());
}
@@ -1040,8 +1036,5 @@ void
sync_check_close()
{
ut_d(LatchDebug::shutdown());
-
- sync_array_close();
-
sync_latch_meta_destroy();
}