/**
 * 为slabclass[id]分配一个新的slab,成功返回1,否则返回0
 * 
 * 1. 确定slab的长度len
 * 2. 分配len大小的内存(预分配的内存中划分或者调malloc()分配)
 * 3. 把所分配的内存初始化成item链表,链接到slabclass[id]的slot中
 * 4. slabclass[i]属性的更新:slabs数增1
 * 5. 已分配内存数的更新
 */
static int do_slabs_newslab(const unsigned int id) {
    slabclass_t *p = &slabclass[id]; //指向第i个slabclass
    int len = settings.slab_reassign ? settings.item_size_max //是否开启可自定slab大小,否则使用默认的大小1M
        : p->size * p->perslab;
    char *ptr;
	//grow_slab_list初始化slabclass的slab_list,而slab_list中的指针指向每个slab  
    //memory_allocate从内存池申请1M的空间  
    if ((mem_limit && mem_malloced + len > mem_limit && p->slabs > 0) ||
        (grow_slab_list(id) == 0) ||
        ((ptr = memory_allocate((size_t)len)) == 0)) {

        MEMCACHED_SLABS_SLABCLASS_ALLOCATE_FAILED(id);
        return 0;
    }

    memset(ptr, 0, (size_t)len);
	//将申请到的1M空间按照slabclass的size进行切分
    split_slab_page_into_freelist(ptr, id);

    p->slab_list[p->slabs++] = ptr;//循环分配
    mem_malloced += len;
    MEMCACHED_SLABS_SLABCLASS_ALLOCATE(id);

    return 1;
}
Пример #2
0
static int do_slabs_newslab(const unsigned int id) {
    slabclass_t *p = &slabclass[id];
#ifdef ALLOW_SLABS_REASSIGN
    int len = POWER_BLOCK;
#else
    int len = p->size * p->perslab;
#endif
    char *ptr;

    if ((mem_limit && mem_malloced + len > mem_limit && p->slabs > 0) ||
        (grow_slab_list(id) == 0) ||
        ((ptr = memory_allocate((size_t)len)) == 0)) {

        MEMCACHED_SLABS_SLABCLASS_ALLOCATE_FAILED(id);
        return 0;
    }

    memset(ptr, 0, (size_t)len);
    p->end_page_ptr = ptr;
    p->end_page_free = p->perslab;

    p->slab_list[p->slabs++] = ptr;
    mem_malloced += len;

    MEMCACHED_SLABS_SLABCLASS_ALLOCATE(id);
    return 1;
}
Пример #3
0
//slabclass_t中slab的数目是慢慢增多的。该函数的作用就是为slabclass_t申请多一个slab  
//参数id指明是slabclass数组中的那个slabclass_t 
static int do_slabs_newslab(const unsigned int id) {
    slabclass_t *p = &slabclass[id];

    //settings.slab_reassign的默认值为false,这里就采用false
    int len = settings.slab_reassign ? settings.item_size_max
        : p->size * p->perslab;//其积 <= settings.item_size_max
    char *ptr;

    //mem_malloced的值通过环境变量设置,默认为0 
    if ((mem_limit && mem_malloced + len > mem_limit && p->slabs > 0) ||
        (grow_slab_list(id) == 0) ||//增长slab_list(失败返回0)。一般都会成功,除非无法分配内存
        ((ptr = memory_allocate((size_t)len)) == 0)) {//分配len字节内存(也就是一个页)

        MEMCACHED_SLABS_SLABCLASS_ALLOCATE_FAILED(id);
        return 0;
    }

    memset(ptr, 0, (size_t)len);//清零内存块是必须的
    //将这块内存切成一个个的item,当然item的大小有id所控制
    split_slab_page_into_freelist(ptr, id);

    //将分配得到的内存页交由slab_list掌管
    p->slab_list[p->slabs++] = ptr;
    mem_malloced += len;
    MEMCACHED_SLABS_SLABCLASS_ALLOCATE(id);

    return 1;
}
Пример #4
0
static int do_slabs_newslab(const unsigned int id) {
    slabclass_t *p = &slabclass[id];
    slabclass_t *g = &slabclass[SLAB_GLOBAL_PAGE_POOL];
    int len = settings.slab_reassign ? settings.item_size_max
        : p->size * p->perslab;
    char *ptr;

    if ((mem_limit && mem_malloced + len > mem_limit && p->slabs > 0
         && g->slabs == 0)) {
        mem_limit_reached = true;
        MEMCACHED_SLABS_SLABCLASS_ALLOCATE_FAILED(id);
        return 0;
    }

    if ((grow_slab_list(id) == 0) ||
        (((ptr = get_page_from_global_pool()) == NULL) &&
        ((ptr = memory_allocate((size_t)len)) == 0))) {

        MEMCACHED_SLABS_SLABCLASS_ALLOCATE_FAILED(id);
        return 0;
    }

    memset(ptr, 0, (size_t)len);
    split_slab_page_into_freelist(ptr, id);

    p->slab_list[p->slabs++] = ptr;
    MEMCACHED_SLABS_SLABCLASS_ALLOCATE(id);

    return 1;
}
Пример #5
0
static int do_slabs_newslab(const unsigned int id) {
    slabclass_t *p = &slabclass[id];
    int len = settings.slab_reassign ? settings.item_size_max
        : p->size * p->perslab;
    char *ptr;

    if ((mem_limit && mem_malloced + len > mem_limit && p->slabs > 0) ||
        (grow_slab_list(id) == 0) ||
        ((ptr = memory_allocate((size_t)len)) == 0)) {

        MEMCACHED_SLABS_SLABCLASS_ALLOCATE_FAILED(id);
        return 0;
    }

    memset(ptr, 0, (size_t)len);
    p->end_page_ptr = ptr;
    p->end_page_free = p->perslab;

    p->slab_list[p->slabs++] = ptr;
#ifdef TEST_CLOCK
    p->clock_max = p->slabs * p->perslab;
#endif
    mem_malloced += len;
    MEMCACHED_SLABS_SLABCLASS_ALLOCATE(id);

    return 1;
}
Пример #6
0
static int do_slabs_newslab(const unsigned int id) {
    slabclass_t *p = &slabclass[id];
    int len = settings.slab_reassign ? settings.item_size_max
        : p->size * p->perslab;
    char *ptr;

    DBG_INFO(DBG_ASSOC_HOPSCOTCH, "%s:%d: mem_limit = %u, len = %u\n",
		__func__, __LINE__, (unsigned int)mem_limit, (unsigned int)len);
    DBG_INFO(DBG_ASSOC_HOPSCOTCH, "%s:%d: p->slabs = %u\n", __func__, __LINE__, p->slabs);
    if ((mem_limit && mem_malloced + len > mem_limit && p->slabs > 0) ||
	(grow_slab_list(id) == 0) ||
	((ptr = memory_allocate((size_t)len)) == 0)) {
        mem_limit_reached = true;
        MEMCACHED_SLABS_SLABCLASS_ALLOCATE_FAILED(id);
	DBG_INFO(DBG_ASSOC_HOPSCOTCH, "%s:%d: mem_limit = %u, mem_malloced = %u, len = %d\n", __func__, __LINE__,
		(unsigned int)mem_limit, (unsigned int)mem_malloced, len);
	DBG_INFO(DBG_ASSOC_HOPSCOTCH, "%s:%d: returning 0\n", __func__, __LINE__);
        return 0;
    }

    memset(ptr, 0, (size_t)len);
	// TODO: Should this be commented?
    split_slab_page_into_freelist(ptr, id);

    p->slab_list[p->slabs++] = ptr;
#ifdef HOPSCOTCH_CLOCK
	p->clock_max = p->slabs * p->perslab;
#endif
    mem_malloced += len;
    MEMCACHED_SLABS_SLABCLASS_ALLOCATE(id);

    return 1;
}
Пример #7
0
static int do_slabs_newslab(struct default_engine *engine, const unsigned int id)
{
    slabclass_t *p = &engine->slabs.slabclass[id];
    int len = p->size * p->perslab;
    char *ptr;

    if ((engine->slabs.mem_limit && engine->slabs.mem_malloced + len > engine->slabs.mem_limit && p->slabs >= p->rsvd_slabs) ||
        (grow_slab_list(engine, id) == 0) ||
        ((ptr = memory_allocate(engine, (size_t)len)) == 0)) {

        MEMCACHED_SLABS_SLABCLASS_ALLOCATE_FAILED(id);
        return 0;
    }

    memset(ptr, 0, (size_t)len);
    p->end_page_ptr = ptr;
    p->end_page_free = p->perslab;

    p->slab_list[p->slabs++] = ptr;
    engine->slabs.mem_malloced += len;

    if ((engine->slabs.mem_limit <= engine->slabs.mem_malloced) ||
        ((engine->slabs.mem_limit - engine->slabs.mem_malloced) < engine->slabs.mem_reserved))
    {
        if (engine->slabs.slabclass[sm_anchor.blck_clsid].rsvd_slabs == 0) { /* undefined */
            /* define the reserved slab count of slab class 0 */
            slabclass_t *z = &engine->slabs.slabclass[sm_anchor.blck_clsid];
            unsigned int additional_slabs = (z->slabs/100) * RESERVED_SLAB_RATIO;
            if (additional_slabs < RESERVED_SLABS)
                additional_slabs = RESERVED_SLABS;
            z->rsvd_slabs = z->slabs + additional_slabs;
            sm_anchor.free_limit_space = (additional_slabs * z->perslab) * sm_anchor.blck_tsize;
            sm_anchor.free_chunk_space = sm_anchor.free_limit_space
                                       + (z->sl_curr + z->end_page_free) * sm_anchor.blck_tsize;
        }
    }
    MEMCACHED_SLABS_SLABCLASS_ALLOCATE(id);

    return 1;
}
Пример #8
0
static int do_slabs_newslab(struct default_engine *engine, const unsigned int id) {
    slabclass_t *p = &engine->slabs.slabclass[id];
    int len = p->size * p->perslab;
    char *ptr;

    if ((engine->slabs.mem_limit && engine->slabs.mem_malloced + len > engine->slabs.mem_limit && p->slabs > 0) ||
        (grow_slab_list(engine, id) == 0) ||
        ((ptr = memory_allocate(engine, (size_t)len)) == 0)) {

        MEMCACHED_SLABS_SLABCLASS_ALLOCATE_FAILED(id);
        return 0;
    }

    memset(ptr, 0, (size_t)len);
    p->end_page_ptr = ptr;
    p->end_page_free = p->perslab;

    p->slab_list[p->slabs++] = ptr;
    engine->slabs.mem_malloced += len;
    MEMCACHED_SLABS_SLABCLASS_ALLOCATE(id);

    return 1;
}