/********************************************************************//**
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. svn:Repository UUID 'XXX' doesn't match expected UUID 'YYY'

    About a month ago, CodePlex have upgraded their TFS servers to to TFS 2010. While this transition wa ...

  2. WPF解析Word为图片

    偶遇需要解析Word为单张图,此做 http://git.oschina.net/jiailiuyan/OfficeDecoder using System; using System.Collect ...

  3. Ffmpeg 定位文件(seek file)

    有朋友问到ffmpeg播放文件如何定位问题,我想到应该还有一些新手朋友对这一块比较陌生.ffmpeg定位问题用到seek方法,代码 如下: void SeekFrame(AVFormatContext ...

  4. Javascript核心概述 - 深入了解javascript

    /* 一.执行上下文:堆栈(底部全局上下文+顶部当前活动上下文) */ /* 二.变量对象: 变量根据执行上下文,找到数据存储位置,这种机制叫变量对象 1. 变量都要var定义,且都不能delete ...

  5. C# - 设置DLL的属性Embed Interop Type 设为False

    错误: Error msg: A reference was created to embedded interop assembly. because of an indirect referenc ...

  6. JQuery绑定和注销事件

    $('#action_list > li').each(function(){ $(this).unbind('click') .bind('click', function(){ /** so ...

  7. SQLServer 触发器 同时插入多条记录有关问题

    由于 SQL Server 的触发器, 没有 FOR EACH ROW (ORACL中有)的选项, 有时候不正确的使用 inserted 与deleted 可能会有点麻烦. 下面来一个简单的例子 -- ...

  8. VS2010字体设置+推荐字体

    字体的设置在工具->选项->环境->字体和颜色. 相信大家在用VS2010的时候都会觉得默认的字体不是很好看,尤其是看的时间长了以后,更是累眼睛,这里推荐一个字体,个人感觉像是加粗加 ...

  9. java poi导入EXCEL xls文件代码

    /** * */ package com.bn.car.common.report.excel; import java.io.FileInputStream; import java.io.IOEx ...

  10. linux源码阅读笔记 jmpi指令(转)

    jmpi是段间跳转指令,用于x86实模式下, 如:BOOTSEG = 0x0c70 jmpi    4, #BOOTSEG 假如当前段CS==00h,那么执行此指令后将跳转到段CS==0x0c70,当 ...