1
/*****************************************************************************
3
Copyright (c) 1997, 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
/************************************************************************
21
2
The lowest-level memory management
23
6
Created 5/12/1997 Heikki Tuuri
24
7
*************************************************************************/
91
72
can occupy at most about the size of the buffer frame of memory in the common
92
73
pool, and after that its locks will grow into the buffer pool. */
94
/** Mask used to extract the free bit from area->size */
75
/* Mask used to extract the free bit from area->size */
95
76
#define MEM_AREA_FREE 1
97
/** The smallest memory area total size */
78
/* The smallest memory area total size */
98
79
#define MEM_AREA_MIN_SIZE (2 * MEM_AREA_EXTRA_SIZE)
101
/** Data structure for a memory pool. The space is allocated using the buddy
82
/* Data structure for a memory pool. The space is allocated using the buddy
102
83
algorithm, where free list i contains areas of size 2 to power i. */
103
84
struct mem_pool_struct{
104
byte* buf; /*!< memory pool */
105
ulint size; /*!< memory common pool size */
106
ulint reserved; /*!< amount of currently allocated
85
byte* buf; /* memory pool */
86
ulint size; /* memory common pool size */
87
ulint reserved; /* amount of currently allocated
108
mutex_t mutex; /*!< mutex protecting this struct */
89
mutex_t mutex; /* mutex protecting this struct */
109
90
UT_LIST_BASE_NODE_T(mem_area_t)
110
free_list[64]; /*!< lists of free memory areas: an
91
free_list[64]; /* lists of free memory areas: an
111
92
area is put to the list whose number
112
93
is the 2-logarithm of the area size */
115
/** The common memory pool */
96
/* The common memory pool */
116
97
UNIV_INTERN mem_pool_t* mem_comm_pool = NULL;
118
#ifdef UNIV_PFS_MUTEX
119
/* Key to register mutex in mem_pool_struct with performance schema */
120
UNIV_INTERN mysql_pfs_key_t mem_pool_mutex_key;
121
#endif /* UNIV_PFS_MUTEX */
123
99
/* We use this counter to check that the mem pool mutex does not leak;
124
100
this is to track a strange assertion failure reported at
125
101
mysql@lists.mysql.com */
127
103
UNIV_INTERN ulint mem_n_threads_inside = 0;
129
/********************************************************************//**
130
Reserves the mem pool mutex if we are not in server shutdown. Use
131
this function only in memory free functions, since only memory
132
free functions are used during server shutdown. */
135
mem_pool_mutex_enter(
136
/*=================*/
137
mem_pool_t* pool) /*!< in: memory pool */
139
if (srv_shutdown_state < SRV_SHUTDOWN_EXIT_THREADS) {
140
mutex_enter(&(pool->mutex));
144
/********************************************************************//**
145
Releases the mem pool mutex if we are not in server shutdown. As
146
its corresponding mem_pool_mutex_enter() function, use it only
147
in memory free functions */
152
mem_pool_t* pool) /*!< in: memory pool */
154
if (srv_shutdown_state < SRV_SHUTDOWN_EXIT_THREADS) {
155
mutex_exit(&(pool->mutex));
159
/********************************************************************//**
160
Returns memory area size.
105
/************************************************************************
106
Reserves the mem pool mutex. */
109
mem_pool_mutex_enter(void)
110
/*======================*/
112
mutex_enter(&(mem_comm_pool->mutex));
115
/************************************************************************
116
Releases the mem pool mutex. */
119
mem_pool_mutex_exit(void)
120
/*=====================*/
122
mutex_exit(&(mem_comm_pool->mutex));
125
/************************************************************************
126
Returns memory area size. */
164
129
mem_area_get_size(
165
130
/*==============*/
166
mem_area_t* area) /*!< in: area */
132
mem_area_t* area) /* in: area */
168
134
return(area->size_and_free & ~MEM_AREA_FREE);
171
/********************************************************************//**
137
/************************************************************************
172
138
Sets memory area size. */
175
141
mem_area_set_size(
176
142
/*==============*/
177
mem_area_t* area, /*!< in: area */
178
ulint size) /*!< in: size */
143
mem_area_t* area, /* in: area */
144
ulint size) /* in: size */
180
146
area->size_and_free = (area->size_and_free & MEM_AREA_FREE)
184
/********************************************************************//**
185
Returns memory area free bit.
186
@return TRUE if free */
150
/************************************************************************
151
Returns memory area free bit. */
189
154
mem_area_get_free(
190
155
/*==============*/
191
mem_area_t* area) /*!< in: area */
156
/* out: TRUE if free */
157
mem_area_t* area) /* in: area */
193
159
#if TRUE != MEM_AREA_FREE
194
160
# error "TRUE != MEM_AREA_FREE"
279
/********************************************************************//**
280
Frees a memory pool. */
285
mem_pool_t* pool) /*!< in, own: memory pool */
291
/********************************************************************//**
292
Fills the specified free list.
293
@return TRUE if we were able to insert a block to the free list */
247
/************************************************************************
248
Fills the specified free list. */
296
251
mem_pool_fill_free_list(
297
252
/*====================*/
298
ulint i, /*!< in: free list index */
299
mem_pool_t* pool) /*!< in: memory pool */
253
/* out: TRUE if we were able to insert a
254
block to the free list */
255
ulint i, /* in: free list index */
256
mem_pool_t* pool) /* in: memory pool */
301
258
mem_area_t* area;
302
259
mem_area_t* area2;
362
/********************************************************************//**
319
/************************************************************************
363
320
Allocates memory from a pool. NOTE: This low-level function should only be
365
@return own: allocated memory buffer */
321
used in mem0mem.*! */
370
ulint* psize, /*!< in: requested size in bytes; for optimum
326
/* out, own: allocated memory buffer */
327
ulint* psize, /* in: requested size in bytes; for optimum
371
328
space usage, the size should be a power of 2
372
329
minus MEM_AREA_EXTRA_SIZE;
373
330
out: allocated size in bytes (greater than
374
331
or equal to the requested size) */
375
mem_pool_t* pool) /*!< in: memory pool */
332
mem_pool_t* pool) /* in: memory pool */
377
334
mem_area_t* area;
382
/* If we are using os allocator just make a simple call
384
if (UNIV_LIKELY(srv_use_sys_malloc)) {
385
return(malloc(*psize));
389
340
n = ut_2_log(ut_max(size + MEM_AREA_EXTRA_SIZE, MEM_AREA_MIN_SIZE));
463
414
return((void*)(MEM_AREA_EXTRA_SIZE + ((byte*)area)));
466
/********************************************************************//**
467
Gets the buddy of an area, if it exists in pool.
468
@return the buddy, NULL if no buddy in pool */
417
/************************************************************************
418
Gets the buddy of an area, if it exists in pool. */
471
421
mem_area_get_buddy(
472
422
/*===============*/
473
mem_area_t* area, /*!< in: memory area */
474
ulint size, /*!< in: memory area size */
475
mem_pool_t* pool) /*!< in: memory pool */
423
/* out: the buddy, NULL if no buddy in pool */
424
mem_area_t* area, /* in: memory area */
425
ulint size, /* in: memory area size */
426
mem_pool_t* pool) /* in: memory pool */
477
428
mem_area_t* buddy;
629
574
mem_n_threads_inside--;
630
mem_pool_mutex_exit(pool);
575
mutex_exit(&(pool->mutex));
632
577
ut_ad(mem_pool_validate(pool));
635
/********************************************************************//**
636
Validates a memory pool.
637
@return TRUE if ok */
580
/************************************************************************
581
Validates a memory pool. */
640
584
mem_pool_validate(
641
585
/*==============*/
642
mem_pool_t* pool) /*!< in: memory pool */
586
/* out: TRUE if ok */
587
mem_pool_t* pool) /* in: memory pool */
644
589
mem_area_t* area;
645
590
mem_area_t* buddy;
649
mem_pool_mutex_enter(pool);
594
mutex_enter(&(pool->mutex));
653
598
for (i = 0; i < 64; i++) {
655
UT_LIST_VALIDATE(free_list, mem_area_t, pool->free_list[i],
600
UT_LIST_VALIDATE(free_list, mem_area_t, pool->free_list[i]);
658
602
area = UT_LIST_GET_FIRST(pool->free_list[i]);