UWord erts_gfalc_test(UWord op, UWord a1, UWord a2) { switch (op) { case 0x100: return (UWord) BKT_IX((GFAllctr_t *) a1, (Uint) a2); case 0x101: return (UWord) BKT_MIN_SZ((GFAllctr_t *) a1, (int) a2); case 0x102: return (UWord) NO_OF_BKTS; case 0x103: return (UWord) find_bucket(&((GFAllctr_t *) a1)->bucket_mask, (int) a2); default: ASSERT(0); return ~((UWord) 0); } }
unsigned long erts_gfalc_test(unsigned long op, unsigned long a1, unsigned long a2) { switch (op) { case 0x100: return (unsigned long) BKT_IX((GFAllctr_t *) a1, (Uint) a2); case 0x101: return (unsigned long) BKT_MIN_SZ((GFAllctr_t *) a1, (int) a2); case 0x102: return (unsigned long) NO_OF_BKTS; case 0x103: return (unsigned long) find_bucket(&((GFAllctr_t *) a1)->bucket_mask, (int) a2); default: ASSERT(0); return ~((unsigned long) 0); } }
static Block_t * search_bucket(Allctr_t *allctr, int ix, Uint size) { int i; Uint min_sz; Uint blk_sz; Uint cand_sz = 0; UWord max_blk_search; GFFreeBlock_t *blk; GFFreeBlock_t *cand = NULL; int blk_on_lambc; int cand_on_lambc = 0; GFAllctr_t *gfallctr = (GFAllctr_t *) allctr; ASSERT(0 <= ix && ix <= NO_OF_BKTS - 1); if (!gfallctr->buckets[ix]) return NULL; min_sz = BKT_MIN_SZ(gfallctr, ix); if (min_sz < size) min_sz = size; max_blk_search = gfallctr->max_blk_search; for (blk = gfallctr->buckets[ix], i = 0; blk && i < max_blk_search; blk = blk->next, i++) { blk_sz = MBC_FBLK_SZ(&blk->block_head); blk_on_lambc = (((char *) blk) < gfallctr->last_aux_mbc_end && gfallctr->last_aux_mbc_start <= ((char *) blk)); if (blk_sz == min_sz && !blk_on_lambc) return (Block_t *) blk; if (blk_sz >= min_sz && (!cand || (!blk_on_lambc && (cand_on_lambc || blk_sz < cand_sz)) || (blk_on_lambc && cand_on_lambc && blk_sz < cand_sz))) { cand_sz = blk_sz; cand = blk; cand_on_lambc = blk_on_lambc; } } return (Block_t *) cand; }
void testcase_run(TestCaseState_t *tcs) { void *tmp; void **fence; void **blk; Ulong sz; Ulong smbcs; int i; int bi; int bi_tests; Ulong sbct = (SBCT/1024)*1024; Ulong min_blk_sz; Ulong ablk_hdr_sz = ABLK_HDR_SZ; char smbcs_buf[30]; char sbct_buf[30]; int no_bkts = (int) NO_OF_BKTS; char *argv1[] = {"-tasgf", "-tmmbcs0", sbct_buf, NULL}; char *argv2[] = {"-tasgf", "-tmmbcs0", sbct_buf, NULL, NULL}; Allctr_t *a; sprintf(sbct_buf, "-tsbct%lu", sbct/1024); a = START_ALC("bkt_mask_1_", 0, argv1); tcs->extra = (void *) a; ASSERT(tcs, a); min_blk_sz = MIN_BLK_SZ(a); smbcs = 2*(no_bkts*sizeof(void *) + min_blk_sz) + min_blk_sz; for (i = 0; i < no_bkts; i++) { sz = BKT_MIN_SZ(a, i); if (sz >= sbct) break; smbcs += sz + min_blk_sz; } bi_tests = i; testcase_printf(tcs, "Will test %d buckets\n", bi_tests); STOP_ALC(a); tcs->extra = NULL; smbcs /= 1024; smbcs++; testcase_printf(tcs, "smbcs = %lu\n", smbcs); sprintf(smbcs_buf, "-tsmbcs%lu", smbcs); argv2[3] = smbcs_buf; a = START_ALC("bkt_mask_2_", 0, argv2); tcs->extra = (void *) a; ASSERT(tcs, a); blk = (void **) ALLOC(a, no_bkts*sizeof(void *)); fence = (void **) ALLOC(a, no_bkts*sizeof(void *)); ASSERT(tcs, blk && fence); testcase_printf(tcs, "Allocating blocks and fences\n"); for (i = 0; i < bi_tests; i++) { sz = BKT_MIN_SZ(a, i); blk[i] = ALLOC(a, sz - ablk_hdr_sz); fence[i] = ALLOC(a, 1); ASSERT(tcs, blk[i] && fence[i]); } tmp = (void *) UMEM2BLK(fence[bi_tests - 1]); tmp = (void *) NXT_BLK((Block_t *) tmp); ASSERT(tcs, IS_LAST_BLK(tmp)); sz = BLK_SZ((Block_t *) tmp); testcase_printf(tcs, "Allocating leftover size = %lu\n", sz); tmp = ALLOC(a, sz - ablk_hdr_sz); ASSERT(tcs, tmp); bi = FIND_BKT(a, 0); ASSERT(tcs, bi < 0); for (i = 0; i < bi_tests; i++) { sz = BKT_MIN_SZ(a, i); testcase_printf(tcs, "Testing bucket %d\n", i); FREE(a, blk[i]); bi = FIND_BKT(a, i); ASSERT(tcs, bi == i); blk[i] = ALLOC(a, sz - ablk_hdr_sz); bi = FIND_BKT(a, i); ASSERT(tcs, bi != i); } for (i = 0; i < bi_tests; i++) { FREE(a, blk[i]); FREE(a, fence[i]); } FREE(a, (void *) blk); FREE(a, (void *) fence); bi = FIND_BKT(a, 0); ASSERT(tcs, bi == no_bkts - 1); FREE(a, tmp); bi = FIND_BKT(a, 0); ASSERT(tcs, bi < 0); STOP_ALC(a); tcs->extra = NULL; }