mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 11:27:39 +02:00
Merge 10.2 into 10.3
This commit is contained in:
commit
a8de8f261d
122 changed files with 19102 additions and 2557 deletions
|
|
@ -29,6 +29,7 @@ Created 2/23/1996 Heikki Tuuri
|
|||
|
||||
#include "dict0dict.h"
|
||||
#include "btr0cur.h"
|
||||
#include "buf0block_hint.h"
|
||||
#include "btr0btr.h"
|
||||
#include "gis0rtree.h"
|
||||
|
||||
|
|
@ -502,13 +503,10 @@ struct btr_pcur_t{
|
|||
whether cursor was on, before, or after the old_rec record */
|
||||
enum btr_pcur_pos_t rel_pos;
|
||||
/** buffer block when the position was stored */
|
||||
buf_block_t* block_when_stored;
|
||||
buf::Block_hint block_when_stored;
|
||||
/** the modify clock value of the buffer block when the cursor position
|
||||
was stored */
|
||||
ib_uint64_t modify_clock;
|
||||
/** the withdraw clock value of the buffer pool when the cursor
|
||||
position was stored */
|
||||
ulint withdraw_clock;
|
||||
/** btr_pcur_store_position() and btr_pcur_restore_position() state. */
|
||||
enum pcur_pos_t pos_state;
|
||||
/** PAGE_CUR_G, ... */
|
||||
|
|
@ -528,9 +526,8 @@ struct btr_pcur_t{
|
|||
btr_pcur_t() :
|
||||
btr_cur(), latch_mode(0), old_stored(false), old_rec(NULL),
|
||||
old_n_fields(0), rel_pos(btr_pcur_pos_t(0)),
|
||||
block_when_stored(NULL),
|
||||
modify_clock(0), withdraw_clock(0),
|
||||
pos_state(BTR_PCUR_NOT_POSITIONED),
|
||||
block_when_stored(),
|
||||
modify_clock(0), pos_state(BTR_PCUR_NOT_POSITIONED),
|
||||
search_mode(PAGE_CUR_UNSUPP), trx_if_known(NULL),
|
||||
old_rec_buf(NULL), buf_size(0)
|
||||
{
|
||||
|
|
|
|||
77
storage/innobase/include/buf0block_hint.h
Normal file
77
storage/innobase/include/buf0block_hint.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2020, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 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, version 2.0, as published by the
|
||||
Free Software Foundation.
|
||||
|
||||
This program is also distributed with certain software (including but not
|
||||
limited to OpenSSL) that is licensed under separate terms, as designated in a
|
||||
particular file or component or in included license documentation. The authors
|
||||
of MySQL hereby grant you an additional permission to link the program and
|
||||
your derivative works with the separately licensed software that they have
|
||||
included with MySQL.
|
||||
|
||||
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, version 2.0,
|
||||
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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*****************************************************************************/
|
||||
#pragma once
|
||||
#include "buf0buf.h"
|
||||
|
||||
namespace buf {
|
||||
class Block_hint {
|
||||
public:
|
||||
Block_hint():m_block(NULL),m_page_id(0,0) {}
|
||||
/** Stores the pointer to the block, which is currently buffer-fixed.
|
||||
@param block a pointer to a buffer-fixed block to be stored */
|
||||
inline void store(buf_block_t *block)
|
||||
{
|
||||
ut_ad(block->page.buf_fix_count);
|
||||
m_block= block;
|
||||
m_page_id= block->page.id;
|
||||
}
|
||||
|
||||
/** Clears currently stored pointer. */
|
||||
inline void clear() { m_block= NULL; }
|
||||
|
||||
/** Invoke f on m_block(which may be null)
|
||||
@param f The function to be executed. It will be passed the pointer.
|
||||
If you wish to use the block pointer subsequently,
|
||||
you need to ensure you buffer-fix it before returning from f.
|
||||
@return the return value of f
|
||||
*/
|
||||
template <typename F>
|
||||
bool run_with_hint(const F &f)
|
||||
{
|
||||
buffer_fix_block_if_still_valid();
|
||||
/* m_block could be changed during f() call, so we use local
|
||||
variable to remember which block we need to unfix */
|
||||
buf_block_t *block= m_block;
|
||||
bool res= f(block);
|
||||
if (block)
|
||||
buf_block_buf_fix_dec(block);
|
||||
return res;
|
||||
}
|
||||
|
||||
buf_block_t *block() const { return m_block; }
|
||||
|
||||
private:
|
||||
/** The block pointer stored by store(). */
|
||||
buf_block_t *m_block;
|
||||
/** If m_block is non-null, the m_block->page.id at time it was stored. */
|
||||
page_id_t m_page_id;
|
||||
|
||||
/** A helper function which checks if m_block is not a dangling pointer and
|
||||
still points to block with page with m_page_id and if so, buffer-fixes it,
|
||||
otherwise clear()s it */
|
||||
void buffer_fix_block_if_still_valid();
|
||||
};
|
||||
} // namespace buf
|
||||
|
|
@ -101,10 +101,6 @@ extern buf_pool_t* buf_pool_ptr; /*!< The buffer pools
|
|||
extern volatile bool buf_pool_withdrawing; /*!< true when withdrawing buffer
|
||||
pool pages might cause page relocation */
|
||||
|
||||
extern volatile ulint buf_withdraw_clock; /*!< the clock is incremented
|
||||
every time a pointer to a page may
|
||||
become obsolete */
|
||||
|
||||
# ifdef UNIV_DEBUG
|
||||
extern my_bool buf_disable_resize_buffer_pool_debug; /*!< if TRUE, resizing
|
||||
buffer pool is not allowed. */
|
||||
|
|
@ -1373,14 +1369,6 @@ buf_get_nth_chunk_block(
|
|||
ulint n, /*!< in: nth chunk in the buffer pool */
|
||||
ulint* chunk_size); /*!< in: chunk size */
|
||||
|
||||
/** Verify the possibility that a stored page is not in buffer pool.
|
||||
@param[in] withdraw_clock withdraw clock when stored the page
|
||||
@retval true if the page might be relocated */
|
||||
UNIV_INLINE
|
||||
bool
|
||||
buf_pool_is_obsolete(
|
||||
ulint withdraw_clock);
|
||||
|
||||
/** Calculate aligned buffer pool size based on srv_buf_pool_chunk_unit,
|
||||
if needed.
|
||||
@param[in] size size in bytes
|
||||
|
|
@ -2207,6 +2195,11 @@ struct buf_pool_t{
|
|||
buf_tmp_array_t* tmp_arr;
|
||||
/*!< Array for temporal memory
|
||||
used in compression and encryption */
|
||||
/** Determine if a pointer belongs to a buf_block_t.
|
||||
It can be a pointer to the buf_block_t itself or a member of it.
|
||||
@param ptr a pointer that will not be dereferenced
|
||||
@return whether the ptr belongs to a buf_block_t struct */
|
||||
inline bool is_block_field(const void *ptr) const;
|
||||
|
||||
#if BUF_BUDDY_LOW > UNIV_ZIP_SIZE_MIN
|
||||
# error "BUF_BUDDY_LOW > UNIV_ZIP_SIZE_MIN"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2008, Google Inc.
|
||||
Copyright (c) 2014, 2019, MariaDB Corporation.
|
||||
Copyright (c) 2014, 2020, MariaDB Corporation.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
Google, Inc. Those modifications are gratefully acknowledged and are described
|
||||
|
|
@ -54,6 +54,25 @@ struct buf_chunk_t{
|
|||
}
|
||||
};
|
||||
|
||||
bool buf_pool_t::is_block_field(const void *ptr) const
|
||||
{
|
||||
const buf_chunk_t* chunk= chunks;
|
||||
const buf_chunk_t *const echunk= chunk + ut_min(n_chunks,
|
||||
n_chunks_new);
|
||||
/* TODO: protect chunks with a mutex (the older pointer will
|
||||
currently remain during resize()) */
|
||||
while (chunk < echunk)
|
||||
{
|
||||
if (ptr >= reinterpret_cast<const void*>(chunk->blocks) &&
|
||||
ptr < reinterpret_cast<const void*>(
|
||||
chunk->blocks + chunk->size))
|
||||
return true;
|
||||
chunk++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Gets the current size of buffer buf_pool in bytes.
|
||||
@return size in bytes */
|
||||
|
|
@ -1056,8 +1075,6 @@ buf_block_buf_fix_dec(
|
|||
/*==================*/
|
||||
buf_block_t* block) /*!< in/out: block to bufferunfix */
|
||||
{
|
||||
buf_block_unfix(block);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/* No debug latch is acquired if block belongs to system temporary.
|
||||
Debug latch is not of much help if access to block is single
|
||||
|
|
@ -1066,6 +1083,8 @@ buf_block_buf_fix_dec(
|
|||
rw_lock_s_unlock(&block->debug_latch);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
buf_block_unfix(block);
|
||||
}
|
||||
|
||||
/** Returns the buffer pool instance given a page id.
|
||||
|
|
@ -1439,18 +1458,6 @@ buf_page_get_frame(
|
|||
}
|
||||
}
|
||||
|
||||
/** Verify the possibility that a stored page is not in buffer pool.
|
||||
@param[in] withdraw_clock withdraw clock when stored the page
|
||||
@retval true if the page might be relocated */
|
||||
UNIV_INLINE
|
||||
bool
|
||||
buf_pool_is_obsolete(
|
||||
ulint withdraw_clock)
|
||||
{
|
||||
return(UNIV_UNLIKELY(buf_pool_withdrawing
|
||||
|| buf_withdraw_clock != withdraw_clock));
|
||||
}
|
||||
|
||||
/** Calculate aligned buffer pool size based on srv_buf_pool_chunk_unit,
|
||||
if needed.
|
||||
@param[in] size size in bytes
|
||||
|
|
|
|||
|
|
@ -302,7 +302,7 @@ UNIV_INLINE
|
|||
void
|
||||
dict_table_autoinc_initialize(dict_table_t* table, ib_uint64_t value)
|
||||
{
|
||||
ut_ad(dict_table_autoinc_own(table));
|
||||
mysql_mutex_assert_owner(&table->autoinc_mutex);
|
||||
table->autoinc = value;
|
||||
}
|
||||
|
||||
|
|
@ -315,7 +315,7 @@ UNIV_INLINE
|
|||
ib_uint64_t
|
||||
dict_table_autoinc_read(const dict_table_t* table)
|
||||
{
|
||||
ut_ad(dict_table_autoinc_own(table));
|
||||
mysql_mutex_assert_owner(&table->autoinc_mutex);
|
||||
return(table->autoinc);
|
||||
}
|
||||
|
||||
|
|
@ -329,7 +329,7 @@ UNIV_INLINE
|
|||
bool
|
||||
dict_table_autoinc_update_if_greater(dict_table_t* table, ib_uint64_t value)
|
||||
{
|
||||
ut_ad(dict_table_autoinc_own(table));
|
||||
mysql_mutex_assert_owner(&table->autoinc_mutex);
|
||||
|
||||
if (value > table->autoinc) {
|
||||
|
||||
|
|
@ -1468,25 +1468,6 @@ void
|
|||
dict_mutex_exit_for_mysql(void);
|
||||
/*===========================*/
|
||||
|
||||
/** Create a dict_table_t's stats latch or delay for lazy creation.
|
||||
This function is only called from either single threaded environment
|
||||
or from a thread that has not shared the table object with other threads.
|
||||
@param[in,out] table table whose stats latch to create
|
||||
@param[in] enabled if false then the latch is disabled
|
||||
and dict_table_stats_lock()/unlock() become noop on this table. */
|
||||
void
|
||||
dict_table_stats_latch_create(
|
||||
dict_table_t* table,
|
||||
bool enabled);
|
||||
|
||||
/** Destroy a dict_table_t's stats latch.
|
||||
This function is only called from either single threaded environment
|
||||
or from a thread that has not shared the table object with other threads.
|
||||
@param[in,out] table table whose stats latch to destroy */
|
||||
void
|
||||
dict_table_stats_latch_destroy(
|
||||
dict_table_t* table);
|
||||
|
||||
/** Lock the appropriate latch to protect a given table's statistics.
|
||||
@param[in] table table whose stats to lock
|
||||
@param[in] latch_mode RW_S_LATCH or RW_X_LATCH */
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ Created 1/8/1996 Heikki Tuuri
|
|||
#include "fts0fts.h"
|
||||
#include "buf0buf.h"
|
||||
#include "gis0type.h"
|
||||
#include "os0once.h"
|
||||
#include "fil0fil.h"
|
||||
#include "fil0crypt.h"
|
||||
#include <set>
|
||||
|
|
@ -296,20 +295,25 @@ parent table will fail, and user has to drop excessive foreign constraint
|
|||
before proceeds. */
|
||||
#define FK_MAX_CASCADE_DEL 15
|
||||
|
||||
/**********************************************************************//**
|
||||
Creates a table memory object.
|
||||
/** Create a table memory object.
|
||||
@param name table name
|
||||
@param space tablespace
|
||||
@param n_cols total number of columns (both virtual and non-virtual)
|
||||
@param n_v_cols number of virtual columns
|
||||
@param flags table flags
|
||||
@param flags2 table flags2
|
||||
@param init_stats_latch whether to init the stats latch
|
||||
@return own: table object */
|
||||
dict_table_t*
|
||||
dict_mem_table_create(
|
||||
/*==================*/
|
||||
const char* name, /*!< in: table name */
|
||||
fil_space_t* space, /*!< in: tablespace */
|
||||
ulint n_cols, /*!< in: total number of columns
|
||||
including virtual and non-virtual
|
||||
columns */
|
||||
ulint n_v_cols, /*!< in: number of virtual columns */
|
||||
ulint flags, /*!< in: table flags */
|
||||
ulint flags2); /*!< in: table flags2 */
|
||||
const char* name,
|
||||
fil_space_t* space,
|
||||
ulint n_cols,
|
||||
ulint n_v_cols,
|
||||
ulint flags,
|
||||
ulint flags2,
|
||||
bool init_stats_latch=true);
|
||||
|
||||
/****************************************************************//**
|
||||
Free a table memory object. */
|
||||
void
|
||||
|
|
@ -812,7 +816,7 @@ extern ulong zip_pad_max;
|
|||
an uncompressed page should be left as padding to avoid compression
|
||||
failures. This estimate is based on a self-adapting heuristic. */
|
||||
struct zip_pad_info_t {
|
||||
SysMutex* mutex; /*!< mutex protecting the info */
|
||||
mysql_mutex_t mutex; /*!< mutex protecting the info */
|
||||
ulint pad; /*!< number of bytes used as pad */
|
||||
ulint success;/*!< successful compression ops during
|
||||
current round */
|
||||
|
|
@ -820,9 +824,6 @@ struct zip_pad_info_t {
|
|||
current round */
|
||||
ulint n_rounds;/*!< number of currently successful
|
||||
rounds */
|
||||
volatile os_once::state_t
|
||||
mutex_created;
|
||||
/*!< Creation state of mutex member */
|
||||
};
|
||||
|
||||
/** Number of samples of data size kept when page compression fails for
|
||||
|
|
@ -1864,7 +1865,7 @@ struct dict_table_t {
|
|||
/** Statistics for query optimization. @{ */
|
||||
|
||||
/** Creation state of 'stats_latch'. */
|
||||
volatile os_once::state_t stats_latch_created;
|
||||
bool stats_latch_inited;
|
||||
|
||||
/** This latch protects:
|
||||
dict_table_t::stat_initialized,
|
||||
|
|
@ -1877,7 +1878,7 @@ struct dict_table_t {
|
|||
dict_table_t::indexes*::stat_n_leaf_pages.
|
||||
(*) Those are not always protected for
|
||||
performance reasons. */
|
||||
rw_lock_t* stats_latch;
|
||||
rw_lock_t stats_latch;
|
||||
|
||||
/** TRUE if statistics have been calculated the first time after
|
||||
database startup or table creation. */
|
||||
|
|
@ -2001,11 +2002,8 @@ struct dict_table_t {
|
|||
from a select. */
|
||||
lock_t* autoinc_lock;
|
||||
|
||||
/** Creation state of autoinc_mutex member */
|
||||
volatile os_once::state_t autoinc_mutex_created;
|
||||
|
||||
/** Mutex protecting the autoincrement counter. */
|
||||
ib_mutex_t* autoinc_mutex;
|
||||
mysql_mutex_t autoinc_mutex;
|
||||
|
||||
/** Autoinc counter value to give to the next inserted row. */
|
||||
ib_uint64_t autoinc;
|
||||
|
|
@ -2112,64 +2110,6 @@ struct dict_foreign_add_to_referenced_table {
|
|||
}
|
||||
};
|
||||
|
||||
/** Destroy the autoinc latch of the given table.
|
||||
This function is only called from either single threaded environment
|
||||
or from a thread that has not shared the table object with other threads.
|
||||
@param[in,out] table table whose stats latch to destroy */
|
||||
inline
|
||||
void
|
||||
dict_table_autoinc_destroy(
|
||||
dict_table_t* table)
|
||||
{
|
||||
if (table->autoinc_mutex_created == os_once::DONE
|
||||
&& table->autoinc_mutex != NULL) {
|
||||
mutex_free(table->autoinc_mutex);
|
||||
UT_DELETE(table->autoinc_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/** Request for lazy creation of the autoinc latch of a given table.
|
||||
This function is only called from either single threaded environment
|
||||
or from a thread that has not shared the table object with other threads.
|
||||
@param[in,out] table table whose autoinc latch is to be created. */
|
||||
inline
|
||||
void
|
||||
dict_table_autoinc_create_lazy(
|
||||
dict_table_t* table)
|
||||
{
|
||||
table->autoinc_mutex = NULL;
|
||||
table->autoinc_mutex_created = os_once::NEVER_DONE;
|
||||
}
|
||||
|
||||
/** Request a lazy creation of dict_index_t::zip_pad::mutex.
|
||||
This function is only called from either single threaded environment
|
||||
or from a thread that has not shared the table object with other threads.
|
||||
@param[in,out] index index whose zip_pad mutex is to be created */
|
||||
inline
|
||||
void
|
||||
dict_index_zip_pad_mutex_create_lazy(
|
||||
dict_index_t* index)
|
||||
{
|
||||
index->zip_pad.mutex = NULL;
|
||||
index->zip_pad.mutex_created = os_once::NEVER_DONE;
|
||||
}
|
||||
|
||||
/** Destroy the zip_pad_mutex of the given index.
|
||||
This function is only called from either single threaded environment
|
||||
or from a thread that has not shared the table object with other threads.
|
||||
@param[in,out] table table whose stats latch to destroy */
|
||||
inline
|
||||
void
|
||||
dict_index_zip_pad_mutex_destroy(
|
||||
dict_index_t* index)
|
||||
{
|
||||
if (index->zip_pad.mutex_created == os_once::DONE
|
||||
&& index->zip_pad.mutex != NULL) {
|
||||
mutex_free(index->zip_pad.mutex);
|
||||
UT_DELETE(index->zip_pad.mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/** Release the zip_pad_mutex of a given index.
|
||||
@param[in,out] index index whose zip_pad_mutex is to be released */
|
||||
inline
|
||||
|
|
@ -2177,22 +2117,9 @@ void
|
|||
dict_index_zip_pad_unlock(
|
||||
dict_index_t* index)
|
||||
{
|
||||
mutex_exit(index->zip_pad.mutex);
|
||||
mysql_mutex_unlock(&index->zip_pad.mutex);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/** Check if the current thread owns the autoinc_mutex of a given table.
|
||||
@param[in] table the autoinc_mutex belongs to this table
|
||||
@return true, if the current thread owns the autoinc_mutex, false otherwise.*/
|
||||
inline
|
||||
bool
|
||||
dict_table_autoinc_own(
|
||||
const dict_table_t* table)
|
||||
{
|
||||
return(mutex_own(table->autoinc_mutex));
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
/** Check whether the col is used in spatial index or regular index.
|
||||
@param[in] col column to check
|
||||
@return spatial status */
|
||||
|
|
|
|||
|
|
@ -170,10 +170,10 @@ mtr_t::release_block_at_savepoint(
|
|||
|
||||
ut_a(slot->object == block);
|
||||
|
||||
buf_block_unfix(reinterpret_cast<buf_block_t*>(block));
|
||||
|
||||
buf_page_release_latch(block, slot->type);
|
||||
|
||||
buf_block_unfix(reinterpret_cast<buf_block_t*>(block));
|
||||
|
||||
slot->object = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,120 +0,0 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 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/os0once.h
|
||||
A class that aids executing a given function exactly once in a multi-threaded
|
||||
environment.
|
||||
|
||||
Created Feb 20, 2014 Vasil Dimov
|
||||
*******************************************************/
|
||||
|
||||
#ifndef os0once_h
|
||||
#define os0once_h
|
||||
|
||||
#include "univ.i"
|
||||
|
||||
#include "ut0ut.h"
|
||||
#include "my_cpu.h"
|
||||
|
||||
/** Execute a given function exactly once in a multi-threaded environment
|
||||
or wait for the function to be executed by another thread.
|
||||
|
||||
Example usage:
|
||||
First the user must create a control variable of type os_once::state_t and
|
||||
assign it os_once::NEVER_DONE.
|
||||
Then the user must pass this variable, together with a function to be
|
||||
executed to os_once::do_or_wait_for_done().
|
||||
|
||||
Multiple threads can call os_once::do_or_wait_for_done() simultaneously with
|
||||
the same (os_once::state_t) control variable. The provided function will be
|
||||
called exactly once and when os_once::do_or_wait_for_done() returns then this
|
||||
function has completed execution, by this or another thread. In other words
|
||||
os_once::do_or_wait_for_done() will either execute the provided function or
|
||||
will wait for its execution to complete if it is already called by another
|
||||
thread or will do nothing if the function has already completed its execution
|
||||
earlier.
|
||||
|
||||
This mimics pthread_once(3), but unfortunatelly pthread_once(3) does not
|
||||
support passing arguments to the init_routine() function. We should use
|
||||
std::call_once() when we start compiling with C++11 enabled. */
|
||||
class os_once {
|
||||
public:
|
||||
/** Control variables' state type */
|
||||
typedef ib_uint32_t state_t;
|
||||
|
||||
/** Not yet executed. */
|
||||
static const state_t NEVER_DONE = 0;
|
||||
|
||||
/** Currently being executed by this or another thread. */
|
||||
static const state_t IN_PROGRESS = 1;
|
||||
|
||||
/** Finished execution. */
|
||||
static const state_t DONE = 2;
|
||||
|
||||
/** Call a given function or wait its execution to complete if it is
|
||||
already called by another thread.
|
||||
@param[in,out] state control variable
|
||||
@param[in] do_func function to call
|
||||
@param[in,out] do_func_arg an argument to pass to do_func(). */
|
||||
static
|
||||
void
|
||||
do_or_wait_for_done(
|
||||
volatile state_t* state,
|
||||
void (*do_func)(void*),
|
||||
void* do_func_arg)
|
||||
{
|
||||
int32 oldval = NEVER_DONE;
|
||||
|
||||
/* Avoid calling my_atomic_cas32() in the most common case. */
|
||||
if (*state == DONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (my_atomic_cas32((int32*) state, &oldval, IN_PROGRESS)) {
|
||||
/* We are the first. Call the function. */
|
||||
|
||||
do_func(do_func_arg);
|
||||
|
||||
my_atomic_store32((int32*) state, DONE);
|
||||
} else {
|
||||
/* The state is not NEVER_DONE, so either it is
|
||||
IN_PROGRESS (somebody is calling the function right
|
||||
now or DONE (it has already been called and completed).
|
||||
Wait for it to become DONE. */
|
||||
for (;;) {
|
||||
const state_t s = *state;
|
||||
|
||||
switch (s) {
|
||||
case DONE:
|
||||
return;
|
||||
case IN_PROGRESS:
|
||||
break;
|
||||
case NEVER_DONE:
|
||||
/* fall through */
|
||||
default:
|
||||
ut_error;
|
||||
}
|
||||
|
||||
MY_RELAX_CPU();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* os0once_h */
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, 2019, MariaDB Corporation.
|
||||
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
|
||||
|
|
@ -1119,7 +1119,7 @@ public:
|
|||
}
|
||||
|
||||
/** @return number of committed transactions waiting for purge */
|
||||
ulint history_size() const
|
||||
uint32 history_size() const
|
||||
{
|
||||
return uint32(my_atomic_load32(&const_cast<trx_sys_t*>(this)
|
||||
->rseg_history_len));
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, 2018, MariaDB Corporation.
|
||||
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
|
||||
|
|
@ -366,8 +366,6 @@ struct trx_undo_t {
|
|||
(IB_ID_MAX if the undo log is empty) */
|
||||
buf_block_t* guess_block; /*!< guess for the buffer block where
|
||||
the top page might reside */
|
||||
ulint withdraw_clock; /*!< the withdraw clock value of the
|
||||
buffer pool when guess_block was stored */
|
||||
|
||||
/** @return whether the undo log is empty */
|
||||
bool empty() const { return top_undo_no == IB_ID_MAX; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue