/* * alloc_class_from_params -- (internal) creates a new allocation class */ static struct alloc_class * alloc_class_from_params(struct alloc_class_collection *ac, enum alloc_class_type type, size_t unit_size, unsigned unit_max, unsigned unit_max_alloc, uint32_t size_idx) { struct alloc_class c; c.unit_size = unit_size; c.header_type = HEADER_COMPACT; c.type = type; switch (type) { case CLASS_HUGE: c.id = DEFAULT_ALLOC_CLASS_ID; break; case CLASS_RUN: alloc_class_generate_run_proto(&c.run, unit_size, size_idx); uint8_t slot; if (alloc_class_find_first_free_slot(ac, &slot) != 0) { return NULL; } c.id = slot; break; default: ASSERT(0); } return alloc_class_register(ac, &c); }
static void test_alloc_class_bitmap_correctness(void) { struct alloc_class_run_proto proto; alloc_class_generate_run_proto(&proto, RUNSIZE / 10, 1); /* 54 set (not available for allocations), and 10 clear (available) */ uint64_t bitmap_lastval = 0b1111111111111111111111111111111111111111111111111111110000000000; UT_ASSERTeq(proto.bitmap_lastval, bitmap_lastval); }
/* * 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; }