码迷,mamicode.com
首页 > 其他好文 > 详细

函数mem_area_alloc

时间:2015-12-02 22:28:30      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:

 

/********************************************************************//**
Allocates memory from a pool. NOTE: This low-level function should only be
used in mem0mem.*!
@return    own: allocated memory buffer */
UNIV_INTERN
void*
mem_area_alloc(
/*===========*/
    ulint*        psize,    /*!< in: requested size in bytes; for optimum
                space usage, the size should be a power of 2
                minus MEM_AREA_EXTRA_SIZE;
                out: allocated size in bytes (greater than
                or equal to the requested size) */
    mem_pool_t*    pool)    /*!< in: memory pool */
{
    mem_area_t*    area;
    ulint        size;
    ulint        n;
    ibool        ret;

    /* If we are using os allocator just make a simple call
    to malloc */
    if (UNIV_LIKELY(srv_use_sys_malloc)) {
        return(malloc(*psize));
    }

    size = *psize;
    n = ut_2_log(ut_max(size + MEM_AREA_EXTRA_SIZE, MEM_AREA_MIN_SIZE));

    mutex_enter(&(pool->mutex));
    mem_n_threads_inside++;

    ut_a(mem_n_threads_inside == 1);

    area = UT_LIST_GET_FIRST(pool->free_list[n]);

    if (area == NULL) {
/**
*详见
     *pool->free_list[i]找不到内存块的话,尝试从pool->free_list[i+1]中查找
*如果找不到,一直向上查找
*
*如果找到了,从list列表中摘除,并插入到向下的数组元素所在列表中
*
*例如:要分配100字节内存,通过计算在pool->free_list[7]中查找 2^7=128 而 2^6=64不符合要求
*如果pool->free_list[7]的头结点为空,
*那么从pool->free_list[7+1]中查找并赋值为area,如果找到,将area从pool->free_list[8]中的链表中删除
*将此area取类型强制转为byte*,然后取(byte*)area+ut_2_exp(7) 即取出area一半的地址
*再设置size为ut_2_exp(7)
*并设置为pool->free_list[7]的头结点

*/
        ret = mem_pool_fill_free_list(n, pool);

        if (ret == FALSE) {
            /* Out of memory in memory pool: we try to allocate
            from the operating system with the regular malloc: */

            mem_n_threads_inside--;
            mutex_exit(&(pool->mutex));

            return(ut_malloc(size));
        }
        //此area为合适的内存块
        area = UT_LIST_GET_FIRST(pool->free_list[n]);
    }
    /**
*判断此area是否是空闲的,false为已使用
*area->size_and_free & MEM_AREA_FREE
*/
if (!mem_area_get_free(area)) { fprintf(stderr, "InnoDB: Error: Removing element from mem pool" " free list %lu though the\n" "InnoDB: element is not marked free!\n", (ulong) n); mem_analyze_corruption(area); /* Try to analyze a strange assertion failure reported at mysql@lists.mysql.com where the free bit IS 1 in the hex dump above */ if (mem_area_get_free(area)) { fprintf(stderr, "InnoDB: Probably a race condition" " because now the area is marked free!\n"); } ut_error; } if (UT_LIST_GET_LEN(pool->free_list[n]) == 0) { fprintf(stderr, "InnoDB: Error: Removing element from mem pool" " free list %lu\n" "InnoDB: though the list length is 0!\n", (ulong) n); mem_analyze_corruption(area); ut_error; } ut_ad(mem_area_get_size(area) == ut_2_exp(n));
/**
*设置为已使用状态
*并从pool->free_list[n]中删除头结点
*/ mem_area_set_free(area, FALSE); UT_LIST_REMOVE(free_list, pool
->free_list[n], area); pool->reserved += mem_area_get_size(area); mem_n_threads_inside--; mutex_exit(&(pool->mutex)); ut_ad(mem_pool_validate(pool)); *psize = ut_2_exp(n) - MEM_AREA_EXTRA_SIZE; UNIV_MEM_ALLOC(MEM_AREA_EXTRA_SIZE + (byte*)area, *psize); return((void*)(MEM_AREA_EXTRA_SIZE + ((byte*)area))); }

 

函数mem_area_alloc

标签:

原文地址:http://www.cnblogs.com/taek/p/5014402.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!