关于3.2.5版本分析,详见《GlusterFS之内存池(mem-pool)实现原理及代码详解

此4.0.1版本内存池与版本3中的描述变化有点大,总的原理还是类似LINUX中的SLAB算法,定义一系列大小类型的池子,

1. 一共定义了15个池,每个池子大小都是依次幂级数增长的

#define POOL_SMALLEST 7 /* i.e. 128 2的7次幂 */
#define POOL_LARGEST 20 /* i.e. 2048576 2的20次幂 */
#define NPOOLS (POOL_LARGEST - POOL_SMALLEST + 1)

结构体 mem_pool_shared 用来记录每一类池子大小,同时用来记录各种操作的次数,用来检测使用情况以及趋势分析

struct mem_pool_shared
{
unsigned int power_of_two; // 每个池子大小定义
gf_atomic_t allocs_hot;
gf_atomic_t allocs_cold;
gf_atomic_t allocs_stdc;
gf_atomic_t frees_to_list;
};

2. 又定义了一组全局变量:

// 这里定义了内存池的全局变量
static pthread_key_t pool_key; // 用来线程本地存储 per_thread_pool_list_t *pool_list,见 mem_get_pool_list ,初始化见mem_pools_init_early
static pthread_mutex_t pool_lock;
static struct list_head pool_threads; // 用来把每个线程的pool_list 链接在一起,见 mem_get_pool_list (void)
static pthread_mutex_t pool_free_lock;
static struct list_head pool_free_threads; //
static struct mem_pool_shared pools[NPOOLS]; // 总共15个池子类型
static size_t pool_list_size; // 线程上本地存储一个队列,队列里面是15个池子类型的链表头,mem_pools_preinit (void) 里给出了计算方法

每个线程使用本地存储方式保存一个链表,链表是开辟的整块内存,内存头是struct per_thread_pool_list 结构,

后面跟着15个 struct per_thread_pool结构,每个结构都有一个热链表和一个冷链表,分别用来保存正在使用的池链表和暂时空闲的池链表。

在函数per_thread_pool_list_t * mem_get_pool_list (void) 中是分配线程池链表头的初始化代码。

逻辑关系如图:

3.  在struct per_thread_pool链表中挂着很多内存块,每个内存块都是一个小的分配池。每个内存块都用 结构体 struct pooled_obj_hdr 来描述头部。

 struct pooled_obj_hdr {
unsigned long magic; // 标记内存块幻数,固定为:#define GF_MEM_HEADER_MAGIC 0xCAFEBABE
struct pooled_obj_hdr *next; // 下一个
struct per_thread_pool_list *pool_list; // 反向引用,指向线程池链表
unsigned int power_of_two; // 块大小 /* track the pool that was used to request this object */
struct mem_pool *pool; //
}

函数 mem_get (struct mem_pool *mem_pool) 是用来获取内存块的函数。

4. struct mem_pool的用法与之前的版本有很大的不同。这个结构体,仅仅用来保存某个类型大小线程池的基本信息,并不实际存储内存块链表。

个人分析如下:之前的版本使用了一个大的结构体管理,但是多个线程竞争影响效率,所以4.0版本每建立一个struct mem_pool 对象就按照大小与 全局 pools[NPOOLS] 相对应,并且将池内存块链表的根使用线程本地存储方式保存。这样每个线程不存在竞争关系。

1)每个需要内存池的地方都是使用宏 mem_pool_new(type,count) 生成。

2)当需要使用内存的时候,调用mem_get0 (struct mem_pool *mem_pool) 。此函数内部再次调用  mem_get(mem_pool) ,该函数内部流程如下:

per_thread_pool_list_t *pool_list = mem_get_pool_list ();

之后从pool_list列表中找到指定大小的per_thread_pool_t *pt_pool,

再根据pooled_obj_hdr_t * retval = mem_get_from_pool (pt_pool); 初始化内存块 前面部分作为 pooled_obj_hdr_t 结构,函数返回结构体后面部分的内存块。

3)释放内存块回链表中:mem_put (void *ptr)

根据ptr指针前移获得 hdr = ((pooled_obj_hdr_t *)ptr) - 1; 检查内存块幻数,并把幻数改为GF_MEM_INVALID_MAGIC 0xDEADC0DE,

之后将内存块放回线程本地存储的对应类型链表头中“hot_list”。

