diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2016-08-12 11:17:45 +0300 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2016-09-02 13:22:28 +0300 |
commit | 2e814d4702d71a04388386a9f591d14a35980bfe (patch) | |
tree | f3f9b48d116a3738c5e71f3a360ca61f16cfb632 /storage/innobase/include/mem0mem.ic | |
parent | 848d211c5c4df00b819cd84d7530cf7d29bb0524 (diff) | |
download | mariadb-git-2e814d4702d71a04388386a9f591d14a35980bfe.tar.gz |
Merge InnoDB 5.7 from mysql-5.7.9.
Contains also
MDEV-10547: Test multi_update_innodb fails with InnoDB 5.7
The failure happened because 5.7 has changed the signature of
the bool handler::primary_key_is_clustered() const
virtual function ("const" was added). InnoDB was using the old
signature which caused the function not to be used.
MDEV-10550: Parallel replication lock waits/deadlock handling does not work with InnoDB 5.7
Fixed mutexing problem on lock_trx_handle_wait. Note that
rpl_parallel and rpl_optimistic_parallel tests still
fail.
MDEV-10156 : Group commit tests fail on 10.2 InnoDB (branch bb-10.2-jan)
Reason: incorrect merge
MDEV-10550: Parallel replication can't sync with master in InnoDB 5.7 (branch bb-10.2-jan)
Reason: incorrect merge
Diffstat (limited to 'storage/innobase/include/mem0mem.ic')
-rw-r--r-- | storage/innobase/include/mem0mem.ic | 408 |
1 files changed, 185 insertions, 223 deletions
diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic index 63e68150b61..d20a1647654 100644 --- a/storage/innobase/include/mem0mem.ic +++ b/storage/innobase/include/mem0mem.ic @@ -23,10 +23,7 @@ The memory management Created 6/8/1994 Heikki Tuuri *************************************************************************/ -#include "mem0dbg.ic" -#ifndef UNIV_HOTBACKUP -# include "mem0pool.h" -#endif /* !UNIV_HOTBACKUP */ +#include "ut0new.h" #ifdef UNIV_DEBUG # define mem_heap_create_block(heap, n, type, file_name, line) \ @@ -43,7 +40,6 @@ Created 6/8/1994 Heikki Tuuri Creates a memory heap block where data can be allocated. @return own: memory heap block, NULL if did not succeed (only possible for MEM_HEAP_BTR_SEARCH type heaps) */ -UNIV_INTERN mem_block_t* mem_heap_create_block_func( /*=======================*/ @@ -56,33 +52,34 @@ mem_heap_create_block_func( #endif /* UNIV_DEBUG */ ulint type); /*!< in: type of heap: MEM_HEAP_DYNAMIC or MEM_HEAP_BUFFER */ + /******************************************************************//** Frees a block from a memory heap. */ -UNIV_INTERN void mem_heap_block_free( /*================*/ mem_heap_t* heap, /*!< in: heap */ mem_block_t* block); /*!< in: block to free */ + #ifndef UNIV_HOTBACKUP /******************************************************************//** Frees the free_block field from a memory heap. */ -UNIV_INTERN void mem_heap_free_block_free( /*=====================*/ mem_heap_t* heap); /*!< in: heap */ #endif /* !UNIV_HOTBACKUP */ + /***************************************************************//** Adds a new block to a memory heap. +@param[in] heap memory heap +@param[in] n number of bytes needed @return created block, NULL if did not succeed (only possible for MEM_HEAP_BTR_SEARCH type heaps) */ -UNIV_INTERN mem_block_t* mem_heap_add_block( -/*===============*/ - mem_heap_t* heap, /*!< in: memory heap */ - ulint n); /*!< in: number of bytes user needs */ + mem_heap_t* heap, + ulint n); UNIV_INLINE void @@ -150,41 +147,49 @@ mem_block_get_start(mem_block_t* block) return(block->start); } -/***************************************************************//** -Allocates and zero-fills n bytes of memory from a memory heap. -@return allocated, zero-filled storage */ +/** Checks that an object is a memory heap block +@param[in] block Memory block to check. */ +UNIV_INLINE +void +mem_block_validate( + const mem_block_t* block) +{ + ut_a(block->magic_n == MEM_BLOCK_MAGIC_N); +} + +/** Allocates and zero-fills n bytes of memory from a memory heap. +@param[in] heap memory heap +@param[in] n number of bytes; if the heap is allowed to grow into +the buffer pool, this must be <= MEM_MAX_ALLOC_IN_BUF +@return allocated, zero-filled storage */ UNIV_INLINE void* mem_heap_zalloc( -/*============*/ - mem_heap_t* heap, /*!< in: memory heap */ - ulint n) /*!< in: number of bytes; if the heap is allowed - to grow into the buffer pool, this must be - <= MEM_MAX_ALLOC_IN_BUF */ + mem_heap_t* heap, + ulint n) { ut_ad(heap); ut_ad(!(heap->type & MEM_HEAP_BTR_SEARCH)); return(memset(mem_heap_alloc(heap, n), 0, n)); } -/***************************************************************//** -Allocates n bytes of memory from a memory heap. +/** Allocates n bytes of memory from a memory heap. +@param[in] heap memory heap +@param[in] n number of bytes; if the heap is allowed to grow into +the buffer pool, this must be <= MEM_MAX_ALLOC_IN_BUF @return allocated storage, NULL if did not succeed (only possible for MEM_HEAP_BTR_SEARCH type heaps) */ UNIV_INLINE void* mem_heap_alloc( -/*===========*/ - mem_heap_t* heap, /*!< in: memory heap */ - ulint n) /*!< in: number of bytes; if the heap is allowed - to grow into the buffer pool, this must be - <= MEM_MAX_ALLOC_IN_BUF */ + mem_heap_t* heap, + ulint n) { mem_block_t* block; void* buf; ulint free; - ut_ad(mem_heap_check(heap)); + ut_d(mem_block_validate(heap)); block = UT_LIST_GET_LAST(heap->base); @@ -210,35 +215,22 @@ mem_heap_alloc( mem_block_set_free(block, free + MEM_SPACE_NEEDED(n)); -#ifdef UNIV_MEM_DEBUG - UNIV_MEM_ALLOC(buf, - n + MEM_FIELD_HEADER_SIZE + MEM_FIELD_TRAILER_SIZE); - - /* In the debug version write debugging info to the field */ - mem_field_init((byte*) buf, n); - - /* Advance buf to point at the storage which will be given to the - caller */ - buf = (byte*) buf + MEM_FIELD_HEADER_SIZE; - -#endif UNIV_MEM_ALLOC(buf, n); return(buf); } -/*****************************************************************//** -Returns a pointer to the heap top. -@return pointer to the heap top */ +/** Returns a pointer to the heap top. +@param[in] heap memory heap +@return pointer to the heap top */ UNIV_INLINE byte* mem_heap_get_heap_top( -/*==================*/ - mem_heap_t* heap) /*!< in: memory heap */ + mem_heap_t* heap) { mem_block_t* block; byte* buf; - ut_ad(mem_heap_check(heap)); + ut_d(mem_block_validate(heap)); block = UT_LIST_GET_LAST(heap->base); @@ -247,37 +239,21 @@ mem_heap_get_heap_top( return(buf); } -/*****************************************************************//** -Frees the space in a memory heap exceeding the pointer given. The -pointer must have been acquired from mem_heap_get_heap_top. The first -memory block of the heap is not freed. */ +/** Frees the space in a memory heap exceeding the pointer given. +The pointer must have been acquired from mem_heap_get_heap_top. +The first memory block of the heap is not freed. +@param[in] heap heap from which to free +@param[in] old_top pointer to old top of heap */ UNIV_INLINE void mem_heap_free_heap_top( -/*===================*/ - mem_heap_t* heap, /*!< in: heap from which to free */ - byte* old_top)/*!< in: pointer to old top of heap */ + mem_heap_t* heap, + byte* old_top) { mem_block_t* block; mem_block_t* prev_block; -#if defined UNIV_MEM_DEBUG || defined UNIV_DEBUG - ibool error; - ulint total_size; - ulint size; - - ut_ad(mem_heap_check(heap)); - - /* Validate the heap and get its total allocated size */ - mem_heap_validate_or_print(heap, NULL, FALSE, &error, &total_size, - NULL, NULL); - ut_a(!error); - /* Get the size below top pointer */ - mem_heap_validate_or_print(heap, old_top, FALSE, &error, &size, NULL, - NULL); - ut_a(!error); - -#endif + ut_d(mem_heap_validate(heap)); block = UT_LIST_GET_LAST(heap->base); @@ -306,15 +282,6 @@ mem_heap_free_heap_top( ut_ad(mem_block_get_start(block) <= mem_block_get_free(block)); UNIV_MEM_ASSERT_W(old_top, (byte*) block + block->len - old_top); -#if defined UNIV_MEM_DEBUG - /* In the debug version erase block from top up */ - mem_erase_buf(old_top, (byte*) block + block->len - old_top); - - /* Update allocated memory count */ - mutex_enter(&mem_hash_mutex); - mem_current_allocated_memory -= (total_size - size); - mutex_exit(&mem_hash_mutex); -#endif /* UNIV_MEM_DEBUG */ UNIV_MEM_ALLOC(old_top, (byte*) block + block->len - old_top); /* If free == start, we may free the block if it is not the first @@ -326,13 +293,13 @@ mem_heap_free_heap_top( } } -/*****************************************************************//** -Empties a memory heap. The first memory block of the heap is not freed. */ +/** Empties a memory heap. +The first memory block of the heap is not freed. +@param[in] heap heap to empty */ UNIV_INLINE void mem_heap_empty( -/*===========*/ - mem_heap_t* heap) /*!< in: heap to empty */ + mem_heap_t* heap) { mem_heap_free_heap_top(heap, (byte*) heap + mem_block_get_start(heap)); #ifndef UNIV_HOTBACKUP @@ -342,39 +309,123 @@ mem_heap_empty( #endif /* !UNIV_HOTBACKUP */ } -/*****************************************************************//** -Returns a pointer to the topmost element in a memory heap. The size of the -element must be given. -@return pointer to the topmost element */ +/** Returns a pointer to the topmost element in a memory heap. +The size of the element must be given. +@param[in] heap memory heap +@param[in] n size of the topmost element +@return pointer to the topmost element */ UNIV_INLINE void* mem_heap_get_top( -/*=============*/ - mem_heap_t* heap, /*!< in: memory heap */ - ulint n) /*!< in: size of the topmost element */ + mem_heap_t* heap, + ulint n) { mem_block_t* block; byte* buf; - ut_ad(mem_heap_check(heap)); + ut_d(mem_block_validate(heap)); block = UT_LIST_GET_LAST(heap->base); buf = (byte*) block + mem_block_get_free(block) - MEM_SPACE_NEEDED(n); -#ifdef UNIV_MEM_DEBUG - ut_ad(mem_block_get_start(block) <= (ulint) (buf - (byte*) block)); + return((void*) buf); +} - /* In the debug version, advance buf to point at the storage which - was given to the caller in the allocation*/ +/** Checks if a given chunk of memory is the topmost element stored in the +heap. If this is the case, then calling mem_heap_free_top() would free +that element from the heap. +@param[in] heap memory heap +@param[in] buf presumed topmost element +@param[in] buf_sz size of buf in bytes +@return true if topmost */ +UNIV_INLINE +bool +mem_heap_is_top( + mem_heap_t* heap, + const void* buf, + ulint buf_sz) +{ + const byte* first_free_byte; + const byte* presumed_start_of_buf; - buf += MEM_FIELD_HEADER_SIZE; + ut_d(mem_block_validate(heap)); - /* Check that the field lengths agree */ - ut_ad(n == mem_field_header_get_len(buf)); -#endif + first_free_byte = mem_heap_get_heap_top(heap); - return((void*) buf); + presumed_start_of_buf = first_free_byte - MEM_SPACE_NEEDED(buf_sz); + + return(presumed_start_of_buf == buf); +} + +/*****************************************************************//** +Allocate a new chunk of memory from a memory heap, possibly discarding +the topmost element. If the memory chunk specified with (top, top_sz) +is the topmost element, then it will be discarded, otherwise it will +be left untouched and this function will be equivallent to +mem_heap_alloc(). +@return allocated storage, NULL if did not succeed (only possible for +MEM_HEAP_BTR_SEARCH type heaps) */ +UNIV_INLINE +void* +mem_heap_replace( +/*=============*/ + mem_heap_t* heap, /*!< in/out: memory heap */ + const void* top, /*!< in: chunk to discard if possible */ + ulint top_sz, /*!< in: size of top in bytes */ + ulint new_sz) /*!< in: desired size of the new chunk */ +{ + if (mem_heap_is_top(heap, top, top_sz)) { + mem_heap_free_top(heap, top_sz); + } + + return(mem_heap_alloc(heap, new_sz)); +} + +/*****************************************************************//** +Allocate a new chunk of memory from a memory heap, possibly discarding +the topmost element and then copy the specified data to it. If the memory +chunk specified with (top, top_sz) is the topmost element, then it will be +discarded, otherwise it will be left untouched and this function will be +equivallent to mem_heap_dup(). +@return allocated storage, NULL if did not succeed (only possible for +MEM_HEAP_BTR_SEARCH type heaps) */ +UNIV_INLINE +void* +mem_heap_dup_replace( +/*=================*/ + mem_heap_t* heap, /*!< in/out: memory heap */ + const void* top, /*!< in: chunk to discard if possible */ + ulint top_sz, /*!< in: size of top in bytes */ + const void* data, /*!< in: new data to duplicate */ + ulint data_sz)/*!< in: size of data in bytes */ +{ + void* p = mem_heap_replace(heap, top, top_sz, data_sz); + + memcpy(p, data, data_sz); + + return(p); +} + +/*****************************************************************//** +Allocate a new chunk of memory from a memory heap, possibly discarding +the topmost element and then copy the specified string to it. If the memory +chunk specified with (top, top_sz) is the topmost element, then it will be +discarded, otherwise it will be left untouched and this function will be +equivallent to mem_heap_strdup(). +@return allocated string, NULL if did not succeed (only possible for +MEM_HEAP_BTR_SEARCH type heaps) */ +UNIV_INLINE +char* +mem_heap_strdup_replace( +/*====================*/ + mem_heap_t* heap, /*!< in/out: memory heap */ + const void* top, /*!< in: chunk to discard if possible */ + ulint top_sz, /*!< in: size of top in bytes */ + const char* str) /*!< in: new data to duplicate */ +{ + return(reinterpret_cast<char*>(mem_heap_dup_replace( + heap, top, top_sz, str, strlen(str) + 1))); } /*****************************************************************//** @@ -389,7 +440,7 @@ mem_heap_free_top( { mem_block_t* block; - ut_ad(mem_heap_check(heap)); + ut_d(mem_block_validate(heap)); block = UT_LIST_GET_LAST(heap->base); @@ -397,13 +448,6 @@ mem_heap_free_top( mem_block_set_free(block, mem_block_get_free(block) - MEM_SPACE_NEEDED(n)); UNIV_MEM_ASSERT_W((byte*) block + mem_block_get_free(block), n); -#ifdef UNIV_MEM_DEBUG - - ut_ad(mem_block_get_start(block) <= mem_block_get_free(block)); - - /* In the debug version check the consistency, and erase field */ - mem_field_erase((byte*) block + mem_block_get_free(block), n); -#endif /* If free == start, we may free the block if it is not the first one */ @@ -420,81 +464,66 @@ mem_heap_free_top( } } -/*****************************************************************//** -NOTE: Use the corresponding macros instead of this function. Creates a -memory heap. For debugging purposes, takes also the file name and line as -argument. +/** Creates a memory heap. +NOTE: Use the corresponding macros instead of this function. +A single user buffer of 'size' will fit in the block. +0 creates a default size block. +@param[in] size Desired start block size. +@param[in] file_name File name where created +@param[in] line Line where created +@param[in] type Heap type @return own: memory heap, NULL if did not succeed (only possible for MEM_HEAP_BTR_SEARCH type heaps) */ UNIV_INLINE mem_heap_t* mem_heap_create_func( -/*=================*/ - ulint n, /*!< in: desired start block size, - this means that a single user buffer - of size n will fit in the block, - 0 creates a default size block */ + ulint size, #ifdef UNIV_DEBUG - const char* file_name, /*!< in: file name where created */ - ulint line, /*!< in: line where created */ + const char* file_name, + ulint line, #endif /* UNIV_DEBUG */ - ulint type) /*!< in: heap type */ + ulint type) { mem_block_t* block; - if (!n) { - n = MEM_BLOCK_START_SIZE; + if (!size) { + size = MEM_BLOCK_START_SIZE; } - block = mem_heap_create_block(NULL, n, type, file_name, line); + block = mem_heap_create_block(NULL, size, type, file_name, line); if (block == NULL) { return(NULL); } - UT_LIST_INIT(block->base); - - /* Add the created block itself as the first block in the list */ - UT_LIST_ADD_FIRST(list, block->base, block); - -#ifdef UNIV_MEM_DEBUG + /* The first block should not be in buffer pool, + because it might be relocated to resize buffer pool. */ + ut_ad(block->buf_block == NULL); - mem_hash_insert(block, file_name, line); + UT_LIST_INIT(block->base, &mem_block_t::list); -#endif + /* Add the created block itself as the first block in the list */ + UT_LIST_ADD_FIRST(block->base, block); return(block); } -/*****************************************************************//** -NOTE: Use the corresponding macro instead of this function. Frees the space -occupied by a memory heap. In the debug version erases the heap memory -blocks. */ +/** Frees the space occupied by a memory heap. +NOTE: Use the corresponding macro instead of this function. +@param[in] heap Heap to be freed */ UNIV_INLINE void -mem_heap_free_func( -/*===============*/ - mem_heap_t* heap, /*!< in, own: heap to be freed */ - const char* file_name MY_ATTRIBUTE((unused)), - /*!< in: file name where freed */ - ulint line MY_ATTRIBUTE((unused))) +mem_heap_free( + mem_heap_t* heap) { mem_block_t* block; mem_block_t* prev_block; - ut_ad(mem_heap_check(heap)); + ut_d(mem_block_validate(heap)); block = UT_LIST_GET_LAST(heap->base); -#ifdef UNIV_MEM_DEBUG - - /* In the debug version remove the heap from the hash table of heaps - and check its consistency */ - - mem_hash_remove(heap, file_name, line); - -#endif #ifndef UNIV_HOTBACKUP if (heap->free_block) { mem_heap_free_block_free(heap); @@ -513,73 +542,6 @@ mem_heap_free_func( } } -/***************************************************************//** -NOTE: Use the corresponding macro instead of this function. -Allocates a single buffer of memory from the dynamic memory of -the C compiler. Is like malloc of C. The buffer must be freed -with mem_free. -@return own: free storage */ -UNIV_INLINE -void* -mem_alloc_func( -/*===========*/ - ulint n, /*!< in: desired number of bytes */ -#ifdef UNIV_DEBUG - const char* file_name, /*!< in: file name where created */ - ulint line, /*!< in: line where created */ -#endif /* UNIV_DEBUG */ - ulint* size) /*!< out: allocated size in bytes, - or NULL */ -{ - mem_heap_t* heap; - void* buf; - - heap = mem_heap_create_at(n, file_name, line); - - /* Note that as we created the first block in the heap big enough - for the buffer requested by the caller, the buffer will be in the - first block and thus we can calculate the pointer to the heap from - the pointer to the buffer when we free the memory buffer. */ - - if (size) { - /* Adjust the allocation to the actual size of the - memory block. */ - ulint m = mem_block_get_len(heap) - - mem_block_get_free(heap); -#ifdef UNIV_MEM_DEBUG - m -= MEM_FIELD_HEADER_SIZE + MEM_FIELD_TRAILER_SIZE; -#endif /* UNIV_MEM_DEBUG */ - ut_ad(m >= n); - n = m; - *size = m; - } - - buf = mem_heap_alloc(heap, n); - - ut_a((byte*) heap == (byte*) buf - MEM_BLOCK_HEADER_SIZE - - MEM_FIELD_HEADER_SIZE); - return(buf); -} - -/***************************************************************//** -NOTE: Use the corresponding macro instead of this function. Frees a single -buffer of storage from the dynamic memory of the C compiler. Similar to the -free of C. */ -UNIV_INLINE -void -mem_free_func( -/*==========*/ - void* ptr, /*!< in, own: buffer to be freed */ - const char* file_name, /*!< in: file name where created */ - ulint line) /*!< in: line where created */ -{ - mem_heap_t* heap; - - heap = (mem_heap_t*)((byte*) ptr - MEM_BLOCK_HEADER_SIZE - - MEM_FIELD_HEADER_SIZE); - mem_heap_free_func(heap, file_name, line); -} - /*****************************************************************//** Returns the space in bytes occupied by a memory heap. */ UNIV_INLINE @@ -590,7 +552,7 @@ mem_heap_get_size( { ulint size = 0; - ut_ad(mem_heap_check(heap)); + ut_d(mem_block_validate(heap)); size = heap->total_size; @@ -605,7 +567,7 @@ mem_heap_get_size( /**********************************************************************//** Duplicates a NUL-terminated string. -@return own: a copy of the string, must be deallocated with mem_free */ +@return own: a copy of the string, must be deallocated with ut_free */ UNIV_INLINE char* mem_strdup( @@ -613,12 +575,12 @@ mem_strdup( const char* str) /*!< in: string to be copied */ { ulint len = strlen(str) + 1; - return((char*) memcpy(mem_alloc(len), str, len)); + return(static_cast<char*>(memcpy(ut_malloc_nokey(len), str, len))); } /**********************************************************************//** Makes a NUL-terminated copy of a nonterminated string. -@return own: a copy of the string, must be deallocated with mem_free */ +@return own: a copy of the string, must be deallocated with ut_free */ UNIV_INLINE char* mem_strdupl( @@ -626,15 +588,15 @@ mem_strdupl( const char* str, /*!< in: string to be copied */ ulint len) /*!< in: length of str, in bytes */ { - char* s = (char*) mem_alloc(len + 1); + char* s = static_cast<char*>(ut_malloc_nokey(len + 1)); s[len] = 0; - return((char*) memcpy(s, str, len)); + return(static_cast<char*>(memcpy(s, str, len))); } /**********************************************************************//** Makes a NUL-terminated copy of a nonterminated string, allocated from a memory heap. -@return own: a copy of the string */ +@return own: a copy of the string */ UNIV_INLINE char* mem_heap_strdupl( |