/****************************************************************//**
Helper function for mem_heap_printf.
@return length of formatted string, including terminating NUL */ static
ulint
mem_heap_printf_low( /*================*/ char* buf, /*!< in/out: buffer to store formatted string
in, or NULL to just calculate length */ constchar* format, /*!< in: format string */
va_list ap) /*!< in: arguments */
{
ulint len = 0;
while (*format) {
/* Does this format specifier have the 'l' length modifier. */
ibool is_long = FALSE;
/* Length of one parameter. */
size_t plen;
if (*format++ != '%') { /* Non-format character. */
/* "%l%" is a non-sensical format specifier. */
ut_a(!is_long);
len++;
if (buf) {
*buf++ = '%';
}
break;
default:
ut_error;
}
}
/* For the NUL character. */
len++;
if (buf) {
*buf = '\0';
}
return(len);
}
/****************************************************************//**
A simple sprintf replacement that dynamically allocates the space for the
formatted string from the given heap. This supports a very limited set of
the printf syntax: types 's'and'u'and length modifier 'l' (which is
required for the 'u' type).
@return heap-allocated formatted string */ char*
mem_heap_printf( /*============*/
mem_heap_t* heap, /*!< in: memory heap */ constchar* format, /*!< in: format string */
...)
{
va_list ap; char* str;
ulint len;
/* Calculate length of string */
len = 0;
va_start(ap, format);
len = mem_heap_printf_low(NULL, format, ap);
va_end(ap);
/* Now create it for real. */
str = static_cast<char*>(mem_heap_alloc(heap, len));
va_start(ap, format);
mem_heap_printf_low(str, format, ap);
va_end(ap);
return(str);
}
#ifdef UNIV_DEBUG /** Validates the contents of a memory heap. Checksamemoryheapforconsistency,printsthecontentsifanyerror isdetected.Afatalerrorisloggedifanerrorisdetected.
@param[in] heap Memory heap to validate. */ void
mem_heap_validate( const mem_heap_t* heap)
{
ulint size = 0;
switch (block->type) { case MEM_HEAP_DYNAMIC: break; case MEM_HEAP_BUFFER:
ut_ad(block->len <= srv_page_size); break; default:
ut_error;
}
size += block->len;
}
ut_ad(size == heap->total_size);
}
/** Copy the tail of a string. @param[in,out]dstdestinationbuffer @param[in]srcstringwhosetailtocopy @param[in]sizesizeofdstbuffer,inbytes,includingNULterminator
@return strlen(src) */ staticvoid ut_strlcpy_rev(char* dst, constchar* src, ulint size)
{
size_t src_size = strlen(src), n = std::min(src_size, size - 1);
memcpy(dst, src + src_size - n, n + 1);
} #endif/* UNIV_DEBUG */
/***************************************************************//**
Creates a memory heap block where data can be allocated.
@return own: memory heap block */
mem_block_t*
mem_heap_create_block_func( /*=======================*/
mem_heap_t* heap, /*!< in: memory heap or NULL if first block
should be created */
ulint n, /*!< in: number of bytes needed for user data */ #ifdef UNIV_DEBUG constchar* file_name,/*!< in: file name where created */ unsigned line, /*!< in: line where created */ #endif/* UNIV_DEBUG */
ulint type) /*!< in: type of heap: MEM_HEAP_DYNAMIC or
MEM_HEAP_BUFFER */
{
buf_block_t* buf_block;
mem_block_t* block;
ulint len;
ut_ad(type == MEM_HEAP_DYNAMIC || type == MEM_HEAP_BUFFER);
if (heap != NULL) {
ut_d(mem_heap_validate(heap));
}
/* In dynamic allocation, calculate the size: block header + data. */
len = MEM_BLOCK_HEADER_SIZE + MEM_SPACE_NEEDED(n);
if (type == MEM_HEAP_DYNAMIC || len < srv_page_size / 2) {
ut_ad(type == MEM_HEAP_DYNAMIC || n <= MEM_MAX_ALLOC_IN_BUF);
if (UNIV_UNLIKELY(heap == NULL)) { /* This is the first block of the heap. The field
total_size should be initialized here */
block->total_size = len;
} else { /* Not the first allocation for the heap. This block's
total_length field should be set to undefined. */
ut_d(block->total_size = ULINT_UNDEFINED);
MEM_UNDEFINED(&block->total_size, sizeof block->total_size);
heap->total_size += len;
}
/* Poison all available memory. Individual chunks will be unpoisoned on
every mem_heap_alloc() call. */
compile_time_assert(MEM_BLOCK_HEADER_SIZE >= sizeof *block);
MEM_NOACCESS(block + 1, len - sizeof *block);
ut_ad((ulint)MEM_BLOCK_HEADER_SIZE < len);
return(block);
}
/***************************************************************//**
Adds a new block to a memory heap.
@return created block */
mem_block_t*
mem_heap_add_block( /*===============*/
mem_heap_t* heap, /*!< in: memory heap */
ulint n) /*!< in: number of bytes user needs */
{
mem_block_t* block;
mem_block_t* new_block;
ulint new_size;
block = UT_LIST_GET_LAST(heap->base);
/* We have to allocate a new block. The size is always at least doubleduntilthestandardsizeisreached.Afterthatthesize
stays the same, except in cases where the caller needs more space. */
new_size = 2 * mem_block_get_len(block);
if (heap->type != MEM_HEAP_DYNAMIC) { /* From the buffer pool we allocate buffer frames */
ut_a(n <= MEM_MAX_ALLOC_IN_BUF);
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.13Bemerkung:
(vorverarbeitet am 2026-10-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.