slab.c
void 
kmem_cache_free(kmem_cache_t cp, void *buf) {
    void * mem;
    kmem_slab_t slab;
    // kmem_bufctl_t bufctl;

    // if this is a small object
    if (cp->size <= SLAB_SMALL_OBJ_SZ) {
        // compute slab position
        // TODO: DO IT GENERIC (PAGE_SZ != 0x1000)
        mem = (void*)((long)buf >> 12 << 12); 
        slab = mem + PAGE_SZ - sizeof(struct kmem_slab);

        // put buffer back in the slab free list
        *((void **)buf) = slab->free_list;
        slab->free_list = buf;

        slab->bufcount--;
    
        // if slab is now complete, discard whole page
        if (slab->bufcount == 0) {
            __slab_remove(cp, slab);
            free(mem);
        }

        // if slab WAS empty, re-add to non-empty slabs
        if (slab->bufcount == cp->slab_maxbuf-1) 
            __slab_move_to_front(cp, slab);

    }
    // if this is a large object
    else {
        // use hash table to get to bufctl

        // ...
        // bufctl = (kmem_cache_t)0x4000;
        // slab = bufctl->slab;
        // put bufctl back in the slab free list
        // bufctl->next = slab->free_list;
        // slab->free_list = bufctl;

        // if slab is now complete, discard whole page
        // if (slab->bufcount == 0) {
        //     __slab_remove(cp, slab);
        //     free(slab->start->buf); // free objects
        //     free(slab->start); // free bufctls
        //     free(slab); // free slab
        // }   
    }
}
/* Frees an allocated object from the cache. 

    @cp cache pointer
    @buf object pointer
*/
Frees an allocated object from the cache.
Frees an allocated object from the cache .
void 
kmem_cache_free(kmem_cache_t cp, void *buf) {
    void * mem;
    kmem_slab_t slab;
    if (cp->size <= SLAB_SMALL_OBJ_SZ) {
        mem = (void*)((long)buf >> 12 << 12); 
        slab = mem + PAGE_SZ - sizeof(struct kmem_slab);
        *((void **)buf) = slab->free_list;
        slab->free_list = buf;
        slab->bufcount--;
        if (slab->bufcount == 0) {
            __slab_remove(cp, slab);
            free(mem);
        }
        if (slab->bufcount == cp->slab_maxbuf-1) 
            __slab_move_to_front(cp, slab);
    }
    else {
    }
}
void kmem_cache_free ( kmem_cache_t cp , void * buf ) { void * mem ; kmem_slab_t slab ; if ( cp -> size <= SLAB_SMALL_OBJ_SZ ) { mem = ( void * ) ( ( long ) buf >> 12 << 12 ) ; slab = mem + PAGE_SZ - sizeof ( struct kmem_slab ) ; * ( ( void * * ) buf ) = slab -> free_list ; slab -> free_list = buf ; slab -> bufcount -- ; if ( slab -> bufcount == 0 ) { __slab_remove ( cp , slab ) ; free ( mem ) ; } if ( slab -> bufcount == cp -> slab_maxbuf - 1 ) __slab_move_to_front ( cp , slab ) ; } else { } }
Frees an allocated object from the cache.
Frees an allocated object from the cache .
// kmem_bufctl_t bufctl; // if this is a small object // compute slab position // TODO: DO IT GENERIC (PAGE_SZ != 0x1000) // put buffer back in the slab free list // if slab is now complete, discard whole page // if slab WAS empty, re-add to non-empty slabs // if this is a large object // use hash table to get to bufctl // ... // bufctl = (kmem_cache_t)0x4000; // slab = bufctl->slab; // put bufctl back in the slab free list // bufctl->next = slab->free_list; // slab->free_list = bufctl; // if slab is now complete, discard whole page // if (slab->bufcount == 0) { //     __slab_remove(cp, slab); //     free(slab->start->buf); // free objects //     free(slab->start); // free bufctls //     free(slab); // free slab // }   