分类: LINUX
2009-09-13 10:28:46
单位 |
接口 | 算法 |
动态大小 |
kmalloc/kfree/krealloc/kcalloc | 按大小组织的缓存数组 |
固定大小 |
kmem_cache_create/kmem_cache_destroy kmem_cache_alloc/kmem_cache_free |
Slab[2] |
2^n页 | alloc_pages/free_pages __get_free_pages/__free_pages |
伙伴算法 |
79 static inline void *kmalloc(size_t size, gfp_t flags) 80 { 81 if (__builtin_constant_p(size)) { 82 int i = 0; 83 #define CACHE(x) \ 84 if (size <= x) \ 85 goto found; \ 86 else \ 87 i++; 88 #include "kmalloc_sizes.h" 89 #undef CACHE 90 { 91 extern void __you_cannot_kmalloc_that_much(void); 92 __you_cannot_kmalloc_that_much(); 93 } 94 found: 95 return kmem_cache_alloc((flags & GFP_DMA) ? 96 malloc_sizes[i].cs_dmacachep : 97 malloc_sizes[i].cs_cachep, flags); 98 } 99 return __kmalloc(size, flags); 100 } |
ptr = kmalloc(128, GTP_KERNEL); |
1 #if (PAGE_SIZE == 4096) 2 CACHE(32) 3 #endif 4 CACHE(64) 5 #if L1_CACHE_BYTES < 64 6 CACHE(96) 7 #endif 8 CACHE(128) 9 #if L1_CACHE_BYTES < 128 10 CACHE(192) 11 #endif 12 CACHE(256) 13 CACHE(512) 14 CACHE(1024) 15 CACHE(2048) 16 CACHE(4096) 17 CACHE(8192) 18 CACHE(16384) 19 CACHE(32768) 20 CACHE(65536) 21 CACHE(131072) 22 #ifndef CONFIG_MMU 23 CACHE(262144) 24 CACHE(524288) 25 CACHE(1048576) 26 #ifdef CONFIG_LARGE_ALLOCS 27 CACHE(2097152) 28 CACHE(4194304) 29 CACHE(8388608) 30 CACHE(16777216) 31 CACHE(33554432) 32 #endif /* CONFIG_LARGE_ALLOCS */ 33 #endif /* CONFIG_MMU */ |
movl malloc_sizes+60, %eax ; 60就是编译时计算出来的。 andl $-16, %esp subl $16, %esp movl %edx, 4(%esp) movl %eax, (%esp) call kmem_cache_alloc |
void *__kmalloc(size_t size, gfp_t flags) { kmem_cache_t *cachep; /* If you want to save a few bytes .text space: replace * __ with kmem_. * Then kmalloc uses the uninlined functions instead of the inline * functions. */ cachep = __find_general_cachep(size, flags); if (unlikely(cachep == NULL)) return NULL; return __cache_alloc(cachep, flags); } |
static inline kmem_cache_t *__find_general_cachep(size_t size, gfp_t gfpflags) { struct cache_sizes *csizep = malloc_sizes; #if DEBUG /* This happens if someone tries to call * kmem_cache_create(), or __kmalloc(), before * the generic caches are initialized. */ BUG_ON(malloc_sizes[INDEX_AC].cs_cachep == NULL); #endif while (size > csizep->cs_size) csizep++; /* * Really subtle: The last entry with cs->cs_size==ULONG_MAX * has cs_{dma,}cachep==NULL. Thus no special case * for large kmalloc calls required. */ if (unlikely(gfpflags & GFP_DMA)) return csizep->cs_dmacachep; return csizep->cs_cachep; } |