Commit 85dbe88d authored by Marko Mäkelä's avatar Marko Mäkelä

Bug#11766305 - 59392: Remove thr0loc.c and ibuf_inside() [part 4 of 4]

ibuf_inside(), ibuf_enter(), ibuf_exit(): Add the parameter mtr. The
flag is no longer kept in the thread-local storage but in the
mini-transaction (mtr->inside_ibuf).

mtr_start(): Clean up the comment and remove the unused return value.
mtr_commit(): Assert !ibuf_inside(mtr) in debug builds.

ibuf_mtr_start(): Like mtr_start(), but sets the flag.
ibuf_mtr_commit(), ibuf_btr_pcur_commit_specify_mtr(): Wrappers that
assert ibuf_inside().

buf_page_get_zip(), buf_page_init_for_read(),
buf_read_ibuf_merge_pages(), fil_io(), ibuf_free_excess_pages(),
ibuf_contract_ext(): Remove assertions on ibuf_inside(), because a
mini-transaction is not available.

buf_read_ahead_linear(): Add the parameter inside_ibuf.

ibuf_restore_pos(): When this function returns FALSE, it commits mtr
and must therefore do ibuf_exit(mtr).

ibuf_delete_rec(): This function commits mtr and must therefore do
ibuf_exit(mtr).

ibuf_rec_get_page_no(), ibuf_rec_get_space(), ibuf_rec_get_info(),
ibuf_rec_get_op_type(), ibuf_build_entry_from_ibuf_rec(),
ibuf_rec_get_volume(), ibuf_get_merge_page_nos(),
ibuf_get_volume_buffered_count(), ibuf_get_entry_counter_low(): Add
the parameter mtr in debug builds, for asserting ibuf_inside(mtr).

