日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

glusterfs4.0.1 mempool 分析笔记

發布時間:2025/7/14 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 glusterfs4.0.1 mempool 分析笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

關于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 0xCAFEBABEstruct 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”。

?

?

?

?

?

?

?

?

?

?

?

轉載于:https://www.cnblogs.com/robinfox/p/8848014.html

總結

以上是生活随笔為你收集整理的glusterfs4.0.1 mempool 分析笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。