28 #include "mem0pool.ic"
95 #define MEM_AREA_FREE 1
98 #define MEM_AREA_MIN_SIZE (2 * MEM_AREA_EXTRA_SIZE)
118 #ifdef UNIV_PFS_MUTEX
120 UNIV_INTERN mysql_pfs_key_t mem_pool_mutex_key;
127 UNIV_INTERN ulint mem_n_threads_inside = 0;
135 mem_pool_mutex_enter(
140 mutex_enter(&(pool->
mutex));
155 mutex_exit(&(pool->
mutex));
193 #if TRUE != MEM_AREA_FREE
194 # error "TRUE != MEM_AREA_FREE"
208 #if TRUE != MEM_AREA_FREE
209 # error "TRUE != MEM_AREA_FREE"
238 mutex_create(mem_pool_mutex_key, &pool->
mutex, SYNC_MEM_POOL);
242 for (i = 0; i < 64; i++) {
249 while (size - used >= MEM_AREA_MIN_SIZE) {
262 mem_area_set_size(area,
ut_2_exp(i));
263 mem_area_set_free(area, TRUE);
296 mem_pool_fill_free_list(
307 if (UNIV_UNLIKELY(i >= 63)) {
321 " InnoDB: Error: mem pool free list %lu"
323 "InnoDB: though the list is empty!\n",
329 ret = mem_pool_fill_free_list(i + 1, pool);
350 mem_area_set_size(area2,
ut_2_exp(i));
351 mem_area_set_free(area2, TRUE);
355 mem_area_set_size(area,
ut_2_exp(i));
384 if (UNIV_LIKELY(srv_use_sys_malloc)) {
385 return(malloc(*psize));
391 mutex_enter(&(pool->
mutex));
392 mem_n_threads_inside++;
394 ut_a(mem_n_threads_inside == 1);
399 ret = mem_pool_fill_free_list(n, pool);
405 mem_n_threads_inside--;
406 mutex_exit(&(pool->
mutex));
414 if (!mem_area_get_free(area)) {
416 "InnoDB: Error: Removing element from mem pool"
417 " free list %lu though the\n"
418 "InnoDB: element is not marked free!\n",
427 if (mem_area_get_free(area)) {
429 "InnoDB: Probably a race condition"
430 " because now the area is marked free!\n");
438 "InnoDB: Error: Removing element from mem pool"
440 "InnoDB: though the list length is 0!\n",
449 mem_area_set_free(area, FALSE);
453 pool->
reserved += mem_area_get_size(area);
455 mem_n_threads_inside--;
456 mutex_exit(&(pool->
mutex));
481 if (((((byte*)area) - pool->
buf) % (2 * size)) == 0) {
487 if ((((byte*)buddy) - pool->
buf) + size > pool->
size) {
522 if (UNIV_LIKELY(srv_use_sys_malloc)) {
531 if ((byte*)ptr < pool->buf || (byte*)ptr >= pool->
buf + pool->
size) {
539 if (mem_area_get_free(area)) {
541 "InnoDB: Error: Freeing element to mem pool"
542 " free list though the\n"
543 "InnoDB: element is marked free!\n");
549 size = mem_area_get_size(area);
554 "InnoDB: Error: Mem area size is 0. Possibly a"
555 " memory overrun of the\n"
556 "InnoDB: previous allocated area!\n");
562 #ifdef UNIV_LIGHT_MEM_DEBUG
563 if (((byte*)area) + size < pool->buf + pool->
size) {
567 next_size = mem_area_get_size(
569 if (UNIV_UNLIKELY(!next_size || !
ut_is_2pow(next_size))) {
571 "InnoDB: Error: Memory area size %lu,"
572 " next area size %lu not a power of 2!\n"
573 "InnoDB: Possibly a memory overrun of"
574 " the buffer being freed here.\n",
575 (ulong) size, (ulong) next_size);
582 buddy = mem_area_get_buddy(area, size, pool);
586 mem_pool_mutex_enter(pool);
587 mem_n_threads_inside++;
589 ut_a(mem_n_threads_inside == 1);
591 if (buddy && mem_area_get_free(buddy)
592 && (size == mem_area_get_size(buddy))) {
596 if ((byte*)buddy < (byte*)area) {
599 mem_area_set_size(buddy, 2 * size);
600 mem_area_set_free(buddy, FALSE);
604 mem_area_set_size(area, 2 * size);
613 mem_n_threads_inside--;
614 mem_pool_mutex_exit(pool);
622 mem_area_set_free(area, TRUE);
629 mem_n_threads_inside--;
630 mem_pool_mutex_exit(pool);
649 mem_pool_mutex_enter(pool);
653 for (i = 0; i < 64; i++) {
660 while (area != NULL) {
661 ut_a(mem_area_get_free(area));
664 buddy = mem_area_get_buddy(area,
ut_2_exp(i), pool);
666 ut_a(!buddy || !mem_area_get_free(buddy)
667 || (
ut_2_exp(i) != mem_area_get_size(buddy)));
677 mem_pool_mutex_exit(pool);
695 fprintf(outfile,
"INFO OF A MEMORY POOL\n");
697 mutex_enter(&(pool->
mutex));
699 for (i = 0; i < 64; i++) {
703 "Free list length %lu for"
704 " blocks of size %lu\n",
710 fprintf(outfile,
"Pool size %lu, reserved %lu.\n", (ulong) pool->
size,
712 mutex_exit(&(pool->
mutex));
726 mutex_enter(&(pool->
mutex));
730 mutex_exit(&(pool->
mutex));
#define UT_LIST_GET_LEN(BASE)
UNIV_INLINE ulint ut_2_exp(ulint n)
#define UT_LIST_GET_NEXT(NAME, N)
UNIV_INTERN mem_pool_t * mem_pool_create(ulint size)
#define UT_LIST_VALIDATE(NAME, TYPE, BASE, ASSERTION)
UNIV_INTERN ibool mem_pool_validate(mem_pool_t *pool)
UNIV_INTERN void * ut_malloc(ulint n)
UNIV_INTERN void * ut_malloc_low(ulint n, ibool set_to_zero, ibool assert_on_error)
UNIV_INTERN void mem_area_free(void *ptr, mem_pool_t *pool)
typedef UT_LIST_BASE_NODE_T(mutex_t) ut_list_base_node_t
#define UT_LIST_REMOVE(NAME, BASE, N)
UNIV_INTERN void * mem_area_alloc(ulint *psize, mem_pool_t *pool)
#define MEM_AREA_EXTRA_SIZE
UNIV_INTERN void mem_pool_print_info(FILE *outfile, mem_pool_t *pool)
UNIV_INLINE ulint ut_max(ulint n1, ulint n2)
#define UT_LIST_GET_FIRST(BASE)
UNIV_INTERN ulint mem_pool_get_reserved(mem_pool_t *pool)
UNIV_INTERN void ut_free(void *ptr)
#define UT_LIST_INIT(BASE)
#define UT_LIST_ADD_FIRST(NAME, BASE, N)
mem_pool_t * mem_comm_pool
UNIV_INLINE ulint ut_2_log(ulint n)
UNIV_INTERN void ut_print_timestamp(FILE *file)
UNIV_INTERN void mem_pool_free(mem_pool_t *pool)
UNIV_INTERN void mem_analyze_corruption(void *ptr)