/********************************************************************//**
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. 写一个EF的CodeFirst的Demo

    写一个EF的CodeFirst的Demo 今天打算写一个关于EF的CodeFirs的一个小Demo.先略说一个EF的三种与数据库,怎么说,叫映射么,好吧,那就这么叫吧,就是一个是ModelFirst就 ...

  2. 在一个Activity里面的TextView上面添加网页链接,启动后到另一个Activity里面!

    可以添加很多的属性,样式或者是什么的,目前要完成的功能是 点击TextView里面的某个文字链接,进入另外一个Activity里面!例如你可以做微博里面的 @XXX: 点击后进入他的个人主页! 下面都 ...

  3. Flv 视频格式(转)

    最近要用到flv,整理了一些flv格式的资料,供参考. flv文件主要由两部分组成:header和body. 1.header header部分记录了flv的类型.版本等信息,是flv的开头,一般都差 ...

  4. EXT--表单AJax提交后台,返回前端数据格式的转换

    前言: 前端发送请求至服务端(Java),得到的数据是Java语言对象所表现的形式,经常需要转换为JSON格式的字符串写出至前端:当前端获取后也往往需要将字符串转换为js的对象.本文描述了在EXT作为 ...

  5. 翻译:用Javascript的Function构造器伪造上下文 by Ben Nadel

    在我的jQuery模板标记语言(JTML)项目中,我需要一种方式将JTML模板编译到JS函数,这样它们就可以如期地在任何时候转换成新的HTML标记.但这是一个严峻的问题,因为JTML代码涉及非作用域( ...

  6. 别让安全问题拖慢了 DevOps!

    DEVSECOPS 所面临的挑战 敏捷开发和 DevOps 方法的出现使软件开发的速度与质量都有所提升,但它们不经意地也为安全机构增压不少.从前的安全策略是基于静态数据的,而在产品上线前才应用这些策略 ...

  7. How to define Servlet filter order of execution using annotations

    If we define Servlet filters in web.xml, then the order of execution of the filters will be the same ...

  8. SSH Tunneling Explained

    转载: http://chamibuddhika.wordpress.com/2012/03/21/ssh-tunnelling-explained/ March 21, 2012 by Buddhi ...

  9. poj 3067 Japan(线段树?,神奇卡时代码,暂未完)

    题目 //暴力的,没什么算法的,被琪琪视为傻逼的代码: //照者学长的神奇幸运卡时代码,虽然能AC,但是中途wa,tle了那么多次,啥也不想说了 //学长威武,能想出sum必须要是—— __int64 ...

  10. Servlet 各种path路径比较

    假定你的web application 名称为news,你在浏览器中输入请求路径: http://localhost:8080/news/main/list.jsp 则执行下面向行代码后打印出如下结果 ...