1
/*****************************************************************************
3
Copyright (C) 1994, 2009, Innobase Oy. All Rights Reserved.
5
This program is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free Software
7
Foundation; version 2 of the License.
9
This program is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License along with
14
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
17
*****************************************************************************/
19
/********************************************************************//**
1
/************************************************************************
4
(c) 1994, 1995 Innobase Oy
23
6
Created 5/11/1994 Heikki Tuuri
24
7
*************************************************************************/
29
12
#include "ut0mem.ic"
32
#ifndef UNIV_HOTBACKUP
33
# include "os0thread.h"
39
/** This struct is placed first in every allocated memory block */
17
#include "os0thread.h"
19
/* This struct is placed first in every allocated memory block */
40
20
typedef struct ut_mem_block_struct ut_mem_block_t;
42
/** The total amount of memory currently allocated from the operating
43
system with os_mem_alloc_large() or malloc(). Does not count malloc()
44
if srv_use_sys_malloc is set. Protected by ut_list_mutex. */
45
UNIV_INTERN ulint ut_total_allocated_memory = 0;
47
/** Mutex protecting ut_total_allocated_memory and ut_mem_block_list */
48
UNIV_INTERN os_fast_mutex_t ut_list_mutex;
50
/** Dynamically allocated memory block */
22
/* The total amount of memory currently allocated from the OS with malloc */
23
UNIV_INTERN ulint ut_total_allocated_memory = 0;
51
25
struct ut_mem_block_struct{
52
26
UT_LIST_NODE_T(ut_mem_block_t) mem_block_list;
53
/*!< mem block list node */
54
ulint size; /*!< size of allocated memory */
55
ulint magic_n;/*!< magic number (UT_MEM_MAGIC_N) */
27
/* mem block list node */
28
ulint size; /* size of allocated memory */
58
/** The value of ut_mem_block_struct::magic_n. Used in detecting
60
32
#define UT_MEM_MAGIC_N 1601650166
62
/** List of all memory blocks allocated from the operating system
63
with malloc. Protected by ut_list_mutex. */
34
/* List of all memory blocks allocated from the operating system
64
36
static UT_LIST_BASE_NODE_T(ut_mem_block_t) ut_mem_block_list;
66
/** Flag: has ut_mem_block_list been initialized? */
38
static os_fast_mutex_t ut_list_mutex; /* this protects the list */
67
40
static ibool ut_mem_block_list_inited = FALSE;
69
/** A dummy pointer for generating a null pointer exception in
71
42
static ulint* ut_mem_null_ptr = NULL;
73
/**********************************************************************//**
44
/**************************************************************************
74
45
Initializes the mem block list at database startup. */
48
ut_mem_block_list_init(void)
49
/*========================*/
80
ut_a(!ut_mem_block_list_inited);
81
51
os_fast_mutex_init(&ut_list_mutex);
82
52
UT_LIST_INIT(ut_mem_block_list);
83
53
ut_mem_block_list_inited = TRUE;
85
#endif /* !UNIV_HOTBACKUP */
87
/**********************************************************************//**
56
/**************************************************************************
88
57
Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is
89
defined and set_to_zero is TRUE.
90
@return own: allocated memory */
58
defined and set_to_zero is TRUE. */
95
ulint n, /*!< in: number of bytes to allocate */
96
ibool set_to_zero, /*!< in: TRUE if allocated memory should be
63
/* out, own: allocated memory */
64
ulint n, /* in: number of bytes to allocate */
65
ibool set_to_zero, /* in: TRUE if allocated memory should be
97
66
set to zero if UNIV_SET_MEM_TO_ZERO is
99
ibool assert_on_error)/*!< in: if TRUE, we crash mysqld if the
68
ibool assert_on_error)/* in: if TRUE, we crash mysqld if the
100
69
memory cannot be allocated */
102
#ifndef UNIV_HOTBACKUP
71
ulint retry_count = 0;
106
if (UNIV_LIKELY(srv_use_sys_malloc)) {
108
ut_a(ret || !assert_on_error);
110
#ifdef UNIV_SET_MEM_TO_ZERO
112
memset(ret, '\0', n);
113
UNIV_MEM_ALLOC(ret, n);
119
74
ut_ad((sizeof(ut_mem_block_t) % 8) == 0); /* check alignment ok */
120
ut_a(ut_mem_block_list_inited);
76
if (!ut_mem_block_list_inited) {
77
ut_mem_block_list_init();
124
80
os_fast_mutex_lock(&ut_list_mutex);
212
174
os_fast_mutex_unlock(&ut_list_mutex);
214
176
return((void*)((byte*)ret + sizeof(ut_mem_block_t)));
215
#else /* !UNIV_HOTBACKUP */
216
void* ret = malloc(n);
217
ut_a(ret || !assert_on_error);
219
# ifdef UNIV_SET_MEM_TO_ZERO
221
memset(ret, '\0', n);
225
#endif /* !UNIV_HOTBACKUP */
228
/**********************************************************************//**
179
/**************************************************************************
229
180
Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is
231
@return own: allocated memory */
237
ulint n) /*!< in: number of bytes to allocate */
186
/* out, own: allocated memory */
187
ulint n) /* in: number of bytes to allocate */
239
#ifndef UNIV_HOTBACKUP
240
189
return(ut_malloc_low(n, TRUE, TRUE));
241
#else /* !UNIV_HOTBACKUP */
243
#endif /* !UNIV_HOTBACKUP */
246
#ifndef UNIV_HOTBACKUP
247
/**********************************************************************//**
192
/**************************************************************************
248
193
Tests if malloc of n bytes would succeed. ut_malloc() asserts if memory runs
249
194
out. It cannot be used if we want to return an error message. Prints to
250
stderr a message if fails.
251
@return TRUE if succeeded */
195
stderr a message if fails. */
256
ulint n) /*!< in: try to allocate this many bytes */
200
/* out: TRUE if succeeded */
201
ulint n) /* in: try to allocate this many bytes */
286
#endif /* !UNIV_HOTBACKUP */
288
/**********************************************************************//**
289
Frees a memory block allocated with ut_malloc. Freeing a NULL pointer is
232
/**************************************************************************
233
Frees a memory block allocated with ut_malloc. */
296
void* ptr) /*!< in, own: memory block, can be NULL */
238
void* ptr) /* in, own: memory block */
298
#ifndef UNIV_HOTBACKUP
299
240
ut_mem_block_t* block;
303
} else if (UNIV_LIKELY(srv_use_sys_malloc)) {
308
242
block = (ut_mem_block_t*)((byte*)ptr - sizeof(ut_mem_block_t));
310
244
os_fast_mutex_lock(&ut_list_mutex);
347
277
size was equal to 0, either NULL or a pointer suitable to
348
278
be passed to free() is returned. If realloc() fails the
349
279
original block is left untouched - it is not freed or
351
@return own: pointer to new mem block or NULL */
357
void* ptr, /*!< in: pointer to old block or NULL */
358
ulint size) /*!< in: desired size */
285
/* out, own: pointer to new mem block or NULL */
286
void* ptr, /* in: pointer to old block or NULL */
287
ulint size) /* in: desired size */
360
289
ut_mem_block_t* block;
365
if (UNIV_LIKELY(srv_use_sys_malloc)) {
366
return(realloc(ptr, size));
369
294
if (ptr == NULL) {
371
296
return(ut_malloc(size));
434
357
" total allocated memory is %lu\n",
435
358
(ulong) ut_total_allocated_memory);
438
ut_mem_block_list_inited = FALSE;
440
#endif /* !UNIV_HOTBACKUP */
442
/**********************************************************************//**
362
/**************************************************************************
443
363
Copies up to size - 1 characters from the NUL-terminated string src to
444
364
dst, NUL-terminating the result. Returns strlen(src), so truncation
445
occurred if the return value >= size.
446
@return strlen(src) */
365
occurred if the return value >= size. */
451
char* dst, /*!< in: destination buffer */
452
const char* src, /*!< in: source buffer */
453
ulint size) /*!< in: size of destination buffer */
370
/* out: strlen(src) */
371
char* dst, /* in: destination buffer */
372
const char* src, /* in: source buffer */
373
ulint size) /* in: size of destination buffer */
455
375
ulint src_size = strlen(src);
464
384
return(src_size);
467
/**********************************************************************//**
387
/**************************************************************************
468
388
Like ut_strlcpy, but if src doesn't fit in dst completely, copies the last
469
(size - 1) bytes of src, not the first.
470
@return strlen(src) */
389
(size - 1) bytes of src, not the first. */
475
char* dst, /*!< in: destination buffer */
476
const char* src, /*!< in: source buffer */
477
ulint size) /*!< in: size of destination buffer */
394
/* out: strlen(src) */
395
char* dst, /* in: destination buffer */
396
const char* src, /* in: source buffer */
397
ulint size) /* in: size of destination buffer */
479
399
ulint src_size = strlen(src);
487
407
return(src_size);
490
/**********************************************************************//**
410
/**************************************************************************
491
411
Make a quoted copy of a NUL-terminated string. Leading and trailing
492
412
quotes will not be included; only embedded quotes will be escaped.
493
See also ut_strlenq() and ut_memcpyq().
494
@return pointer to end of dest */
413
See also ut_strlenq() and ut_memcpyq(). */
499
char* dest, /*!< in: output buffer */
500
char q, /*!< in: the quote character */
501
const char* src) /*!< in: null-terminated string */
418
/* out: pointer to end of dest */
419
char* dest, /* in: output buffer */
420
char q, /* in: the quote character */
421
const char* src) /* in: null-terminated string */
504
424
if ((*dest++ = *src++) == q) {
512
/**********************************************************************//**
432
/**************************************************************************
513
433
Make a quoted copy of a fixed-length string. Leading and trailing
514
434
quotes will not be included; only embedded quotes will be escaped.
515
See also ut_strlenq() and ut_strcpyq().
516
@return pointer to end of dest */
435
See also ut_strlenq() and ut_strcpyq(). */
521
char* dest, /*!< in: output buffer */
522
char q, /*!< in: the quote character */
523
const char* src, /*!< in: string to be quoted */
524
ulint len) /*!< in: length of src */
440
/* out: pointer to end of dest */
441
char* dest, /* in: output buffer */
442
char q, /* in: the quote character */
443
const char* src, /* in: string to be quoted */
444
ulint len) /* in: length of src */
526
446
const char* srcend = src + len;
537
#ifndef UNIV_HOTBACKUP
538
/**********************************************************************//**
457
/**************************************************************************
539
458
Return the number of times s2 occurs in s1. Overlapping instances of s2
540
are only counted once.
541
@return the number of times s2 occurs in s1 */
459
are only counted once. */
546
const char* s1, /*!< in: string to search in */
547
const char* s2) /*!< in: string to search for */
464
/* out: the number of times s2 occurs in s1 */
465
const char* s1, /* in: string to search in */
466
const char* s2) /* in: string to search for */
550
469
ulint len = strlen(s2);
572
/**********************************************************************//**
491
/**************************************************************************
573
492
Replace every occurrence of s1 in str with s2. Overlapping instances of s1
574
are only replaced once.
575
@return own: modified string, must be freed with mem_free() */
493
are only replaced once. */
580
const char* str, /*!< in: string to operate on */
581
const char* s1, /*!< in: string to replace */
582
const char* s2) /*!< in: string to replace s1 with */
498
/* out, own: modified string, must be
499
freed with mem_free() */
500
const char* str, /* in: string to operate on */
501
const char* s1, /* in: string to replace */
502
const char* s2) /* in: string to replace s1 with */