rte_malloc()为程序运行过程中分配内存,模拟从堆中动态分配内存空间。
void *rte_malloc(const char *type, size_t size, unsigned align)
{
return rte_malloc_socket(type, size, align, SOCKET_ID_ANY);
}
rte_malloc()函数调用关系如下图:
rte_malloc_socket():
指定从哪个 socket 上分配内存空间,默认是指定 SOCKET_ID_ANY,即,程序在哪个socket上运行,就从哪个 socket 上分配内存。
如果指定的 socket 上没有合适的内存空间,就再从其它 socket 上分配。
malloc_heap_alloc():
从 rte_config.mem_config->malloc_heaps[] 数组中找到指定socket对应的堆(使用 struct malloc_heap 描述堆),即,从这个堆中分配空间。
如果该堆是第一次使用,还没有被初始化过,则调用 malloc_heap_init() 初始化;
首先,调用 find_suitable_element() 在堆中查找是否有合适内存可以分配,如果没有,则调用 malloc_heap_add_memzone() 在 rte_config.mem_config->memzone[] 中给堆分配一块内存。
最后,调用 malloc_elem_alloc() 在堆中,将需要分配的内存划分出去。
void * malloc_heap_alloc (struct malloc_heap *heap,
const char *type __attribute__((unused)), size_t size, unsigned align)
{
if (!heap->initialised)
malloc_heap_init(heap);
size = CACHE_LINE_ROUNDUP(size);
align= CACHE_LINE_ROUNDUP(align);
rte_spinlock_lock(&heap->lock);
struct malloc_elem *prev, *elem = find_suitable_element(heap, size, align, &prev);
if (elem == NULL){
if ((malloc_heap_add_memzone(heap, size, align)) == 0)
elem = find_suitable_element(heap, size, align, &prev);
}
if (elem != NULL) {
elem = malloc_elem_alloc(elem, size, align, prev);
/* increase heap's count of allocated elements */
heap->alloc_count++;
}
rte_spinlock_unlock(&heap->lock);
return elem == NULL ? NULL : (void *)(&elem[1]);
}
malloc_heap_init():
主要是为struct malloc_heap数据结构的各个成员变量赋初始值,并将该堆的状态设置为INITIALISED。
malloc_heap_add_memzone():
调用rte_memzone_reserve(),在rte_config.mem_config->memzone[]中分配合适大小的内存。
分配的内存的大小是 mz_size = MAX(min_size, 11M),其中,min_size =size + align + MALLOC_ELEM_OVERHEAD * 2; size是rte_malloc()指定的需要分配内存的大小。
如果 memzone[] 中没有合适的内存块,将mz_size减半,再次查找。
do {
mz = rte_memzone_reserve(mz_name, mz_size, numa_socket, mz_flags);
if (mz == NULL)
mz_size /= 2;
} while (mz == NULL && mz_size > min_size);
find_suitable_element():
在堆中找到一块合适大小的内存,分配的内存是从堆的底部开始查找的。如果堆剩余内存不够分配的,会再次调用malloc_heap_add_memzone()扩展堆的大小。
malloc_elem_alloc():
查找到合适大小的内存块后,将这一块内存从堆中划分出去。
文章来源
http://www.cnblogs.com/MerlinJ/p/4092432.html