nginx slab管理

Time: 十月 6, 2013
Category: Programming practices

今天在看一个开源的内存管理,https://github.com/flygoast/flib/blob/master/src/slab.c#L296

有几个地方比较难理解,记录一下,代码在 void *slab_alloc_locked(slab_pool_t *pool, size_t size) 函数里

    if (page) {
        if (shift < slab_exact_shift) {
            p = (page - pool->pages) << pagesize_shift;
            bitmap = (uintptr_t*)(pool->start + p);

            s = 1 << shift;
            n = (1 << (pagesize_shift - shift)) / 8 / s;
            if (n == 0) {
                n = 1;
            }

            bitmap[0] = (2 << n) - 1;

            map = (1 << (pagesize_shift - shift))
                / (sizeof(uintptr_t) * 8);

            for (i = 1; i < map; ++i) {
                bitmap[i] = 0;
            }
            page->slab = shift;
            page->next = &slots[slot];
            page->prev = (uintptr_t) &slots[slot] | SLAB_SMALL;

            slots[slot].next = page;

            p = ((page - pool->pages) << pagesize_shift) + s * n;
            p += (uintptr_t)pool->start;
            goto done;

起初一直看不明白第296行代码的 n = (1 << (pagesize_shift - shift)) / 8 / s; 是做什么的,你想一下,1<<pagesize_shift - shift)是一个page内能容纳对象的个数,对象的大小是1<<shift,拿个数除以大小本身有什么作用?越想就越懵了,回头看前面内存分配时的代码,也没什么可参考的地方,内存分配时的实现写的比较简洁和易懂

这里最主要的作用其实是计算bitmap要占用多少个对象的空间,为什么要这么做?是因为它管理内存的数据结构是放在被管理的内存区域上的,这种方法很原始确是真正意义上的内存管理,和内核管理内存的思想很类似。

BTW:这居然是nginx的代码

Leave a Comment