/* * alloc_class_register -- registers an allocation classes in the collection */ struct alloc_class * alloc_class_register(struct alloc_class_collection *ac, struct alloc_class *c) { struct alloc_class *nc = Malloc(sizeof(*nc)); if (nc == NULL) goto error_class_alloc; *nc = *c; if (c->type == CLASS_RUN) { size_t map_idx = SIZE_TO_CLASS_MAP_INDEX(nc->unit_size, ac->granularity); ASSERT(map_idx <= UINT32_MAX); uint32_t map_idx_s = (uint32_t)map_idx; ASSERT(nc->run.size_idx <= UINT16_MAX); uint16_t size_idx_s = (uint16_t)nc->run.size_idx; uint16_t header_type_s = (uint16_t)nc->header_type; uint64_t k = RUN_CLASS_KEY_PACK(map_idx_s, header_type_s, size_idx_s); if (cuckoo_insert(ac->class_map_by_unit_size, k, nc) != 0) { ERR("unable to register allocation class"); goto error_map_insert; } } ac->aclasses[nc->id] = nc; return nc; error_map_insert: Free(nc); error_class_alloc: alloc_class_reservation_clear(ac, c->id); return NULL; }
/* * alloc_class_new -- creates a new allocation class */ struct alloc_class * alloc_class_new(int id, struct alloc_class_collection *ac, enum alloc_class_type type, enum header_type htype, size_t unit_size, size_t alignment, uint32_t size_idx) { LOG(10, NULL); struct alloc_class *c = Malloc(sizeof(*c)); if (c == NULL) goto error_class_alloc; c->unit_size = unit_size; c->header_type = htype; c->type = type; c->flags = (uint16_t) (header_type_to_flag[c->header_type] | (alignment ? CHUNK_FLAG_ALIGNED : 0)); switch (type) { case CLASS_HUGE: id = DEFAULT_ALLOC_CLASS_ID; break; case CLASS_RUN: alloc_class_generate_run_proto(&c->run, unit_size, size_idx, alignment); uint8_t slot = (uint8_t)id; if (id < 0 && alloc_class_find_first_free_slot(ac, &slot) != 0) goto error_class_alloc; id = slot; size_t map_idx = SIZE_TO_CLASS_MAP_INDEX(c->unit_size, ac->granularity); ASSERT(map_idx <= UINT32_MAX); uint32_t map_idx_s = (uint32_t)map_idx; ASSERT(c->run.size_idx <= UINT16_MAX); uint16_t size_idx_s = (uint16_t)c->run.size_idx; uint16_t flags_s = (uint16_t)c->flags; uint64_t k = RUN_CLASS_KEY_PACK(map_idx_s, flags_s, size_idx_s); if (cuckoo_insert(ac->class_map_by_unit_size, k, c) != 0) { ERR("unable to register allocation class"); goto error_map_insert; } break; default: ASSERT(0); } c->id = (uint8_t)id; ac->aclasses[c->id] = c; return c; error_map_insert: Free(c); error_class_alloc: if (id >= 0) alloc_class_reservation_clear(ac, id); return NULL; }