Documentation/CodingStyle에서 inline disease 에 언급된 (slab 기준) kmalloc 구현을 살펴보다가 눈에 띄어서 정리해 둔다.
__builtin_constant_p(exp) 는 컴파일 타임에 상수로 정해질 수 있는 경우에 1을, 아닌 경우에는 0을 리턴한다. 따라서 이 조건에 따라 다른 코드를 사용함으로 써 최적화할 수 있도록 할 수 있다.
(이 글을 쓰는 시점인 v3.3-rc6 기준)kmalloc 의 경우 다음과 같이 구현되어 있다.
include/linux/slab_def.h
static __always_inline void *kmalloc(size_t size, gfp_t flags)
{ struct kmem_cache *cachep; void *ret; if (__builtin_constant_p(size)) { int i = 0; if (!size) return ZERO_SIZE_PTR; #define CACHE(x) \ if (size <= x) \ goto found; \ else \ i++; #include <linux/kmalloc_sizes.h> #undef CACHE return NULL; found: #ifdef CONFIG_ZONE_DMA if (flags & GFP_DMA) cachep = malloc_sizes[i].cs_dmacachep; else #endif cachep = malloc_sizes[i].cs_cachep; ret = kmem_cache_alloc_trace(size, cachep, flags); return ret; } return __kmalloc(size, flags); }
이외에도 __always_inline 사용, CACHE(x) 매크로를 상황에 따라 define하고 linux/kmalloc_sizes.h 헤더를 include 하여 사용하는 부분은 매우 흥미롭다. __always_inline 은 gcc의 function attribute 를 이용한다.
이 글의 라이센스는 GPL 을 따른다(This document is released under the GPL licence.).
참고 :
http://gcc.gnu.org/onlinedocs/gcc-4.6.3/gcc/Other-Builtins.html