glusterfs4.0.1 mempool 分析笔记的更多相关文章

  1. glusterfs 4.0.1 api 分析笔记1

    一般来说,我们写个客户端程序大概的样子是这样的: /* glfs_example.c */ // gcc -o glfs_example glfs_example.c -L /usr/lib64/ - ...

  2. glusterfs 4.0.1 rpc 分析笔记1

    Jimmy的文档:Glusterfs的rpc模块分析 第一节.rpc服务器端实现原理及代码分析 第二节.rpc客户端实现原理及代码分析 第三节.rpc通信过程分析 经过阅读源码对比之前提及的文档,我个 ...

  3. glusterfs 4.0.1 rpc 分析笔记2 (socket.so 模块)

    socket.c在4000行位置定义了一组结构函数,我们可以从这里开始找到入口,如果是客户端则需要调用connect, 如果是服务端则需要调用listen, struct rpc_transport_ ...

  4. 3.View绘制分析笔记之onLayout

    上一篇文章我们了解了View的onMeasure,那么今天我们继续来学习Android View绘制三部曲的第二步,onLayout,布局. ViewRootImpl#performLayout pr ...

  5. 4.View绘制分析笔记之onDraw

    上一篇文章我们了解了View的onLayout,那么今天我们来学习Android View绘制三部曲的最后一步,onDraw,绘制. ViewRootImpl#performDraw private ...

  6. 2.View绘制分析笔记之onMeasure

    今天主要学习记录一下Android View绘制三部曲的第一步,onMeasure,测量. 起源 在Activity中,所有的View都是DecorView的子View,然后DecorView又是被V ...

  7. 1.Android 视图及View绘制分析笔记之setContentView

    自从1983年第一台图形用户界面的个人电脑问世以来,几乎所有的PC操作系统都支持可视化操作,Android也不例外.对于所有Android Developer来说,我们接触最多的控件就是View.通常 ...

  8. JavaScript中的ParseInt("08")和“09”返回0的原因分析及解决办法

    今天在程序中出现一个bugger ,调试了好久,最后才发现,原来是这个问题. 做了一个实验: alert(parseInt("01")),当这个里面的值为01====>07时 ...

  9. Solr4.8.0源码分析(20)之SolrCloud的Recovery策略(一)

    Solr4.8.0源码分析(20)之SolrCloud的Recovery策略(一) 题记: 我们在使用SolrCloud中会经常发现会有备份的shard出现状态Recoverying,这就表明Solr ...

随机推荐

  1. js定时刷新页面.

    //页面定时刷新.2017.09.27 $(document).ready(function () { self.setInterval(function () { var d = new Date( ...

  2. python虚拟环境搭建大全(转)

    Pipenv & 虚拟环境 本教程将引导您完成安装和使用 Python 包. 它将向您展示如何安装和使用必要的工具,并就最佳做法做出强烈推荐.请记住, Python 用于许多不同的目的.准确地 ...

  3. Python内置函数(25)——frozenset

    英文文档: class frozenset([iterable]) Return a new frozenset object, optionally with elements taken from ...

  4. angular2 学习笔记 ( angular cli & npm version manage npm 版本管理 )

    更新 : 2017-05-05 现在流行 Yarn ! 它是 facebook google 推出的东西. 算是补助 npm 做的不够好的地方. 源码依然是发布去 npm,只是下载接口换掉罢了哦. n ...

  5. spring boot定制Jackson ObjectMapper,为什么不生效

    先说结论: 项目中定制了spring 的redisTemplate,而这个template没有使用我自定义的Jackson ObjectMapper.所以不生效. 下面是详细过程: 起因是spring ...

  6. golang微信公众号请求获取信息

    初次用golang在公众号中获取信息,记录一下 看了下文档,粗略的写了个demo,如下: func HttpGet(c*gin.Context) { var param GetType if er:= ...

  7. Lintcode373 Partition Array by Odd and Even solution 题解

    [题目描述] Partition an integers array into odd number first and even number second. 分割一个整数数组,使得奇数在前偶数在后 ...

  8. JVM 性能调优监控工具

    声明:本文转自<https://www.cnblogs.com/anxiao/p/6796644.html?utm_source=itdadao&utm_medium=referral& ...

  9. hdu-1082 Matrix Chain Multiplication---栈的运用

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1082 题目大意: 题意大致是N个矩阵,如果要求计算的矩阵例如(AB),如果A的列等于B的行,进行:A ...

  10. Menu-右键弹出菜单

    #右键弹出菜单 from tkinter import * root=Tk() def callback(): print('我被调用了') menubar =Menu(root) menubar.a ...