Commit 8f3b5ebd authored by Vadim Tkachenko's avatar Vadim Tkachenko

Sync with patches commit rev 8

parent bf05180b
...@@ -131,7 +131,7 @@ noinst_HEADERS= include/btr0btr.h include/btr0btr.ic \ ...@@ -131,7 +131,7 @@ noinst_HEADERS= include/btr0btr.h include/btr0btr.ic \
include/ut0list.ic include/ut0wqueue.h \ include/ut0list.ic include/ut0wqueue.h \
include/ha_prototypes.h handler/ha_innodb.h \ include/ha_prototypes.h handler/ha_innodb.h \
include/handler0alter.h \ include/handler0alter.h \
handler/i_s.h handler/i_s.h handler/innodb_patch_info.h
EXTRA_LIBRARIES= libinnobase.a EXTRA_LIBRARIES= libinnobase.a
noinst_LIBRARIES= @plugin_innobase_static_target@ noinst_LIBRARIES= @plugin_innobase_static_target@
......
...@@ -651,7 +651,7 @@ noinst_HEADERS = include/btr0btr.h include/btr0btr.ic \ ...@@ -651,7 +651,7 @@ noinst_HEADERS = include/btr0btr.h include/btr0btr.ic \
include/ut0list.ic include/ut0wqueue.h \ include/ut0list.ic include/ut0wqueue.h \
include/ha_prototypes.h handler/ha_innodb.h \ include/ha_prototypes.h handler/ha_innodb.h \
include/handler0alter.h \ include/handler0alter.h \
handler/i_s.h handler/i_s.h handler/innodb_patch_info.h
EXTRA_LIBRARIES = libinnobase.a EXTRA_LIBRARIES = libinnobase.a
noinst_LIBRARIES = @plugin_innobase_static_target@ noinst_LIBRARIES = @plugin_innobase_static_target@
......
...@@ -3595,13 +3595,15 @@ buf_print_io( ...@@ -3595,13 +3595,15 @@ buf_print_io(
buf_pool_mutex_enter(); buf_pool_mutex_enter();
fprintf(file, fprintf(file,
"Buffer pool size %lu\n" "Buffer pool size %lu\n"
"Free buffers %lu\n" "Buffer pool size, bytes %lu\n"
"Database pages %lu\n" "Free buffers %lu\n"
"Modified db pages %lu\n" "Database pages %lu\n"
"Modified db pages %lu\n"
"Pending reads %lu\n" "Pending reads %lu\n"
"Pending writes: LRU %lu, flush list %lu, single page %lu\n", "Pending writes: LRU %lu, flush list %lu, single page %lu\n",
(ulong) size, (ulong) size,
(ulong) size * UNIV_PAGE_SIZE,
(ulong) UT_LIST_GET_LEN(buf_pool->free), (ulong) UT_LIST_GET_LEN(buf_pool->free),
(ulong) UT_LIST_GET_LEN(buf_pool->LRU), (ulong) UT_LIST_GET_LEN(buf_pool->LRU),
(ulong) UT_LIST_GET_LEN(buf_pool->flush_list), (ulong) UT_LIST_GET_LEN(buf_pool->flush_list),
......
...@@ -4816,3 +4816,30 @@ fil_page_get_type( ...@@ -4816,3 +4816,30 @@ fil_page_get_type(
return(mach_read_from_2(page + FIL_PAGE_TYPE)); return(mach_read_from_2(page + FIL_PAGE_TYPE));
} }
/*************************************************************************
Return local hash table informations. */
ulint
fil_system_hash_cells(void)
/*=======================*/
{
if (fil_system) {
return (fil_system->spaces->n_cells
+ fil_system->name_hash->n_cells);
} else {
return 0;
}
}
ulint
fil_system_hash_nodes(void)
/*=======================*/
{
if (fil_system) {
return (UT_LIST_GET_LEN(fil_system->space_list)
* (sizeof(fil_space_t) + MEM_BLOCK_HEADER_SIZE));
} else {
return 0;
}
}
...@@ -9409,6 +9409,16 @@ static MYSQL_SYSVAR_BOOL(locks_unsafe_for_binlog, innobase_locks_unsafe_for_binl ...@@ -9409,6 +9409,16 @@ static MYSQL_SYSVAR_BOOL(locks_unsafe_for_binlog, innobase_locks_unsafe_for_binl
"Force InnoDB to not use next-key locking, to use only row-level locking.", "Force InnoDB to not use next-key locking, to use only row-level locking.",
NULL, NULL, FALSE); NULL, NULL, FALSE);
static MYSQL_SYSVAR_ULONG(show_verbose_locks, srv_show_verbose_locks,
PLUGIN_VAR_OPCMDARG,
"Whether to show records locked in SHOW INNODB STATUS.",
NULL, NULL, 0, 0, 1, 0);
static MYSQL_SYSVAR_ULONG(show_locks_held, srv_show_locks_held,
PLUGIN_VAR_RQCMDARG,
"Number of locks held to print for each InnoDB transaction in SHOW INNODB STATUS.",
NULL, NULL, 10, 0, 1000, 0);
#ifdef UNIV_LOG_ARCHIVE #ifdef UNIV_LOG_ARCHIVE
static MYSQL_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir, static MYSQL_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
...@@ -9559,7 +9569,7 @@ static MYSQL_SYSVAR_LONG(autoinc_lock_mode, innobase_autoinc_lock_mode, ...@@ -9559,7 +9569,7 @@ static MYSQL_SYSVAR_LONG(autoinc_lock_mode, innobase_autoinc_lock_mode,
static MYSQL_SYSVAR_STR(version, innodb_version_str, static MYSQL_SYSVAR_STR(version, innodb_version_str,
PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY, PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
"InnoDB version", NULL, NULL, INNODB_VERSION_STR); "Percona-InnoDB-plugin version", NULL, NULL, INNODB_VERSION_STR);
static MYSQL_SYSVAR_ULONG(io_capacity, srv_io_capacity, static MYSQL_SYSVAR_ULONG(io_capacity, srv_io_capacity,
PLUGIN_VAR_RQCMDARG, PLUGIN_VAR_RQCMDARG,
...@@ -9573,7 +9583,7 @@ static MYSQL_SYSVAR_ULONG(read_ahead, srv_read_ahead, ...@@ -9573,7 +9583,7 @@ static MYSQL_SYSVAR_ULONG(read_ahead, srv_read_ahead,
static MYSQL_SYSVAR_ULONG(adaptive_checkpoint, srv_adaptive_checkpoint, static MYSQL_SYSVAR_ULONG(adaptive_checkpoint, srv_adaptive_checkpoint,
PLUGIN_VAR_RQCMDARG, PLUGIN_VAR_RQCMDARG,
"Enable/Diasable flushing along modified age 0:disable 1:enable", "Enable/Disable flushing along modified age 0:disable 1:enable",
NULL, NULL, 0, 0, 1, 0); NULL, NULL, 0, 0, 1, 0);
static MYSQL_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads, static MYSQL_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads,
...@@ -9631,6 +9641,8 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { ...@@ -9631,6 +9641,8 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(thread_concurrency), MYSQL_SYSVAR(thread_concurrency),
MYSQL_SYSVAR(thread_sleep_delay), MYSQL_SYSVAR(thread_sleep_delay),
MYSQL_SYSVAR(autoinc_lock_mode), MYSQL_SYSVAR(autoinc_lock_mode),
MYSQL_SYSVAR(show_verbose_locks),
MYSQL_SYSVAR(show_locks_held),
MYSQL_SYSVAR(version), MYSQL_SYSVAR(version),
MYSQL_SYSVAR(io_capacity), MYSQL_SYSVAR(io_capacity),
MYSQL_SYSVAR(read_ahead), MYSQL_SYSVAR(read_ahead),
...@@ -9823,7 +9835,8 @@ i_s_innodb_lock_waits, ...@@ -9823,7 +9835,8 @@ i_s_innodb_lock_waits,
i_s_innodb_cmp, i_s_innodb_cmp,
i_s_innodb_cmp_reset, i_s_innodb_cmp_reset,
i_s_innodb_cmpmem, i_s_innodb_cmpmem,
i_s_innodb_cmpmem_reset i_s_innodb_cmpmem_reset,
i_s_innodb_patches
mysql_declare_plugin_end; mysql_declare_plugin_end;
#ifdef UNIV_COMPILE_TEST_FUNCS #ifdef UNIV_COMPILE_TEST_FUNCS
......
...@@ -15,6 +15,7 @@ Created July 18, 2007 Vasil Dimov ...@@ -15,6 +15,7 @@ Created July 18, 2007 Vasil Dimov
#include <mysys_err.h> #include <mysys_err.h>
#include <my_sys.h> #include <my_sys.h>
#include "i_s.h" #include "i_s.h"
#include "innodb_patch_info.h"
#include <mysql/plugin.h> #include <mysql/plugin.h>
extern "C" { extern "C" {
...@@ -199,6 +200,188 @@ field_store_ulint( ...@@ -199,6 +200,188 @@ field_store_ulint(
return(ret); return(ret);
} }
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_patches */
static ST_FIELD_INFO innodb_patches_fields_info[] =
{
#define IDX_PATCH_NAME 0
{STRUCT_FLD(field_name, "name"),
STRUCT_FLD(field_length, 255),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_PATCH_DESCR 1
{STRUCT_FLD(field_name, "description"),
STRUCT_FLD(field_length, 255),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_PATCH_VER 2
{STRUCT_FLD(field_name, "version"),
STRUCT_FLD(field_length, 10),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_PATCH_AUTHOR 3
{STRUCT_FLD(field_name, "author"),
STRUCT_FLD(field_length, 50),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_PATCH_LICENCE 4
{STRUCT_FLD(field_name, "licence"),
STRUCT_FLD(field_length, 50),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_PATCH_COMMENT 5
{STRUCT_FLD(field_name, "comment"),
STRUCT_FLD(field_length, 100),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
END_OF_ST_FIELD_INFO
};
static struct st_mysql_information_schema i_s_info =
{
MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION
};
/***********************************************************************
Fill the dynamic table information_schema.innodb_patches */
static
int
innodb_patches_fill(
/*=============*/
/* out: 0 on success, 1 on failure */
THD* thd, /* in: thread */
TABLE_LIST* tables, /* in/out: tables to fill */
COND* cond) /* in: condition (ignored) */
{
TABLE* table = (TABLE *) tables->table;
int status = 0;
int i;
Field** fields;
DBUG_ENTER("innodb_patches_fill");
fields = table->field;
/* deny access to non-superusers */
if (check_global_access(thd, PROCESS_ACL)) {
DBUG_RETURN(0);
}
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
for (i = 0; innodb_patches[i].file; i++) {
field_store_string(fields[0],innodb_patches[i].file);
field_store_string(fields[1],innodb_patches[i].name);
field_store_string(fields[2],innodb_patches[i].version);
field_store_string(fields[3],innodb_patches[i].author);
field_store_string(fields[4],innodb_patches[i].license);
field_store_string(fields[5],innodb_patches[i].comment);
if (schema_table_store_record(thd, table)) {
status = 1;
break;
}
}
DBUG_RETURN(status);
}
/***********************************************************************
Bind the dynamic table information_schema.innodb_patches. */
static
int
innodb_patches_init(
/*=========*/
/* out: 0 on success */
void* p) /* in/out: table schema object */
{
DBUG_ENTER("innodb_patches_init");
ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
schema->fields_info = innodb_patches_fields_info;
schema->fill_table = innodb_patches_fill;
DBUG_RETURN(0);
}
UNIV_INTERN struct st_mysql_plugin i_s_innodb_patches =
{
/* 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_PATCHES"),
/* plugin author (for SHOW PLUGINS) */
/* const char* */
STRUCT_FLD(author, "Percona"),
/* general descriptive text (for SHOW PLUGINS) */
/* const char* */
STRUCT_FLD(descr, "Patches applied to InnoDB plugin"),
/* 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_patches_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),
/* reserved for dependency checking */
/* void* */
STRUCT_FLD(__reserved1, NULL)
};
/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_trx */ /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_trx */
static ST_FIELD_INFO innodb_trx_fields_info[] = static ST_FIELD_INFO innodb_trx_fields_info[] =
{ {
...@@ -383,10 +566,6 @@ innodb_trx_init( ...@@ -383,10 +566,6 @@ innodb_trx_init(
DBUG_RETURN(0); DBUG_RETURN(0);
} }
static struct st_mysql_information_schema i_s_info =
{
MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION
};
UNIV_INTERN struct st_mysql_plugin i_s_innodb_trx = UNIV_INTERN struct st_mysql_plugin i_s_innodb_trx =
{ {
......
...@@ -16,5 +16,6 @@ extern struct st_mysql_plugin i_s_innodb_cmp; ...@@ -16,5 +16,6 @@ extern struct st_mysql_plugin i_s_innodb_cmp;
extern struct st_mysql_plugin i_s_innodb_cmp_reset; extern struct st_mysql_plugin i_s_innodb_cmp_reset;
extern struct st_mysql_plugin i_s_innodb_cmpmem; extern struct st_mysql_plugin i_s_innodb_cmpmem;
extern struct st_mysql_plugin i_s_innodb_cmpmem_reset; extern struct st_mysql_plugin i_s_innodb_cmpmem_reset;
extern struct st_mysql_plugin i_s_innodb_patches;
#endif /* i_s_h */ #endif /* i_s_h */
/* Copyright (C) 2002-2006 MySQL AB
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef USE_PRAGMA_INTERFACE
#pragma interface /* gcc class implementation */
#endif
struct innodb_patch {
const char *file;
const char *name;
const char *version;
const char *author;
const char *license;
const char *comment;
}innodb_patches[] = {
{"innodb_show_patches.patch","I_S.INNODB_PATCHES","1.0","Percona","GPLv2",""},
{"innodb_show_status.patch","Fixes to SHOW INNODB STATUS","1.0","Percona","GPLv2","Memory information and lock info fixes"},
{"innodb_io_patches.patch","Patches to InnoDB IO","1.0","Percona","GPLv2",""},
{"innodb_rw_lock.patch","InnoDB RW-lock fixes","1.0","Percona","GPLv2","Useful for 8+ cores SMP systems"},
{NULL, NULL, NULL, NULL, NULL, NULL}
};
...@@ -696,6 +696,16 @@ fil_page_get_type( ...@@ -696,6 +696,16 @@ fil_page_get_type(
return value not defined */ return value not defined */
const byte* page); /* in: file page */ const byte* page); /* in: file page */
/*************************************************************************
Return local hash table informations. */
ulint
fil_system_hash_cells(void);
/*========================*/
ulint
fil_system_hash_nodes(void);
/*========================*/
typedef struct fil_space_struct fil_space_t; typedef struct fil_space_struct fil_space_t;
......
...@@ -90,6 +90,9 @@ extern ulint srv_log_file_size; ...@@ -90,6 +90,9 @@ extern ulint srv_log_file_size;
extern ulint srv_log_buffer_size; extern ulint srv_log_buffer_size;
extern ulong srv_flush_log_at_trx_commit; extern ulong srv_flush_log_at_trx_commit;
extern ulint srv_show_locks_held;
extern ulint srv_show_verbose_locks;
/* The sort order table of the MySQL latin1_swedish_ci character set /* The sort order table of the MySQL latin1_swedish_ci character set
collation */ collation */
extern const byte* srv_latin1_ordering; extern const byte* srv_latin1_ordering;
......
...@@ -328,7 +328,17 @@ rw_lock_get_x_lock_count( ...@@ -328,7 +328,17 @@ rw_lock_get_x_lock_count(
Accessor functions for rw lock. */ Accessor functions for rw lock. */
UNIV_INLINE UNIV_INLINE
ulint ulint
rw_lock_get_waiters( rw_lock_get_s_waiters(
/*==================*/
rw_lock_t* lock);
UNIV_INLINE
ulint
rw_lock_get_x_waiters(
/*==================*/
rw_lock_t* lock);
UNIV_INLINE
ulint
rw_lock_get_wx_waiters(
/*================*/ /*================*/
rw_lock_t* lock); rw_lock_t* lock);
UNIV_INLINE UNIV_INLINE
...@@ -412,6 +422,11 @@ rw_lock_debug_print( ...@@ -412,6 +422,11 @@ rw_lock_debug_print(
rw_lock_debug_t* info); /* in: debug struct */ rw_lock_debug_t* info); /* in: debug struct */
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
#ifdef HAVE_GCC_ATOMIC_BUILTINS
/* This value means NOT_LOCKED */
#define RW_LOCK_BIAS 0x00100000
#endif
/* NOTE! The structure appears here only for the compiler to know its size. /* NOTE! The structure appears here only for the compiler to know its size.
Do not use its fields directly! The structure used in the spin lock Do not use its fields directly! The structure used in the spin lock
implementation of a read-write lock. Several threads may have a shared lock implementation of a read-write lock. Several threads may have a shared lock
...@@ -421,9 +436,9 @@ blocked by readers, a writer may queue for the lock by setting the writer ...@@ -421,9 +436,9 @@ blocked by readers, a writer may queue for the lock by setting the writer
field. Then no new readers are allowed in. */ field. Then no new readers are allowed in. */
struct rw_lock_struct { struct rw_lock_struct {
os_event_t event; /* Used by sync0arr.c for thread queueing */ /* Used by sync0arr.c for thread queueing */
os_event_t s_event; /* Used for s_lock */
#ifdef __WIN__ os_event_t x_event; /* Used for x_lock */
os_event_t wait_ex_event; /* This windows specific event is os_event_t wait_ex_event; /* This windows specific event is
used by the thread which has set the used by the thread which has set the
lock state to RW_LOCK_WAIT_EX. The lock state to RW_LOCK_WAIT_EX. The
...@@ -431,30 +446,34 @@ struct rw_lock_struct { ...@@ -431,30 +446,34 @@ struct rw_lock_struct {
thread will be the next one to proceed thread will be the next one to proceed
once the current the event gets once the current the event gets
signalled. See LEMMA 2 in sync0sync.c */ signalled. See LEMMA 2 in sync0sync.c */
#ifdef HAVE_GCC_ATOMIC_BUILTINS
volatile lint lock_word; /* Used by using atomic builtin */
#endif #endif
ulint reader_count; /* Number of readers who have locked this volatile ulint reader_count; /* Number of readers who have locked this
lock in the shared mode */ lock in the shared mode */
ulint writer; /* This field is set to RW_LOCK_EX if there volatile ulint writer; /* This field is set to RW_LOCK_EX if there
is a writer owning the lock (in exclusive is a writer owning the lock (in exclusive
mode), RW_LOCK_WAIT_EX if a writer is mode), RW_LOCK_WAIT_EX if a writer is
queueing for the lock, and queueing for the lock, and
RW_LOCK_NOT_LOCKED, otherwise. */ RW_LOCK_NOT_LOCKED, otherwise. */
os_thread_id_t writer_thread; volatile os_thread_id_t writer_thread;
/* Thread id of a possible writer thread */ /* Thread id of a possible writer thread */
ulint writer_count; /* Number of times the same thread has volatile ulint writer_count; /* Number of times the same thread has
recursively locked the lock in the exclusive recursively locked the lock in the exclusive
mode */ mode */
#ifndef HAVE_GCC_ATOMIC_BUILTINS
mutex_t mutex; /* The mutex protecting rw_lock_struct */ mutex_t mutex; /* The mutex protecting rw_lock_struct */
#endif
ulint pass; /* Default value 0. This is set to some ulint pass; /* Default value 0. This is set to some
value != 0 given by the caller of an x-lock value != 0 given by the caller of an x-lock
operation, if the x-lock is to be passed to operation, if the x-lock is to be passed to
another thread to unlock (which happens in another thread to unlock (which happens in
asynchronous i/o). */ asynchronous i/o). */
ulint waiters; /* This ulint is set to 1 if there are volatile ulint s_waiters; /* 1: there are waiters (s_lock) */
waiters (readers or writers) in the global volatile ulint x_waiters; /* 1: there are waiters (x_lock) */
wait array, waiting for this rw_lock. volatile ulint wait_ex_waiters; /* 1: there are waiters (wait_ex) */
Otherwise, == 0. */
UT_LIST_NODE_T(rw_lock_t) list; UT_LIST_NODE_T(rw_lock_t) list;
/* All allocated rw locks are put into a /* All allocated rw locks are put into a
list */ list */
...@@ -467,7 +486,7 @@ struct rw_lock_struct { ...@@ -467,7 +486,7 @@ struct rw_lock_struct {
const char* cfile_name;/* File name where lock created */ const char* cfile_name;/* File name where lock created */
const char* last_s_file_name;/* File name where last s-locked */ const char* last_s_file_name;/* File name where last s-locked */
const char* last_x_file_name;/* File name where last x-locked */ const char* last_x_file_name;/* File name where last x-locked */
ibool writer_is_wait_ex; volatile ibool writer_is_wait_ex;
/* This is TRUE if the writer field is /* This is TRUE if the writer field is
RW_LOCK_WAIT_EX; this field is located far RW_LOCK_WAIT_EX; this field is located far
from the memory update hotspot fields which from the memory update hotspot fields which
......
This diff is collapsed.
...@@ -60,6 +60,17 @@ thr_local_get_in_ibuf_field(void); ...@@ -60,6 +60,17 @@ thr_local_get_in_ibuf_field(void);
/*=============================*/ /*=============================*/
/* out: pointer to the in_ibuf field */ /* out: pointer to the in_ibuf field */
/*************************************************************************
Return local hash table informations. */
ulint
thr_local_hash_cells(void);
/*=======================*/
ulint
thr_local_hash_nodes(void);
/*=======================*/
#ifndef UNIV_NONINL #ifndef UNIV_NONINL
#include "thr0loc.ic" #include "thr0loc.ic"
#endif #endif
......
...@@ -12,6 +12,7 @@ Created 1/20/1994 Heikki Tuuri ...@@ -12,6 +12,7 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 1 #define INNODB_VERSION_MAJOR 1
#define INNODB_VERSION_MINOR 0 #define INNODB_VERSION_MINOR 0
#define INNODB_VERSION_BUGFIX 2 #define INNODB_VERSION_BUGFIX 2
#define PERCONA_INNODB_VERSION -1
/* The following is the InnoDB version as shown in /* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins; SELECT plugin_version FROM information_schema.plugins;
...@@ -23,13 +24,14 @@ component, i.e. we show M.N.P as M.N */ ...@@ -23,13 +24,14 @@ component, i.e. we show M.N.P as M.N */
(INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR) (INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR)
/* auxiliary macros to help creating the version as string */ /* auxiliary macros to help creating the version as string */
#define __INNODB_VERSION(a, b, c) (#a "." #b "." #c) #define __INNODB_VERSION(a, b, c, d) (#a "." #b "." #c "." #d)
#define _INNODB_VERSION(a, b, c) __INNODB_VERSION(a, b, c) #define _INNODB_VERSION(a, b, c, d) __INNODB_VERSION(a, b, c, d)
#define INNODB_VERSION_STR \ #define INNODB_VERSION_STR \
_INNODB_VERSION(INNODB_VERSION_MAJOR, \ _INNODB_VERSION(INNODB_VERSION_MAJOR, \
INNODB_VERSION_MINOR, \ INNODB_VERSION_MINOR, \
INNODB_VERSION_BUGFIX) INNODB_VERSION_BUGFIX, \
PERCONA_INNODB_VERSION)
#ifdef MYSQL_DYNAMIC_PLUGIN #ifdef MYSQL_DYNAMIC_PLUGIN
/* In the dynamic plugin, redefine some externally visible symbols /* In the dynamic plugin, redefine some externally visible symbols
......
...@@ -4294,32 +4294,32 @@ lock_rec_print( ...@@ -4294,32 +4294,32 @@ lock_rec_print(
putc('\n', file); putc('\n', file);
block = buf_page_try_get(space, page_no, &mtr); if ( srv_show_verbose_locks ) {
block = buf_page_try_get(space, page_no, &mtr);
if (block) { if (block) {
for (i = 0; i < lock_rec_get_n_bits(lock); i++) { for (i = 0; i < lock_rec_get_n_bits(lock); i++) {
if (lock_rec_get_nth_bit(lock, i)) { if (lock_rec_get_nth_bit(lock, i)) {
const rec_t* rec const rec_t* rec
= page_find_rec_with_heap_no( = page_find_rec_with_heap_no(
buf_block_get_frame(block), i); buf_block_get_frame(block), i);
offsets = rec_get_offsets( offsets = rec_get_offsets(
rec, lock->index, offsets, rec, lock->index, offsets,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
fprintf(file, "Record lock, heap no %lu ", fprintf(file, "Record lock, heap no %lu ",
(ulong) i); (ulong) i);
rec_print_new(file, rec, offsets); rec_print_new(file, rec, offsets);
putc('\n', file); putc('\n', file);
}
}
} else {
for (i = 0; i < lock_rec_get_n_bits(lock); i++) {
fprintf(file, "Record lock, heap no %lu\n", (ulong) i);
} }
}
} else {
for (i = 0; i < lock_rec_get_n_bits(lock); i++) {
fprintf(file, "Record lock, heap no %lu\n", (ulong) i);
} }
} }
mtr_commit(&mtr); mtr_commit(&mtr);
if (UNIV_LIKELY_NULL(heap)) { if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap); mem_heap_free(heap);
...@@ -4498,7 +4498,7 @@ lock_print_info_all_transactions( ...@@ -4498,7 +4498,7 @@ lock_print_info_all_transactions(
} }
} }
if (!srv_print_innodb_lock_monitor) { if (!srv_print_innodb_lock_monitor && !srv_show_locks_held) {
nth_trx++; nth_trx++;
goto loop; goto loop;
} }
...@@ -4557,8 +4557,8 @@ lock_print_info_all_transactions( ...@@ -4557,8 +4557,8 @@ lock_print_info_all_transactions(
nth_lock++; nth_lock++;
if (nth_lock >= 10) { if (nth_lock >= srv_show_locks_held) {
fputs("10 LOCKS PRINTED FOR THIS TRX:" fputs("TOO LOCKS PRINTED FOR THIS TRX:"
" SUPPRESSING FURTHER PRINTS\n", " SUPPRESSING FURTHER PRINTS\n",
file); file);
......
...@@ -3263,9 +3263,9 @@ log_print( ...@@ -3263,9 +3263,9 @@ log_print(
"Modified age %lu\n" "Modified age %lu\n"
"Checkpoint age %lu\n", "Checkpoint age %lu\n",
(ulong) log_sys->max_checkpoint_age, (ulong) log_sys->max_checkpoint_age,
(ulong) ut_dulint_minus(log_sys->lsn, (ulong) (log_sys->lsn -
log_buf_pool_get_oldest_modification()), log_buf_pool_get_oldest_modification()),
(ulong) ut_dulint_minus(log_sys->lsn, log_sys->last_checkpoint_lsn)); (ulong) (log_sys->lsn - log_sys->last_checkpoint_lsn));
current_time = time(NULL); current_time = time(NULL);
......
...@@ -132,6 +132,10 @@ UNIV_INTERN ulint srv_log_file_size = ULINT_MAX; ...@@ -132,6 +132,10 @@ UNIV_INTERN ulint srv_log_file_size = ULINT_MAX;
UNIV_INTERN ulint srv_log_buffer_size = ULINT_MAX; UNIV_INTERN ulint srv_log_buffer_size = ULINT_MAX;
UNIV_INTERN ulong srv_flush_log_at_trx_commit = 1; UNIV_INTERN ulong srv_flush_log_at_trx_commit = 1;
UNIV_INTERN ulint srv_show_locks_held = 10;
UNIV_INTERN ulint srv_show_verbose_locks = 0;
/* The sort order table of the MySQL latin1_swedish_ci character set /* The sort order table of the MySQL latin1_swedish_ci character set
collation */ collation */
UNIV_INTERN const byte* srv_latin1_ordering; UNIV_INTERN const byte* srv_latin1_ordering;
...@@ -1625,6 +1629,14 @@ srv_printf_innodb_monitor( ...@@ -1625,6 +1629,14 @@ srv_printf_innodb_monitor(
time_t current_time; time_t current_time;
ulint n_reserved; ulint n_reserved;
ulint btr_search_sys_subtotal;
ulint lock_sys_subtotal;
ulint recv_sys_subtotal;
ulint io_counter_subtotal;
ulint i;
trx_t* trx;
mutex_enter(&srv_innodb_monitor_mutex); mutex_enter(&srv_innodb_monitor_mutex);
current_time = time(NULL); current_time = time(NULL);
...@@ -1668,24 +1680,6 @@ srv_printf_innodb_monitor( ...@@ -1668,24 +1680,6 @@ srv_printf_innodb_monitor(
mutex_exit(&dict_foreign_err_mutex); mutex_exit(&dict_foreign_err_mutex);
lock_print_info_summary(file);
if (trx_start) {
long t = ftell(file);
if (t < 0) {
*trx_start = ULINT_UNDEFINED;
} else {
*trx_start = (ulint) t;
}
}
lock_print_info_all_transactions(file);
if (trx_end) {
long t = ftell(file);
if (t < 0) {
*trx_end = ULINT_UNDEFINED;
} else {
*trx_end = (ulint) t;
}
}
fputs("--------\n" fputs("--------\n"
"FILE I/O\n" "FILE I/O\n"
"--------\n", file); "--------\n", file);
...@@ -1716,10 +1710,84 @@ srv_printf_innodb_monitor( ...@@ -1716,10 +1710,84 @@ srv_printf_innodb_monitor(
"BUFFER POOL AND MEMORY\n" "BUFFER POOL AND MEMORY\n"
"----------------------\n", file); "----------------------\n", file);
fprintf(file, fprintf(file,
"Total memory allocated " ULINTPF "Total memory allocated " ULINTPF
"; in additional pool allocated " ULINTPF "\n", "; in additional pool allocated " ULINTPF "\n",
ut_total_allocated_memory, ut_total_allocated_memory,
mem_pool_get_reserved(mem_comm_pool)); mem_pool_get_reserved(mem_comm_pool));
/* Calcurate reserved memories */
if (btr_search_sys && btr_search_sys->hash_index->heap) {
btr_search_sys_subtotal = mem_heap_get_size(btr_search_sys->hash_index->heap);
} else {
btr_search_sys_subtotal = 0;
for (i=0; i < btr_search_sys->hash_index->n_mutexes; i++) {
btr_search_sys_subtotal += mem_heap_get_size(btr_search_sys->hash_index->heaps[i]);
}
}
lock_sys_subtotal = 0;
if (trx_sys) {
mutex_enter(&kernel_mutex);
trx = UT_LIST_GET_FIRST(trx_sys->mysql_trx_list);
while (trx) {
lock_sys_subtotal += ((trx->lock_heap) ? mem_heap_get_size(trx->lock_heap) : 0);
trx = UT_LIST_GET_NEXT(mysql_trx_list, trx);
}
mutex_exit(&kernel_mutex);
}
recv_sys_subtotal = ((recv_sys && recv_sys->addr_hash)
? mem_heap_get_size(recv_sys->heap) : 0);
fprintf(file,
"Internal hash tables (constant factor + variable factor)\n"
" Adaptive hash index %lu \t(%lu + %lu)\n"
" Page hash %lu\n"
" Dictionary cache %lu \t(%lu + %lu)\n"
" File system %lu \t(%lu + %lu)\n"
" Lock system %lu \t(%lu + %lu)\n"
" Recovery system %lu \t(%lu + %lu)\n"
" Threads %lu \t(%lu + %lu)\n",
(ulong) (btr_search_sys
? (btr_search_sys->hash_index->n_cells * sizeof(hash_cell_t)) : 0)
+ btr_search_sys_subtotal,
(ulong) (btr_search_sys
? (btr_search_sys->hash_index->n_cells * sizeof(hash_cell_t)) : 0),
(ulong) btr_search_sys_subtotal,
(ulong) (buf_pool->page_hash->n_cells * sizeof(hash_cell_t)),
(ulong) (dict_sys ? ((dict_sys->table_hash->n_cells
+ dict_sys->table_id_hash->n_cells
) * sizeof(hash_cell_t)
+ dict_sys->size) : 0),
(ulong) (dict_sys ? ((dict_sys->table_hash->n_cells
+ dict_sys->table_id_hash->n_cells
) * sizeof(hash_cell_t)) : 0),
(ulong) (dict_sys ? (dict_sys->size) : 0),
(ulong) (fil_system_hash_cells() * sizeof(hash_cell_t)
+ fil_system_hash_nodes()),
(ulong) (fil_system_hash_cells() * sizeof(hash_cell_t)),
(ulong) fil_system_hash_nodes(),
(ulong) ((lock_sys ? (lock_sys->rec_hash->n_cells * sizeof(hash_cell_t)) : 0)
+ lock_sys_subtotal),
(ulong) (lock_sys ? (lock_sys->rec_hash->n_cells * sizeof(hash_cell_t)) : 0),
(ulong) lock_sys_subtotal,
(ulong) (((recv_sys && recv_sys->addr_hash)
? (recv_sys->addr_hash->n_cells * sizeof(hash_cell_t)) : 0)
+ recv_sys_subtotal),
(ulong) ((recv_sys && recv_sys->addr_hash)
? (recv_sys->addr_hash->n_cells * sizeof(hash_cell_t)) : 0),
(ulong) recv_sys_subtotal,
(ulong) (thr_local_hash_cells() * sizeof(hash_cell_t)
+ thr_local_hash_nodes()),
(ulong) (thr_local_hash_cells() * sizeof(hash_cell_t)),
(ulong) thr_local_hash_nodes());
fprintf(file, "Dictionary memory allocated " ULINTPF "\n", fprintf(file, "Dictionary memory allocated " ULINTPF "\n",
dict_sys->size); dict_sys->size);
...@@ -1778,6 +1846,25 @@ srv_printf_innodb_monitor( ...@@ -1778,6 +1846,25 @@ srv_printf_innodb_monitor(
srv_n_rows_deleted_old = srv_n_rows_deleted; srv_n_rows_deleted_old = srv_n_rows_deleted;
srv_n_rows_read_old = srv_n_rows_read; srv_n_rows_read_old = srv_n_rows_read;
lock_print_info_summary(file);
if (trx_start) {
long t = ftell(file);
if (t < 0) {
*trx_start = ULINT_UNDEFINED;
} else {
*trx_start = (ulint) t;
}
}
lock_print_info_all_transactions(file);
if (trx_end) {
long t = ftell(file);
if (t < 0) {
*trx_end = ULINT_UNDEFINED;
} else {
*trx_end = (ulint) t;
}
}
fputs("----------------------------\n" fputs("----------------------------\n"
"END OF INNODB MONITOR OUTPUT\n" "END OF INNODB MONITOR OUTPUT\n"
"============================\n", file); "============================\n", file);
...@@ -2214,7 +2301,7 @@ srv_master_thread( ...@@ -2214,7 +2301,7 @@ srv_master_thread(
ibool skip_sleep = FALSE; ibool skip_sleep = FALSE;
ulint i; ulint i;
dulint oldest_lsn; ib_uint64_t oldest_lsn;
#ifdef UNIV_DEBUG_THREAD_CREATION #ifdef UNIV_DEBUG_THREAD_CREATION
fprintf(stderr, "Master thread starts, id %lu\n", fprintf(stderr, "Master thread starts, id %lu\n",
...@@ -2336,12 +2423,12 @@ srv_master_thread( ...@@ -2336,12 +2423,12 @@ srv_master_thread(
mutex_enter(&(log_sys->mutex)); mutex_enter(&(log_sys->mutex));
oldest_lsn = buf_pool_get_oldest_modification(); oldest_lsn = buf_pool_get_oldest_modification();
if (ut_dulint_is_zero(oldest_lsn)) { if (oldest_lsn == 0) {
mutex_exit(&(log_sys->mutex)); mutex_exit(&(log_sys->mutex));
} else { } else {
if (ut_dulint_minus(log_sys->lsn, oldest_lsn) if ((log_sys->lsn - oldest_lsn)
> (log_sys->max_checkpoint_age) - ((log_sys->max_checkpoint_age) / 4)) { > (log_sys->max_checkpoint_age) - ((log_sys->max_checkpoint_age) / 4)) {
/* 2nd defence line (max_checkpoint_age * 3/4) */ /* 2nd defence line (max_checkpoint_age * 3/4) */
...@@ -2349,9 +2436,9 @@ srv_master_thread( ...@@ -2349,9 +2436,9 @@ srv_master_thread(
mutex_exit(&(log_sys->mutex)); mutex_exit(&(log_sys->mutex));
n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100), n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100),
ut_dulint_max); IB_ULONGLONG_MAX);
skip_sleep = TRUE; skip_sleep = TRUE;
} else if (ut_dulint_minus(log_sys->lsn, oldest_lsn) } else if ((log_sys->lsn - oldest_lsn)
> (log_sys->max_checkpoint_age)/2 ) { > (log_sys->max_checkpoint_age)/2 ) {
/* 1st defence line (max_checkpoint_age * 1/2) */ /* 1st defence line (max_checkpoint_age * 1/2) */
...@@ -2359,7 +2446,7 @@ srv_master_thread( ...@@ -2359,7 +2446,7 @@ srv_master_thread(
mutex_exit(&(log_sys->mutex)); mutex_exit(&(log_sys->mutex));
n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(10), n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(10),
ut_dulint_max); IB_ULONGLONG_MAX);
skip_sleep = TRUE; skip_sleep = TRUE;
} else { } else {
mutex_exit(&(log_sys->mutex)); mutex_exit(&(log_sys->mutex));
......
...@@ -307,13 +307,13 @@ sync_cell_event_reset( ...@@ -307,13 +307,13 @@ sync_cell_event_reset(
{ {
if (type == SYNC_MUTEX) { if (type == SYNC_MUTEX) {
return(os_event_reset(((mutex_t *) object)->event)); return(os_event_reset(((mutex_t *) object)->event));
#ifdef __WIN__
} else if (type == RW_LOCK_WAIT_EX) { } else if (type == RW_LOCK_WAIT_EX) {
return(os_event_reset( return(os_event_reset(
((rw_lock_t *) object)->wait_ex_event)); ((rw_lock_t *) object)->wait_ex_event));
#endif } else if (type == RW_LOCK_SHARED) {
} else { return(os_event_reset(((rw_lock_t *) object)->s_event));
return(os_event_reset(((rw_lock_t *) object)->event)); } else { /* RW_LOCK_EX */
return(os_event_reset(((rw_lock_t *) object)->x_event));
} }
} }
...@@ -413,15 +413,12 @@ sync_array_wait_event( ...@@ -413,15 +413,12 @@ sync_array_wait_event(
if (cell->request_type == SYNC_MUTEX) { if (cell->request_type == SYNC_MUTEX) {
event = ((mutex_t*) cell->wait_object)->event; event = ((mutex_t*) cell->wait_object)->event;
#ifdef __WIN__
/* On windows if the thread about to wait is the one which
has set the state of the rw_lock to RW_LOCK_WAIT_EX, then
it waits on a special event i.e.: wait_ex_event. */
} else if (cell->request_type == RW_LOCK_WAIT_EX) { } else if (cell->request_type == RW_LOCK_WAIT_EX) {
event = ((rw_lock_t*) cell->wait_object)->wait_ex_event; event = ((rw_lock_t*) cell->wait_object)->wait_ex_event;
#endif } else if (cell->request_type == RW_LOCK_SHARED) {
event = ((rw_lock_t*) cell->wait_object)->s_event;
} else { } else {
event = ((rw_lock_t*) cell->wait_object)->event; event = ((rw_lock_t*) cell->wait_object)->x_event;
} }
cell->waiting = TRUE; cell->waiting = TRUE;
...@@ -462,6 +459,7 @@ sync_array_cell_print( ...@@ -462,6 +459,7 @@ sync_array_cell_print(
mutex_t* mutex; mutex_t* mutex;
rw_lock_t* rwlock; rw_lock_t* rwlock;
ulint type; ulint type;
ulint writer;
type = cell->request_type; type = cell->request_type;
...@@ -491,12 +489,10 @@ sync_array_cell_print( ...@@ -491,12 +489,10 @@ sync_array_cell_print(
(ulong) mutex->waiters); (ulong) mutex->waiters);
} else if (type == RW_LOCK_EX } else if (type == RW_LOCK_EX
#ifdef __WIN__
|| type == RW_LOCK_WAIT_EX || type == RW_LOCK_WAIT_EX
#endif
|| type == RW_LOCK_SHARED) { || type == RW_LOCK_SHARED) {
fputs(type == RW_LOCK_EX ? "X-lock on" : "S-lock on", file); fputs(type == RW_LOCK_SHARED ? "S-lock on" : "X-lock on", file);
rwlock = cell->old_wait_rw_lock; rwlock = cell->old_wait_rw_lock;
...@@ -504,22 +500,24 @@ sync_array_cell_print( ...@@ -504,22 +500,24 @@ sync_array_cell_print(
" RW-latch at %p created in file %s line %lu\n", " RW-latch at %p created in file %s line %lu\n",
(void*) rwlock, rwlock->cfile_name, (void*) rwlock, rwlock->cfile_name,
(ulong) rwlock->cline); (ulong) rwlock->cline);
if (rwlock->writer != RW_LOCK_NOT_LOCKED) { writer = rw_lock_get_writer(rwlock);
if (writer != RW_LOCK_NOT_LOCKED) {
fprintf(file, fprintf(file,
"a writer (thread id %lu) has" "a writer (thread id %lu) has"
" reserved it in mode %s", " reserved it in mode %s",
(ulong) os_thread_pf(rwlock->writer_thread), (ulong) os_thread_pf(rwlock->writer_thread),
rwlock->writer == RW_LOCK_EX writer == RW_LOCK_EX
? " exclusive\n" ? " exclusive\n"
: " wait exclusive\n"); : " wait exclusive\n");
} }
fprintf(file, fprintf(file,
"number of readers %lu, waiters flag %lu\n" "number of readers %lu, s_waiters flag %lu, x_waiters flag %lu\n"
"Last time read locked in file %s line %lu\n" "Last time read locked in file %s line %lu\n"
"Last time write locked in file %s line %lu\n", "Last time write locked in file %s line %lu\n",
(ulong) rwlock->reader_count, (ulong) rwlock->reader_count,
(ulong) rwlock->waiters, (ulong) rwlock->s_waiters,
(ulong) (rwlock->x_waiters || rwlock->wait_ex_waiters),
rwlock->last_s_file_name, rwlock->last_s_file_name,
(ulong) rwlock->last_s_line, (ulong) rwlock->last_s_line,
rwlock->last_x_file_name, rwlock->last_x_file_name,
...@@ -844,11 +842,15 @@ sync_array_object_signalled( ...@@ -844,11 +842,15 @@ sync_array_object_signalled(
/*========================*/ /*========================*/
sync_array_t* arr) /* in: wait array */ sync_array_t* arr) /* in: wait array */
{ {
#ifdef HAVE_GCC_ATOMIC_BUILTINS
__sync_fetch_and_add(&(arr->sg_count),1);
#else
sync_array_enter(arr); sync_array_enter(arr);
arr->sg_count++; arr->sg_count++;
sync_array_exit(arr); sync_array_exit(arr);
#endif
} }
/************************************************************************** /**************************************************************************
...@@ -889,19 +891,23 @@ sync_arr_wake_threads_if_sema_free(void) ...@@ -889,19 +891,23 @@ sync_arr_wake_threads_if_sema_free(void)
mutex = cell->wait_object; mutex = cell->wait_object;
os_event_set(mutex->event); os_event_set(mutex->event);
#ifdef __WIN__
} else if (cell->request_type } else if (cell->request_type
== RW_LOCK_WAIT_EX) { == RW_LOCK_WAIT_EX) {
rw_lock_t* lock; rw_lock_t* lock;
lock = cell->wait_object; lock = cell->wait_object;
os_event_set(lock->wait_ex_event); os_event_set(lock->wait_ex_event);
#endif } else if (cell->request_type
} else { == RW_LOCK_SHARED) {
rw_lock_t* lock; rw_lock_t* lock;
lock = cell->wait_object; lock = cell->wait_object;
os_event_set(lock->event); os_event_set(lock->s_event);
} else {
rw_lock_t* lock;
lock = cell->wait_object;
os_event_set(lock->x_event);
} }
} }
} }
......
This diff is collapsed.
...@@ -32,6 +32,7 @@ static mutex_t thr_local_mutex; ...@@ -32,6 +32,7 @@ static mutex_t thr_local_mutex;
/* The hash table. The module is not yet initialized when it is NULL. */ /* The hash table. The module is not yet initialized when it is NULL. */
static hash_table_t* thr_local_hash = NULL; static hash_table_t* thr_local_hash = NULL;
ulint thr_local_hash_n_nodes = 0;
/* The private data for each thread should be put to /* The private data for each thread should be put to
the structure below and the accessor functions written the structure below and the accessor functions written
...@@ -177,6 +178,7 @@ thr_local_create(void) ...@@ -177,6 +178,7 @@ thr_local_create(void)
os_thread_pf(os_thread_get_curr_id()), os_thread_pf(os_thread_get_curr_id()),
local); local);
thr_local_hash_n_nodes++;
mutex_exit(&thr_local_mutex); mutex_exit(&thr_local_mutex);
} }
...@@ -204,6 +206,7 @@ thr_local_free( ...@@ -204,6 +206,7 @@ thr_local_free(
HASH_DELETE(thr_local_t, hash, thr_local_hash, HASH_DELETE(thr_local_t, hash, thr_local_hash,
os_thread_pf(id), local); os_thread_pf(id), local);
thr_local_hash_n_nodes--;
mutex_exit(&thr_local_mutex); mutex_exit(&thr_local_mutex);
...@@ -226,3 +229,29 @@ thr_local_init(void) ...@@ -226,3 +229,29 @@ thr_local_init(void)
mutex_create(&thr_local_mutex, SYNC_THR_LOCAL); mutex_create(&thr_local_mutex, SYNC_THR_LOCAL);
} }
/*************************************************************************
Return local hash table informations. */
ulint
thr_local_hash_cells(void)
/*======================*/
{
if (thr_local_hash) {
return (thr_local_hash->n_cells);
} else {
return 0;
}
}
ulint
thr_local_hash_nodes(void)
/*======================*/
{
if (thr_local_hash) {
return (thr_local_hash_n_nodes
* (sizeof(thr_local_t) + MEM_BLOCK_HEADER_SIZE));
} else {
return 0;
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment