/********************************************************************//**
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 == );

    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;
    }

    ) {
        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的更多相关文章

  1. Python 小而美的函数

    python提供了一些有趣且实用的函数,如any all zip,这些函数能够大幅简化我们得代码,可以更优雅的处理可迭代的对象,同时使用的时候也得注意一些情况   any any(iterable) ...

  2. 探究javascript对象和数组的异同,及函数变量缓存技巧

    javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...

  3. JavaScript权威指南 - 函数

    函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...

  4. C++对C的函数拓展

    一,内联函数 1.内联函数的概念 C++中的const常量可以用来代替宏常数的定义,例如:用const int a = 10来替换# define a 10.那么C++中是否有什么解决方案来替代宏代码 ...

  5. 菜鸟Python学习笔记第一天:关于一些函数库的使用

    2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...

  6. javascript中的this与函数讲解

    前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码, ...

  7. 复杂的 Hash 函数组合有意义吗?

    很久以前看到一篇文章,讲某个大网站储存用户口令时,会经过十分复杂的处理.怎么个复杂记不得了,大概就是先 Hash,结果加上一些特殊字符再 Hash,结果再加上些字符.再倒序.再怎么怎么的.再 Hash ...

  8. JS核心系列:浅谈函数的作用域

    一.作用域(scope) 所谓作用域就是:变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的. function scope(){ var foo = "global&quo ...

  9. C++中的时间函数

    C++获取时间函数众多,何时该用什么函数,拿到的是什么时间?该怎么用?很多人都会混淆. 本文是本人经历了几款游戏客户端和服务器开发后,对游戏中时间获取的一点总结. 最早学习游戏客户端时,为了获取最精确 ...

随机推荐

  1. android 弹出框(输入框和选择框)

    1.输入框: final EditText inputServer = new EditText(this); inputServer.setFilters(new InputFilter[]{new ...

  2. ffmpeg 音频转码

    大多数厂家摄像机输出的音频流格式都是PCM,有一些场合(比如讲音视频流保存成Ts流)需要将PCM格式转成AAC格式.基本的思路是先解码得到音频帧,再将音频帧编码成AAC格式.编码和解码之间需要添加一个 ...

  3. notifyDataSetChanged listview内容没更新的问题

    如红色部分所示,需在Adapter添加setData方法,当 listData中数据更改后,调用setData,为Adapter设置新的数据,此时调用notifyDataSetChanged() 就可 ...

  4. BZOJ 1143: [CTSC2008]祭祀river 最大独立集

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=1143 题解: 给你一个DAG,求最大的顶点集,使得任意两个顶点之间不可达. 把每个顶点v ...

  5. Unit Test Generator

           

  6. tangent space /handness

    normal tangent bitangent 三者互相垂直. 组成一个tangent space 表示一个点 对于原本位置的偏移(扰动) 考虑到这是为了 normalmap做出虚假的normal来 ...

  7. javascript 比较

    javascript中由于是弱类型,所以在比较的时候有较大的麻烦.这次专门做了总结: Comparison Operators Comparison operators are used in log ...

  8. java.util.ResourceBundle

    转载自: http://lavasoft.blog.51cto.com/62575/184605 这个类提供软件国际化的捷径.通过此类,可以使您所编写的程序可以:          轻松地本地化或翻译 ...

  9. hdu2011

    http://acm.hdu.edu.cn/showproblem.php?pid=2011 #include<iostream> #include<math.h> #incl ...

  10. python 常用数据结构使用

    python 字典操作 http://www.cnblogs.com/kaituorensheng/archive/2013/01/24/2875456.html python 字典排序 http:/ ...