slab.c
void 
kmem_cache_grow(kmem_cache_t cp) {
    void *mem;
    kmem_slab_t slab;
    void *p, *lastbuf;
    int i;
    kmem_bufctl_t bufctl;

    // if this is a small object
    if (cp->size <= SLAB_SMALL_OBJ_SZ) {
        // allocating one page
        if (0 != posix_memalign(&mem, PAGE_SZ, PAGE_SZ))
            return;

        // positioning slab at the end of the page
        slab = mem + PAGE_SZ - sizeof(struct kmem_slab);

        slab->next = slab->prev = slab;        
        slab->bufcount = 0;
        slab->free_list = mem;
        
        // creating linkage
        lastbuf = mem + (cp->effsize * (cp->slab_maxbuf-1));
        for (p=mem; p < lastbuf; p+=cp->effsize) 
             *((void **)p) = p + cp->effsize;

        // complete slab at the front...
        __slab_move_to_front(cp, slab);
        assert(cp->slabs == slab);

        // printf("\n%p\n%p\n%#x\n%#x\n", mem, slab, sizeof(struct kmem_slab), sizeof(struct kmem_cache));
    }
    // if this is a large object
    else {
        // allocating pages
        if (0 != posix_memalign(&mem, PAGE_SZ, (cp->slab_maxbuf * cp->effsize)/PAGE_SZ))
            return;

        // allocating slab
        slab = (kmem_slab_t)malloc(sizeof(struct kmem_slab));
        
        // initializing slab
        slab->next = slab->prev = slab;        
        slab->bufcount = 0;

        bufctl = (kmem_bufctl_t)malloc(sizeof(struct kmem_bufctl) * cp->slab_maxbuf);
        bufctl[0].next = NULL;
        bufctl[0].buf = mem;
        bufctl[0].slab = slab;
        slab->start = &bufctl[0];
        slab->free_list = &bufctl[0];
        // creating addtl bufctls
        for (i=1; i < cp->slab_maxbuf; i++) {
            bufctl[i].next = slab->free_list;
            bufctl[i].buf = mem + (i*cp->effsize + (PAGE_SZ%cp->effsize * (((i+1)*cp->effsize)/PAGE_SZ)));
            bufctl[i].slab = slab;
            slab->free_list = &bufctl[i];
        }

        // complete slab at the front...
        __slab_move_to_front(cp, slab);        

        // printf("\n%p\n%p\n%#x\n%#x\n", mem, slab, sizeof(struct kmem_slab), sizeof(struct kmem_cache));
    }
}
/* Grow a specified cache. Specifically adds one slab to it.

   @cp cache pointer
*/
Grow a specified cache. Specifically adds one slab to it.
Grow a specified cache . Specifically adds one slab to it .
void 
kmem_cache_grow(kmem_cache_t cp) {
    void *mem;
    kmem_slab_t slab;
    void *p, *lastbuf;
    int i;
    kmem_bufctl_t bufctl;
    if (cp->size <= SLAB_SMALL_OBJ_SZ) {
        if (0 != posix_memalign(&mem, PAGE_SZ, PAGE_SZ))
            return;
        slab = mem + PAGE_SZ - sizeof(struct kmem_slab);
        slab->next = slab->prev = slab;        
        slab->bufcount = 0;
        slab->free_list = mem;
        lastbuf = mem + (cp->effsize * (cp->slab_maxbuf-1));
        for (p=mem; p < lastbuf; p+=cp->effsize) 
             *((void **)p) = p + cp->effsize;
        __slab_move_to_front(cp, slab);
        assert(cp->slabs == slab);
    }
    else {
        if (0 != posix_memalign(&mem, PAGE_SZ, (cp->slab_maxbuf * cp->effsize)/PAGE_SZ))
            return;
        slab = (kmem_slab_t)malloc(sizeof(struct kmem_slab));
        slab->next = slab->prev = slab;        
        slab->bufcount = 0;
        bufctl = (kmem_bufctl_t)malloc(sizeof(struct kmem_bufctl) * cp->slab_maxbuf);
        bufctl[0].next = NULL;
        bufctl[0].buf = mem;
        bufctl[0].slab = slab;
        slab->start = &bufctl[0];
        slab->free_list = &bufctl[0];
        for (i=1; i < cp->slab_maxbuf; i++) {
            bufctl[i].next = slab->free_list;
            bufctl[i].buf = mem + (i*cp->effsize + (PAGE_SZ%cp->effsize * (((i+1)*cp->effsize)/PAGE_SZ)));
            bufctl[i].slab = slab;
            slab->free_list = &bufctl[i];
        }
        __slab_move_to_front(cp, slab);        
    }
}
void kmem_cache_grow ( kmem_cache_t cp ) { void * mem ; kmem_slab_t slab ; void * p , * lastbuf ; int i ; kmem_bufctl_t bufctl ; if ( cp -> size <= SLAB_SMALL_OBJ_SZ ) { if ( 0 != posix_memalign ( & mem , PAGE_SZ , PAGE_SZ ) ) return ; slab = mem + PAGE_SZ - sizeof ( struct kmem_slab ) ; slab -> next = slab -> prev = slab ; slab -> bufcount = 0 ; slab -> free_list = mem ; lastbuf = mem + ( cp -> effsize * ( cp -> slab_maxbuf - 1 ) ) ; for ( p = mem ; p < lastbuf ; p += cp -> effsize ) * ( ( void * * ) p ) = p + cp -> effsize ; __slab_move_to_front ( cp , slab ) ; assert ( cp -> slabs == slab ) ; } else { if ( 0 != posix_memalign ( & mem , PAGE_SZ , ( cp -> slab_maxbuf * cp -> effsize ) / PAGE_SZ ) ) return ; slab = ( kmem_slab_t ) malloc ( sizeof ( struct kmem_slab ) ) ; slab -> next = slab -> prev = slab ; slab -> bufcount = 0 ; bufctl = ( kmem_bufctl_t ) malloc ( sizeof ( struct kmem_bufctl ) * cp -> slab_maxbuf ) ; bufctl [ 0 ] . next = NULL ; bufctl [ 0 ] . buf = mem ; bufctl [ 0 ] . slab = slab ; slab -> start = & bufctl [ 0 ] ; slab -> free_list = & bufctl [ 0 ] ; for ( i = 1 ; i < cp -> slab_maxbuf ; i ++ ) { bufctl [ i ] . next = slab -> free_list ; bufctl [ i ] . buf = mem + ( i * cp -> effsize + ( PAGE_SZ % cp -> effsize * ( ( ( i + 1 ) * cp -> effsize ) / PAGE_SZ ) ) ) ; bufctl [ i ] . slab = slab ; slab -> free_list = & bufctl [ i ] ; } __slab_move_to_front ( cp , slab ) ; } }
Grow a specified cache.
Grow a specified cache .
// if this is a small object // allocating one page // positioning slab at the end of the page // creating linkage // complete slab at the front... // printf("\n%p\n%p\n%#x\n%#x\n", mem, slab, sizeof(struct kmem_slab), sizeof(struct kmem_cache)); // if this is a large object // allocating pages // allocating slab // initializing slab // creating addtl bufctls // complete slab at the front... // printf("\n%p\n%p\n%#x\n%#x\n", mem, slab, sizeof(struct kmem_slab), sizeof(struct kmem_cache));