Beispiel #1
0
void* slab_alloc(size_t sz)
{
    meta_t* meta;
    page_t* page;
    list_head_t* head;
    void* memory;

    if (sz == 0) return NULL;
    sz = SLAB_ALIGN(sz);

    // try different list, if exceeds max return null
    head = _slab_free_page(sz);
    if (!head) return NULL;

    // alloc from free page
    list_for_each_entry(page, page_t, head, link) {
        memory = _slab_alloc(page, head, sz);
        if (memory) return memory;
    }
Beispiel #2
0
void *mprSlabAllocBlock(MPR_LOC_DEC(ctx, loc), uint size, uint inc)
{

#if NO_SLAB
    return mprAllocBlock(MPR_LOC_PASS(ctx, loc), size);
#else

    MprBlk			*parent, *bp;
    MprSlabBlock	*sb;
    MprApp			*app;
    MprSlab			*slab;
    int				slabIndex;

    if (ctx == 0) {
        mprAssert(ctx);
        return 0;
    }

    mprAssert(size > 0);
    mprAssert(VALID_BLK(ctx));

    parent = GET_HDR(ctx);
    mprAssert(VALID_HDR(parent));

    CHECK_HDR(parent);

    size = SLAB_ALIGN(size);

    app = parent->app;
    mprAssert(app);

    slabIndex = GET_SLAB(size);

    if (slabIndex < 0 || slabIndex >= MPR_MAX_SLAB) {
        return mprAllocBlock(MPR_LOC_PASS(ctx, loc), size);
    }

    /*
     *	Dequeue a block from the slab. "sb" will point to the user data
     *	portion of the block (i.e. after the MprBlk header). Slabs must be
     *	allocated off the "slabs" context to ensure they don't get freed
     *	until after all other blocks are freed.
     */
    mprLock(app->allocLock);
    slab = &app->alloc.slabs[slabIndex];
    if ((sb = slab->next) == 0) {
        if (growSlab(MPR_LOC_ARGS(parent->app->alloc.slabs),
                     slab, size, inc) < 0) {
            mprUnlock(app->allocLock);
            return 0;
        }
        sb = slab->next;
    }
    mprAssert(sb);

    /*
     *	Dequeue the block
     */
    slab->next = sb->next;

#if BLD_FEATURE_ALLOC_STATS
    {
        MprSlabStats	*slabStats;
        /*
         *	Update the slab stats
         */
        slabStats = &slab->stats;
        slabStats->totalAllocCount++;
        slabStats->freeCount--;
        slabStats->allocCount++;
        if (slabStats->allocCount > slabStats->peakAllocCount) {
            slabStats->peakAllocCount = slabStats->allocCount;
        }
    }
#endif /* BLD_FEATURE_ALLOC_STATS */

    bp = GET_HDR(sb);

#if BLD_DEBUG && !BREW
    if (bp == stopAlloc) {
        mprBreakpoint(MPR_LOC, "breakOnAddr");
    }
#endif

    bp->size = size;
    bp->flags = ALLOC_MAGIC | ALLOC_FLAGS_SLAB_BLOCK;
    bp->destructor = 0;

    bp->parent = parent;

    if (parent->children == 0) {
        parent->children = bp;
        bp->next = bp->prev = bp;

    } else {
        /*
         *	Append to the end of the list. Preserve alloc order
         */
        bp->next = parent->children;
        bp->prev = parent->children->prev;
        parent->children->prev->next = bp;
        parent->children->prev = bp;
    }

    bp->children = 0;

    bp->app = app;

#if BLD_FEATURE_ALLOC_LEAK_TRACK
    bp->location = loc;
#endif
    mprUnlock(app->allocLock);

    return GET_PTR(bp);
#endif
}