/* ``Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' * * $Id$ */ #include "erl_int_sizes_config.h" #include "testcase_driver.h" #include "allocator_test.h" #include #if defined(__WIN32__) && SIZEOF_VOID_P == 8 /* Use larger threashold for win64 as block alignment is 16 bytes and not 8 */ #define SBCT ((1024*1024)) #else #define SBCT ((512*1024)) #endif char * testcase_name(void) { return "bucket_mask"; } void testcase_cleanup(TestCaseState_t *tcs) { if (tcs->extra) { STOP_ALC(tcs->extra); tcs->extra = NULL; } } void testcase_run(TestCaseState_t *tcs) { typedef struct linked_block { struct linked_block* next; }Linked; Linked* link = NULL; Linked* fence_list; Linked* pad_list; void* tmp; void **blk; Ulong sz; Ulong residue; 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 = (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 *)); ASSERT(tcs, blk); fence_list = NULL; 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); link = (Linked*) ALLOC(a, sizeof(Linked)); ASSERT(tcs, blk[i] && link); link->next = fence_list; fence_list = link; } pad_list = 0; do { tmp = (void *) UMEM2BLK(link); /* last allocated */ tmp = (void *) NXT_BLK((Block_t *) tmp); ASSERT(tcs, IS_LAST_BLK(tmp)); sz = BLK_SZ((Block_t *) tmp); if (sz >= sbct) { residue = sz; sz = sbct - min_blk_sz; residue -= sz; } else { residue = 0; } testcase_printf(tcs, "Allocating leftover size = %lu, residue = %lu\n", sz, residue); link = (Linked*) ALLOC(a, sz - ablk_hdr_sz); ASSERT(tcs, link); link->next = pad_list; pad_list = link; } while (residue); 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]); } while (fence_list) { link = fence_list; fence_list = link->next; FREE(a, link); } FREE(a, (void *) blk); bi = FIND_BKT(a, 0); ASSERT(tcs, bi == no_bkts - 1); while (pad_list) { link = pad_list; pad_list = link->next; FREE(a, link); } bi = FIND_BKT(a, 0); ASSERT(tcs, bi < 0); STOP_ALC(a); tcs->extra = NULL; } ERL_NIF_INIT(bucket_mask, testcase_nif_funcs, testcase_nif_init, NULL, NULL, NULL);