rb:585 approved by Sunny Bains
parent a4d2a3a3
...@@ -241,7 +241,6 @@ SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c ...@@ -241,7 +241,6 @@ SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
row/row0sel.c row/row0uins.c row/row0umod.c row/row0undo.c row/row0upd.c row/row0vers.c row/row0sel.c row/row0uins.c row/row0umod.c row/row0undo.c row/row0upd.c row/row0vers.c
srv/srv0srv.c srv/srv0start.c srv/srv0srv.c srv/srv0start.c
sync/sync0arr.c sync/sync0rw.c sync/sync0sync.c sync/sync0arr.c sync/sync0rw.c sync/sync0sync.c
thr/thr0loc.c
trx/trx0i_s.c trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c trx/trx0i_s.c trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c
trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c
usr/usr0sess.c usr/usr0sess.c
......
...@@ -402,7 +402,7 @@ btr_cur_search_to_nth_level( ...@@ -402,7 +402,7 @@ btr_cur_search_to_nth_level(
ut_ad(level == 0 || mode == PAGE_CUR_LE); ut_ad(level == 0 || mode == PAGE_CUR_LE);
ut_ad(dict_index_check_search_tuple(index, tuple)); ut_ad(dict_index_check_search_tuple(index, tuple));
ut_ad(!dict_index_is_ibuf(index) || ibuf_inside()); ut_ad(!dict_index_is_ibuf(index) || ibuf_inside(mtr));
ut_ad(dtuple_check_typed(tuple)); ut_ad(dtuple_check_typed(tuple));
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
......
...@@ -2316,9 +2316,6 @@ buf_page_get_zip( ...@@ -2316,9 +2316,6 @@ buf_page_get_zip(
unsigned access_time; unsigned access_time;
buf_pool_t* buf_pool = buf_pool_get(space, offset); buf_pool_t* buf_pool = buf_pool_get(space, offset);
#ifndef UNIV_LOG_DEBUG
ut_ad(!ibuf_inside());
#endif
buf_pool->stat.n_page_gets++; buf_pool->stat.n_page_gets++;
for (;;) { for (;;) {
...@@ -2758,7 +2755,8 @@ buf_page_get_gen( ...@@ -2758,7 +2755,8 @@ buf_page_get_gen(
ut_ad(zip_size == fil_space_get_zip_size(space)); ut_ad(zip_size == fil_space_get_zip_size(space));
ut_ad(ut_is_2pow(zip_size)); ut_ad(ut_is_2pow(zip_size));
#ifndef UNIV_LOG_DEBUG #ifndef UNIV_LOG_DEBUG
ut_ad(!ibuf_inside() || ibuf_page_low(space, zip_size, offset, ut_ad(!ibuf_inside(mtr)
|| ibuf_page_low(space, zip_size, offset,
FALSE, file, line, NULL)); FALSE, file, line, NULL));
#endif #endif
buf_pool->stat.n_page_gets++; buf_pool->stat.n_page_gets++;
...@@ -3132,7 +3130,8 @@ wait_until_unfixed: ...@@ -3132,7 +3130,8 @@ wait_until_unfixed:
/* In the case of a first access, try to apply linear /* In the case of a first access, try to apply linear
read-ahead */ read-ahead */
buf_read_ahead_linear(space, zip_size, offset); buf_read_ahead_linear(space, zip_size, offset,
ibuf_inside(mtr));
} }
#ifdef UNIV_IBUF_COUNT_DEBUG #ifdef UNIV_IBUF_COUNT_DEBUG
...@@ -3189,7 +3188,7 @@ buf_page_optimistic_get( ...@@ -3189,7 +3188,7 @@ buf_page_optimistic_get(
access_time = buf_page_is_accessed(&block->page); access_time = buf_page_is_accessed(&block->page);
buf_page_set_accessed_make_young(&block->page, access_time); buf_page_set_accessed_make_young(&block->page, access_time);
ut_ad(!ibuf_inside() ut_ad(!ibuf_inside(mtr)
|| ibuf_page(buf_block_get_space(block), || ibuf_page(buf_block_get_space(block),
buf_block_get_zip_size(block), buf_block_get_zip_size(block),
buf_block_get_page_no(block), NULL)); buf_block_get_page_no(block), NULL));
...@@ -3245,7 +3244,8 @@ buf_page_optimistic_get( ...@@ -3245,7 +3244,8 @@ buf_page_optimistic_get(
buf_read_ahead_linear(buf_block_get_space(block), buf_read_ahead_linear(buf_block_get_space(block),
buf_block_get_zip_size(block), buf_block_get_zip_size(block),
buf_block_get_page_no(block)); buf_block_get_page_no(block),
ibuf_inside(mtr));
} }
#ifdef UNIV_IBUF_COUNT_DEBUG #ifdef UNIV_IBUF_COUNT_DEBUG
...@@ -3321,7 +3321,7 @@ buf_page_get_known_nowait( ...@@ -3321,7 +3321,7 @@ buf_page_get_known_nowait(
buf_pool_mutex_exit(buf_pool); buf_pool_mutex_exit(buf_pool);
} }
ut_ad(!ibuf_inside() || (mode == BUF_KEEP_OLD)); ut_ad(!ibuf_inside(mtr) || mode == BUF_KEEP_OLD);
if (rw_latch == RW_S_LATCH) { if (rw_latch == RW_S_LATCH) {
success = rw_lock_s_lock_nowait(&(block->lock), success = rw_lock_s_lock_nowait(&(block->lock),
...@@ -3586,14 +3586,13 @@ buf_page_init_for_read( ...@@ -3586,14 +3586,13 @@ buf_page_init_for_read(
/* It is a read-ahead within an ibuf routine */ /* It is a read-ahead within an ibuf routine */
ut_ad(!ibuf_bitmap_page(zip_size, offset)); ut_ad(!ibuf_bitmap_page(zip_size, offset));
ut_ad(ibuf_inside());
mtr_start(&mtr); ibuf_mtr_start(&mtr);
if (!recv_no_ibuf_operations if (!recv_no_ibuf_operations
&& !ibuf_page(space, zip_size, offset, &mtr)) { && !ibuf_page(space, zip_size, offset, &mtr)) {
mtr_commit(&mtr); ibuf_mtr_commit(&mtr);
return(NULL); return(NULL);
} }
...@@ -3778,7 +3777,7 @@ func_exit: ...@@ -3778,7 +3777,7 @@ func_exit:
if (mode == BUF_READ_IBUF_PAGES_ONLY) { if (mode == BUF_READ_IBUF_PAGES_ONLY) {
mtr_commit(&mtr); ibuf_mtr_commit(&mtr);
} }
ut_ad(!bpage || buf_page_in_file(bpage)); ut_ad(!bpage || buf_page_in_file(bpage));
......
...@@ -237,9 +237,9 @@ ulint ...@@ -237,9 +237,9 @@ ulint
buf_read_ahead_linear( buf_read_ahead_linear(
/*==================*/ /*==================*/
ulint space, /*!< in: space id */ ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */ ulint zip_size, /*!< in: compressed page size in bytes, or 0 */
ulint offset) /*!< in: page number of a page; NOTE: the current thread ulint offset, /*!< in: page number; see NOTE 3 above */
must want access to this page (see NOTE 3 above) */ ibool inside_ibuf) /*!< in: TRUE if we are inside ibuf routine */
{ {
buf_pool_t* buf_pool = buf_pool_get(space, offset); buf_pool_t* buf_pool = buf_pool_get(space, offset);
ib_int64_t tablespace_version; ib_int64_t tablespace_version;
...@@ -429,11 +429,9 @@ buf_read_ahead_linear( ...@@ -429,11 +429,9 @@ buf_read_ahead_linear(
/* If we got this far, read-ahead can be sensible: do it */ /* If we got this far, read-ahead can be sensible: do it */
if (ibuf_inside()) { ibuf_mode = inside_ibuf
ibuf_mode = BUF_READ_IBUF_PAGES_ONLY; ? BUF_READ_IBUF_PAGES_ONLY | OS_AIO_SIMULATED_WAKE_LATER
} else { : BUF_READ_ANY_PAGE | OS_AIO_SIMULATED_WAKE_LATER;
ibuf_mode = BUF_READ_ANY_PAGE;
}
count = 0; count = 0;
...@@ -450,7 +448,7 @@ buf_read_ahead_linear( ...@@ -450,7 +448,7 @@ buf_read_ahead_linear(
if (!ibuf_bitmap_page(zip_size, i)) { if (!ibuf_bitmap_page(zip_size, i)) {
count += buf_read_page_low( count += buf_read_page_low(
&err, FALSE, &err, FALSE,
ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER, ibuf_mode,
space, zip_size, FALSE, tablespace_version, i); space, zip_size, FALSE, tablespace_version, i);
if (err == DB_TABLESPACE_DELETED) { if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
...@@ -520,7 +518,6 @@ buf_read_ibuf_merge_pages( ...@@ -520,7 +518,6 @@ buf_read_ibuf_merge_pages(
{ {
ulint i; ulint i;
ut_ad(!ibuf_inside());
#ifdef UNIV_IBUF_DEBUG #ifdef UNIV_IBUF_DEBUG
ut_a(n_stored < UNIV_PAGE_SIZE); ut_a(n_stored < UNIV_PAGE_SIZE);
#endif #endif
......
...@@ -4342,8 +4342,6 @@ fil_io( ...@@ -4342,8 +4342,6 @@ fil_io(
ut_ad(recv_no_ibuf_operations || (type == OS_FILE_WRITE) ut_ad(recv_no_ibuf_operations || (type == OS_FILE_WRITE)
|| !ibuf_bitmap_page(zip_size, block_offset) || !ibuf_bitmap_page(zip_size, block_offset)
|| sync || is_log); || sync || is_log);
ut_ad(!ibuf_inside() || is_log || (type == OS_FILE_WRITE)
|| ibuf_page(space_id, zip_size, block_offset, NULL));
# endif /* UNIV_LOG_DEBUG */ # endif /* UNIV_LOG_DEBUG */
if (sync) { if (sync) {
mode = OS_AIO_SYNC; mode = OS_AIO_SYNC;
......
...@@ -82,7 +82,6 @@ extern "C" { ...@@ -82,7 +82,6 @@ extern "C" {
#include "fil0fil.h" #include "fil0fil.h"
#include "trx0xa.h" #include "trx0xa.h"
#include "row0merge.h" #include "row0merge.h"
#include "thr0loc.h"
#include "dict0boot.h" #include "dict0boot.h"
#include "ha_prototypes.h" #include "ha_prototypes.h"
#include "ut0mem.h" #include "ut0mem.h"
...@@ -280,7 +279,6 @@ static PSI_mutex_info all_innodb_mutexes[] = { ...@@ -280,7 +279,6 @@ static PSI_mutex_info all_innodb_mutexes[] = {
{&sync_thread_mutex_key, "sync_thread_mutex", 0}, {&sync_thread_mutex_key, "sync_thread_mutex", 0},
# endif /* UNIV_SYNC_DEBUG */ # endif /* UNIV_SYNC_DEBUG */
{&trx_doublewrite_mutex_key, "trx_doublewrite_mutex", 0}, {&trx_doublewrite_mutex_key, "trx_doublewrite_mutex", 0},
{&thr_local_mutex_key, "thr_local_mutex", 0},
{&trx_undo_mutex_key, "trx_undo_mutex", 0} {&trx_undo_mutex_key, "trx_undo_mutex", 0}
}; };
# endif /* UNIV_PFS_MUTEX */ # endif /* UNIV_PFS_MUTEX */
...@@ -3042,7 +3040,6 @@ innobase_close_connection( ...@@ -3042,7 +3040,6 @@ innobase_close_connection(
innobase_rollback_trx(trx); innobase_rollback_trx(trx);
thr_local_free(trx->mysql_thread_id);
trx_free_for_mysql(trx); trx_free_for_mysql(trx);
DBUG_RETURN(0); DBUG_RETURN(0);
......
This diff is collapsed.
...@@ -71,9 +71,9 @@ ulint ...@@ -71,9 +71,9 @@ ulint
buf_read_ahead_linear( buf_read_ahead_linear(
/*==================*/ /*==================*/
ulint space, /*!< in: space id */ ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */ ulint zip_size, /*!< in: compressed page size in bytes, or 0 */
ulint offset);/*!< in: page number of a page; NOTE: the current thread ulint offset, /*!< in: page number; see NOTE 3 above */
must want access to this page (see NOTE 3 above) */ ibool inside_ibuf); /*!< in: TRUE if we are inside ibuf routine */
/********************************************************************//** /********************************************************************//**
Issues read requests for pages which the ibuf module wants to read in, in Issues read requests for pages which the ibuf module wants to read in, in
order to contract the insert buffer tree. Technically, this function is like order to contract the insert buffer tree. Technically, this function is like
......
...@@ -104,6 +104,22 @@ UNIV_INTERN ...@@ -104,6 +104,22 @@ UNIV_INTERN
void void
ibuf_update_max_tablespace_id(void); ibuf_update_max_tablespace_id(void);
/*===============================*/ /*===============================*/
/***************************************************************//**
Starts an insert buffer mini-transaction. */
UNIV_INLINE
void
ibuf_mtr_start(
/*===========*/
mtr_t* mtr) /*!< out: mini-transaction */
__attribute__((nonnull));
/***************************************************************//**
Commits an insert buffer mini-transaction. */
UNIV_INLINE
void
ibuf_mtr_commit(
/*============*/
mtr_t* mtr) /*!< in/out: mini-transaction */
__attribute__((nonnull));
/*********************************************************************//** /*********************************************************************//**
Initializes an ibuf bitmap page. */ Initializes an ibuf bitmap page. */
UNIV_INTERN UNIV_INTERN
...@@ -224,10 +240,12 @@ routine. ...@@ -224,10 +240,12 @@ routine.
For instance, a read-ahead of non-ibuf pages is forbidden by threads For instance, a read-ahead of non-ibuf pages is forbidden by threads
that are executing an insert buffer routine. that are executing an insert buffer routine.
@return TRUE if inside an insert buffer routine */ @return TRUE if inside an insert buffer routine */
UNIV_INTERN UNIV_INLINE
ibool ibool
ibuf_inside(void); ibuf_inside(
/*=============*/ /*========*/
const mtr_t* mtr) /*!< in: mini-transaction */
__attribute__((nonnull, pure));
/***********************************************************************//** /***********************************************************************//**
Checks if a page address is an ibuf bitmap page (level 3 page) address. Checks if a page address is an ibuf bitmap page (level 3 page) address.
@return TRUE if a bitmap page */ @return TRUE if a bitmap page */
......
...@@ -37,6 +37,30 @@ buffer inserts to this page. If there is this much of free space, the ...@@ -37,6 +37,30 @@ buffer inserts to this page. If there is this much of free space, the
corresponding bits are set in the ibuf bitmap. */ corresponding bits are set in the ibuf bitmap. */
#define IBUF_PAGE_SIZE_PER_FREE_SPACE 32 #define IBUF_PAGE_SIZE_PER_FREE_SPACE 32
/***************************************************************//**
Starts an insert buffer mini-transaction. */
UNIV_INLINE
void
ibuf_mtr_start(
/*===========*/
mtr_t* mtr) /*!< out: mini-transaction */
{
mtr_start(mtr);
mtr->inside_ibuf = TRUE;
}
/***************************************************************//**
Commits an insert buffer mini-transaction. */
UNIV_INLINE
void
ibuf_mtr_commit(
/*============*/
mtr_t* mtr) /*!< in/out: mini-transaction */
{
ut_ad(mtr->inside_ibuf);
ut_d(mtr->inside_ibuf = FALSE);
mtr_commit(mtr);
}
/** Insert buffer struct */ /** Insert buffer struct */
struct ibuf_struct{ struct ibuf_struct{
ulint size; /*!< current size of the ibuf index ulint size; /*!< current size of the ibuf index
...@@ -120,6 +144,22 @@ ibuf_should_try( ...@@ -120,6 +144,22 @@ ibuf_should_try(
return(FALSE); return(FALSE);
} }
/******************************************************************//**
Returns TRUE if the current OS thread is performing an insert buffer
routine.
For instance, a read-ahead of non-ibuf pages is forbidden by threads
that are executing an insert buffer routine.
@return TRUE if inside an insert buffer routine */
UNIV_INLINE
ibool
ibuf_inside(
/*========*/
const mtr_t* mtr) /*!< in: mini-transaction */
{
return(mtr->inside_ibuf);
}
/***********************************************************************//** /***********************************************************************//**
Checks if a page address is an ibuf bitmap page address. Checks if a page address is an ibuf bitmap page address.
@return TRUE if a bitmap page */ @return TRUE if a bitmap page */
......
...@@ -190,21 +190,21 @@ functions). The page number parameter was originally written as 0. @{ */ ...@@ -190,21 +190,21 @@ functions). The page number parameter was originally written as 0. @{ */
/* @} */ /* @} */
/***************************************************************//** /***************************************************************//**
Starts a mini-transaction and creates a mini-transaction handle Starts a mini-transaction. */
and buffer in the memory buffer given by the caller.
@return mtr buffer which also acts as the mtr handle */
UNIV_INLINE UNIV_INLINE
mtr_t* void
mtr_start( mtr_start(
/*======*/ /*======*/
mtr_t* mtr); /*!< in: memory buffer for the mtr buffer */ mtr_t* mtr) /*!< out: mini-transaction */
__attribute__((nonnull));
/***************************************************************//** /***************************************************************//**
Commits a mini-transaction. */ Commits a mini-transaction. */
UNIV_INTERN UNIV_INTERN
void void
mtr_commit( mtr_commit(
/*=======*/ /*=======*/
mtr_t* mtr); /*!< in: mini-transaction */ mtr_t* mtr) /*!< in/out: mini-transaction */
__attribute__((nonnull));
/**********************************************************//** /**********************************************************//**
Sets and returns a savepoint in mtr. Sets and returns a savepoint in mtr.
@return savepoint */ @return savepoint */
...@@ -378,6 +378,8 @@ struct mtr_struct{ ...@@ -378,6 +378,8 @@ struct mtr_struct{
#endif #endif
dyn_array_t memo; /*!< memo stack for locks etc. */ dyn_array_t memo; /*!< memo stack for locks etc. */
dyn_array_t log; /*!< mini-transaction log */ dyn_array_t log; /*!< mini-transaction log */
ibool inside_ibuf;
/*!< TRUE if inside ibuf changes */
ibool modifications; ibool modifications;
/* TRUE if the mtr made modifications to /* TRUE if the mtr made modifications to
buffer pool pages */ buffer pool pages */
......
...@@ -30,26 +30,23 @@ Created 11/26/1995 Heikki Tuuri ...@@ -30,26 +30,23 @@ Created 11/26/1995 Heikki Tuuri
#include "mach0data.h" #include "mach0data.h"
/***************************************************************//** /***************************************************************//**
Starts a mini-transaction and creates a mini-transaction handle Starts a mini-transaction. */
and a buffer in the memory buffer given by the caller.
@return mtr buffer which also acts as the mtr handle */
UNIV_INLINE UNIV_INLINE
mtr_t* void
mtr_start( mtr_start(
/*======*/ /*======*/
mtr_t* mtr) /*!< in: memory buffer for the mtr buffer */ mtr_t* mtr) /*!< out: mini-transaction */
{ {
dyn_array_create(&(mtr->memo)); dyn_array_create(&(mtr->memo));
dyn_array_create(&(mtr->log)); dyn_array_create(&(mtr->log));
mtr->log_mode = MTR_LOG_ALL; mtr->log_mode = MTR_LOG_ALL;
mtr->modifications = FALSE; mtr->modifications = FALSE;
mtr->inside_ibuf = FALSE;
mtr->n_log_recs = 0; mtr->n_log_recs = 0;
ut_d(mtr->state = MTR_ACTIVE); ut_d(mtr->state = MTR_ACTIVE);
ut_d(mtr->magic_n = MTR_MAGIC_N); ut_d(mtr->magic_n = MTR_MAGIC_N);
return(mtr);
} }
/***************************************************//** /***************************************************//**
......
...@@ -110,7 +110,6 @@ extern mysql_pfs_key_t syn_arr_mutex_key; ...@@ -110,7 +110,6 @@ extern mysql_pfs_key_t syn_arr_mutex_key;
extern mysql_pfs_key_t sync_thread_mutex_key; extern mysql_pfs_key_t sync_thread_mutex_key;
# endif /* UNIV_SYNC_DEBUG */ # endif /* UNIV_SYNC_DEBUG */
extern mysql_pfs_key_t trx_doublewrite_mutex_key; extern mysql_pfs_key_t trx_doublewrite_mutex_key;
extern mysql_pfs_key_t thr_local_mutex_key;
extern mysql_pfs_key_t trx_undo_mutex_key; extern mysql_pfs_key_t trx_undo_mutex_key;
#endif /* UNIV_PFS_MUTEX */ #endif /* UNIV_PFS_MUTEX */
......
/*****************************************************************************
Copyright (c) 1995, 2009, Innobase Oy. 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., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/**************************************************//**
@file include/thr0loc.h
The thread local storage
Created 10/5/1995 Heikki Tuuri
*******************************************************/
/* This module implements storage private to each thread,
a capability useful in some situations like storing the
OS handle to the current thread, or its priority. */
#ifndef thr0loc_h
#define thr0loc_h
#include "univ.i"
#include "os0thread.h"
/****************************************************************//**
Initializes the thread local storage module. */
UNIV_INTERN
void
thr_local_init(void);
/*================*/
/****************************************************************//**
Close the thread local storage module. */
UNIV_INTERN
void
thr_local_close(void);
/*=================*/
/*******************************************************************//**
Creates a local storage struct for the calling new thread. */
UNIV_INTERN
void
thr_local_create(void);
/*==================*/
/*******************************************************************//**
Frees the local storage struct for the specified thread. */
UNIV_INTERN
void
thr_local_free(
/*===========*/
os_thread_id_t id); /*!< in: thread id */
/*******************************************************************//**
Returns pointer to the 'in_ibuf' field within the current thread local
storage.
@return pointer to the in_ibuf field */
UNIV_INTERN
ibool*
thr_local_get_in_ibuf_field(void);
/*=============================*/
#ifndef UNIV_NONINL
#include "thr0loc.ic"
#endif
#endif
/*****************************************************************************
Copyright (c) 1995, 2009, Innobase Oy. 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., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/**************************************************//**
@file include/thr0loc.ic
Thread local storage
Created 10/4/1995 Heikki Tuuri
*******************************************************/
...@@ -251,6 +251,7 @@ mtr_commit( ...@@ -251,6 +251,7 @@ mtr_commit(
ut_ad(mtr); ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N); ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_ACTIVE); ut_ad(mtr->state == MTR_ACTIVE);
ut_ad(!mtr->inside_ibuf);
ut_d(mtr->state = MTR_COMMITTING); ut_d(mtr->state = MTR_COMMITTING);
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP
......
...@@ -66,7 +66,6 @@ Created 10/8/1995 Heikki Tuuri ...@@ -66,7 +66,6 @@ Created 10/8/1995 Heikki Tuuri
#include "mem0mem.h" #include "mem0mem.h"
#include "mem0pool.h" #include "mem0pool.h"
#include "sync0sync.h" #include "sync0sync.h"
#include "thr0loc.h"
#include "que0que.h" #include "que0que.h"
#include "log0recv.h" #include "log0recv.h"
#include "pars0pars.h" #include "pars0pars.h"
...@@ -1129,7 +1128,6 @@ srv_general_init(void) ...@@ -1129,7 +1128,6 @@ srv_general_init(void)
os_sync_init(); os_sync_init();
sync_init(); sync_init();
mem_init(srv_mem_pool_size); mem_init(srv_mem_pool_size);
thr_local_init();
} }
/*======================= InnoDB Server FIFO queue =======================*/ /*======================= InnoDB Server FIFO queue =======================*/
...@@ -3071,8 +3069,6 @@ suspend_thread: ...@@ -3071,8 +3069,6 @@ suspend_thread:
main thread goes back to loop. */ main thread goes back to loop. */
goto loop; goto loop;
OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
} }
/*********************************************************************//** /*********************************************************************//**
......
...@@ -85,7 +85,6 @@ Created 2/16/1996 Heikki Tuuri ...@@ -85,7 +85,6 @@ Created 2/16/1996 Heikki Tuuri
# include "row0row.h" # include "row0row.h"
# include "row0mysql.h" # include "row0mysql.h"
# include "btr0pcur.h" # include "btr0pcur.h"
# include "thr0loc.h"
# include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */ # include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
# include "zlib.h" /* for ZLIB_VERSION */ # include "zlib.h" /* for ZLIB_VERSION */
...@@ -2210,7 +2209,6 @@ innobase_shutdown_for_mysql(void) ...@@ -2210,7 +2209,6 @@ innobase_shutdown_for_mysql(void)
ibuf_close(); ibuf_close();
log_shutdown(); log_shutdown();
lock_sys_close(); lock_sys_close();
thr_local_close();
trx_sys_file_format_close(); trx_sys_file_format_close();
trx_sys_close(); trx_sys_close();
......
/*****************************************************************************
Copyright (c) 1995, 2009, Innobase Oy. 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., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/**************************************************//**
@file thr/thr0loc.c
The thread local storage
Created 10/5/1995 Heikki Tuuri
*******************************************************/
#include "thr0loc.h"
#ifdef UNIV_NONINL
#include "thr0loc.ic"
#endif
#include "sync0sync.h"
#include "hash0hash.h"
#include "mem0mem.h"
#include "srv0srv.h"
/*
IMPLEMENTATION OF THREAD LOCAL STORAGE
======================================
The threads sometimes need private data which depends on the thread id.
This is implemented as a hash table, where the hash value is calculated
from the thread id, to prepare for a large number of threads. The hash table
is protected by a mutex. If you need modify the program and put new data to
the thread local storage, just add it to struct thr_local_struct in the
header file. */
/** Mutex protecting thr_local_hash */
static mutex_t thr_local_mutex;
/** The hash table. The module is not yet initialized when it is NULL. */
static hash_table_t* thr_local_hash = NULL;
/** Thread local data */
typedef struct thr_local_struct thr_local_t;
#ifdef UNIV_PFS_MUTEX
/* Key to register the mutex with performance schema */
UNIV_INTERN mysql_pfs_key_t thr_local_mutex_key;
#endif /* UNIV_PFS_MUTEX */
/** @brief Thread local data.
The private data for each thread should be put to
the structure below and the accessor functions written
for the field. */
struct thr_local_struct{
os_thread_id_t id; /*!< id of the thread which owns this struct */
os_thread_t handle; /*!< operating system handle to the thread */
ibool in_ibuf;/*!< TRUE if the thread is doing an ibuf
operation */
hash_node_t hash; /*!< hash chain node */
ulint magic_n;/*!< magic number (THR_LOCAL_MAGIC_N) */
};
/** The value of thr_local_struct::magic_n */
#define THR_LOCAL_MAGIC_N 1231234
#ifdef UNIV_DEBUG
/*******************************************************************//**
Validates thread local data.
@return TRUE if valid */
static
ibool
thr_local_validate(
/*===============*/
const thr_local_t* local) /*!< in: data to validate */
{
ut_ad(local->magic_n == THR_LOCAL_MAGIC_N);
ut_ad(local->in_ibuf == FALSE || local->in_ibuf == TRUE);
return(TRUE);
}
#endif /* UNIV_DEBUG */
/*******************************************************************//**
Returns the local storage struct for a thread.
@return local storage */
static
thr_local_t*
thr_local_get(
/*==========*/
os_thread_id_t id) /*!< in: thread id of the thread */
{
thr_local_t* local;
try_again:
ut_ad(thr_local_hash);
ut_ad(mutex_own(&thr_local_mutex));
/* Look for the local struct in the hash table */
local = NULL;
HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id),
thr_local_t*, local, ut_ad(thr_local_validate(local)),
os_thread_eq(local->id, id));
if (local == NULL) {
mutex_exit(&thr_local_mutex);
thr_local_create();
mutex_enter(&thr_local_mutex);
goto try_again;
}
ut_ad(thr_local_validate(local));
return(local);
}
/*******************************************************************//**
Returns pointer to the 'in_ibuf' field within the current thread local
storage.
@return pointer to the in_ibuf field */
UNIV_INTERN
ibool*
thr_local_get_in_ibuf_field(void)
/*=============================*/
{
thr_local_t* local;
mutex_enter(&thr_local_mutex);
local = thr_local_get(os_thread_get_curr_id());
mutex_exit(&thr_local_mutex);
return(&(local->in_ibuf));
}
/*******************************************************************//**
Creates a local storage struct for the calling new thread. */
UNIV_INTERN
void
thr_local_create(void)
/*==================*/
{
thr_local_t* local;
if (thr_local_hash == NULL) {
thr_local_init();
}
local = mem_alloc(sizeof(thr_local_t));
local->id = os_thread_get_curr_id();
local->handle = os_thread_get_curr();
local->magic_n = THR_LOCAL_MAGIC_N;
local->in_ibuf = FALSE;
mutex_enter(&thr_local_mutex);
HASH_INSERT(thr_local_t, hash, thr_local_hash,
os_thread_pf(os_thread_get_curr_id()),
local);
mutex_exit(&thr_local_mutex);
}
/*******************************************************************//**
Frees the local storage struct for the specified thread. */
UNIV_INTERN
void
thr_local_free(
/*===========*/
os_thread_id_t id) /*!< in: thread id */
{
thr_local_t* local;
mutex_enter(&thr_local_mutex);
/* Look for the local struct in the hash table */
HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id),
thr_local_t*, local, ut_ad(thr_local_validate(local)),
os_thread_eq(local->id, id));
if (local == NULL) {
mutex_exit(&thr_local_mutex);
return;
}
HASH_DELETE(thr_local_t, hash, thr_local_hash,
os_thread_pf(id), local);
mutex_exit(&thr_local_mutex);
ut_a(local->magic_n == THR_LOCAL_MAGIC_N);
ut_ad(thr_local_validate(local));
mem_free(local);
}
/****************************************************************//**
Initializes the thread local storage module. */
UNIV_INTERN
void
thr_local_init(void)
/*================*/
{
ut_a(thr_local_hash == NULL);
thr_local_hash = hash_create(OS_THREAD_MAX_N + 100);
mutex_create(thr_local_mutex_key,
&thr_local_mutex, SYNC_THR_LOCAL);
}
/********************************************************************
Close the thread local storage module. */
UNIV_INTERN
void
thr_local_close(void)
/*=================*/
{
ulint i;
ut_a(thr_local_hash != NULL);
/* Free the hash elements. We don't remove them from the table
because we are going to destroy the table anyway. */
for (i = 0; i < hash_get_n_cells(thr_local_hash); i++) {
thr_local_t* local;
local = HASH_GET_FIRST(thr_local_hash, i);
while (local) {
thr_local_t* prev_local = local;
local = HASH_GET_NEXT(hash, prev_local);
ut_a(prev_local->magic_n == THR_LOCAL_MAGIC_N);
ut_ad(thr_local_validate(prev_local));
mem_free(prev_local);
}
}
hash_table_free(thr_local_hash);
thr_local_hash = NULL;
}
...@@ -38,7 +38,6 @@ Created 3/26/1996 Heikki Tuuri ...@@ -38,7 +38,6 @@ Created 3/26/1996 Heikki Tuuri
#include "usr0sess.h" #include "usr0sess.h"
#include "read0read.h" #include "read0read.h"
#include "srv0srv.h" #include "srv0srv.h"
#include "thr0loc.h"
#include "btr0sea.h" #include "btr0sea.h"
#include "os0proc.h" #include "os0proc.h"
#include "trx0xa.h" #include "trx0xa.h"
......
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