歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux Slob分配器(一)--概述

Slob分配器相較Slab和Slub分配器而言,最大的特點就是簡潔,其總共的實現代碼大概就600多行,因此其適用於嵌入式系統。不同於Slab和Slub,Slob分配器沒有引入本地CPU高速緩存和本地節點的概念。Slob分配器同樣使用鏈表來管理slob,不過總共只存在三個全局partial_free鏈表,這三個鏈表是按對象大小來劃分的。

相關閱讀:
Linux Slob分配器(二)--分配對象 http://www.linuxidc.com/Linux/2012-07/64108.htm
Linux Slob分配器(三)--釋放對象 http://www.linuxidc.com/Linux/2012-07/64109.htm

  1. #define SLOB_BREAK1 256   
  2. #define SLOB_BREAK2 1024   
  3. static LIST_HEAD(free_slob_small);  
  4. static LIST_HEAD(free_slob_medium);  
  5. static LIST_HEAD(free_slob_large);  

對於小於256字節的對象,將從free_slob_small鏈表中尋找slob進行分配

對於小於1024字節的對象,將從free_slob_medium鏈表中尋找slob進行分配

對於大於1024字節的對象,將從free_slob_large鏈表中尋找slob進行分配

對於大於PAGE_SIZE的對象,將直接通過伙伴系統分配,不經手Slob分配器

那麼總共只有三個鏈表,Slob分配器的各類緩存怎麼管理自己的空閒對象呢?實際上,所謂的不同類別的緩存都只是偽緩存,因為它們並沒有專屬自己的內存。當你在Slob分配器中創建一個緩存時,只是聲明了該緩存的對象的大小size、對齊值align等,那麼當要從該緩存分配對象時,將會根據size定位到相應的鏈表,尋求分配。因此專用緩存分配對象(kmem_cache_alloc())和普通緩存分配對象(kmalloc())並無太多區別,它們的對象都來源於這三個鏈表,只不過內核欺騙性的保留了這些接口而已。由此可以想象,struct kmem_cache這個結構在Slob分配器中是很簡潔的

  1. struct kmem_cache {  
  2.     unsigned int size, align; //對象大小,對齊值   
  3.     unsigned long flags;      //屬性標識   
  4.     const char *name;         //緩存名   
  5.     void (*ctor)(void *);     //分配對象時的構造函數   
  6. };  

接下來的一個問題就是Slob分配器是如何描述slob的。在Slob分配器中,一個slob永遠都是占用一個頁框的大小,所以對於大於PAGE_SIZE的對象,會選擇直接通過伙伴系統分配。Slob分配器將所有的slob組織在三個全局鏈表中,不過,這些slob的描述結構都不需要進行額外的分配。Slob分配器將描述slob的變量打包成一個結構,然後和頁描述符struct page一起組成一個聯合體,這樣就可以直接利用頁描述符已占有的空間,將頁描述符中無關緊要的字段填充為slob的有效描述字段,這樣便可以省下一筆內存了!

  1. struct slob_page {  
  2.     union {  
  3.         struct {  
  4.             unsigned long flags;/* 填充用,為了不覆蓋page->flags */  
  5.             atomic_t _count;      /* 填充用,為了不覆蓋page->_count */  
  6.             slobidx_t units;      /* slob的空閒單元數 */  
  7.             unsigned long pad[2];  
  8.             slob_t *free;       /* 指向第一個空閒塊 */  
  9.             struct list_head list;  /* 用於鏈入slob全局鏈表 */  
  10.         };  
  11.         struct page page;  
  12.     };  
  13. };  

我們可以看到,實際上真正用於slob管理的項只有三個,即units,free和list.

free和list的意義已經很清楚明了了,現在來解釋下slobidx_t units這個玩意。unit是slob的粒度,也就是說當你分配內存時,必須分配出去N個unit,所有的管理都是基於unit的。unit的大小根據PAGE_SIZE的不同而不同,通常情況下為2個字節,關於unit大小的定義:

  1. #if PAGE_SIZE <= (32767 * 2)   
  2. typedef s16 slobidx_t;  
  3. #else   
  4. typedef s32 slobidx_t;  
  5. #endif  

既然slob的管理是基於unit的,那麼units字段的含義也就很容易理解了,它表示的是slob中當前還剩余的空閒單元數目。

Copyright © Linux教程網 All Rights Reserved