/** * 为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; }
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; }
//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; }
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; }
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; }
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; }
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; }
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; }