Beispiel #1
0
static void
alloc_op(TestCaseState_t *tcs, Allctr_t *a, block *bp, int id, int clean_up)
{
    if(bp->p)
	CHECK_BLOCK_DATA(tcs, bp->p, bp->s, id);

    if(bp->as[bp->i] == 0 || clean_up) {
	FREE(a, bp->p);
#ifdef PRINT_ALLOC_OPS
	testcase_printf(tcs, "FREE(0x%lx) [id=%d]\n", (Ulong) bp->p, id);
#endif
	bp->p = NULL;
	bp->s = 0;
	bp->i = 0; /* start from the beginning again */
	return;
    }

    if(!bp->p) {
	bp->s = bp->as[bp->i];
	bp->p = (unsigned char *) ALLOC(a, bp->s);
#ifdef PRINT_ALLOC_OPS
	testcase_printf(tcs, "0x%lx = ALLOC(%lu) [id=%d]\n",
			(Ulong) bp->p, bp->s, id);
#endif
	if(!bp->p)
	    testcase_failed(tcs, "ALLOC(%lu) failed [id=%d])\n", bp->s, id);
	memset((void *) bp->p, id, (size_t) bp->s);
    }
    else {
	unsigned char *p = (unsigned char *) REALLOC(a, bp->p, bp->as[bp->i]);
#ifdef PRINT_ALLOC_OPS
	testcase_printf(tcs, "0x%lx = REALLOC(0x%lx, %lu) [id=%d]\n",
			(Ulong) p, (Ulong) bp->p, bp->as[bp->i], id);
#endif
	if(!p) {
	    testcase_failed(tcs, "REALLOC(0x%lx, %lu) failed [id=%d]\n",
			    (Ulong) bp->p, bp->as[bp->i], id);
	}

	if(bp->s < bp->as[bp->i]) {
	    CHECK_BLOCK_DATA(tcs, p, bp->s, id);
	    memset((void *) p, id, (size_t) bp->as[bp->i]);
	}
	else
	    CHECK_BLOCK_DATA(tcs, p, bp->as[bp->i], id);

	bp->s = bp->as[bp->i];
	bp->p = p;
    }

    bp->i++;
}
Beispiel #2
0
static void
test_free(TestCaseState_t *tcs, Allctr_t *a, Ulong bsz)
{
    Block_t *blk;
    void *p[7];

    testcase_printf(tcs," --- Testing free() with block size %lu ---\n",bsz);

    setup_sequence(tcs, a, bsz, 7, p);

    check_ablk(tcs, a, p[0], bsz);
    check_ablk(tcs, a, p[1], bsz);
    check_ablk(tcs, a, p[2], bsz);
    check_ablk(tcs, a, p[3], bsz);
    check_ablk(tcs, a, p[4], bsz);
    check_ablk(tcs, a, p[5], bsz);
    check_ablk(tcs, a, p[6], bsz);

    /* Coalescing with previous block */
    FREE(a, p[2]);
    FREE(a, p[3]); 

    blk = NXT_BLK(UMEM2BLK(p[1]));
    ASSERT(tcs, IS_FREE_BLK(blk));
    ASSERT(tcs, NXT_BLK(blk) == UMEM2BLK(p[4]));

    /* Coalescing with next block */

    FREE(a, p[1]);
    blk = NXT_BLK(UMEM2BLK(p[0]));
    ASSERT(tcs, IS_FREE_BLK(blk));
    ASSERT(tcs, NXT_BLK(blk) == UMEM2BLK(p[4]));
    
    /* Coalescing with next and previous block */

    FREE(a, p[5]);
    FREE(a, p[4]);

    blk = NXT_BLK(UMEM2BLK(p[0]));
    ASSERT(tcs, IS_FREE_BLK(blk));
    ASSERT(tcs, NXT_BLK(blk) == UMEM2BLK(p[6]));
    
    /* Cleanup */

    FREE(a, p[0]);
    FREE(a, p[6]);

    testcase_printf(tcs," --- free() with block size %lu succeded ---\n",bsz);
}
Beispiel #3
0
void
testcase_run(TestCaseState_t *tcs)
{
    int no_threads, t, c;
    char *block, *p;
    Ulong zcrr_sz;

    if (!IS_SMP_ENABLED)
	testcase_skipped(tcs, "No SMP support");

    alloc = START_ALC("Zero carrier allocator", 1, NULL);

    zcrr_sz = ZERO_CRR_SIZE;

    block = p = ALLOC(alloc, zcrr_sz*TEST_NO_THREADS*TEST_NO_CARRIERS_PER_THREAD);

    ASSERT(tcs, block != NULL);    

    for (t = 0; t < TEST_NO_THREADS; t++) {
	for (c = 0; c < TEST_NO_CARRIERS_PER_THREAD; c++) {
	    Carrier_t *crr = (Carrier_t *) p;
	    p += zcrr_sz;
	    ZERO_CRR_INIT(alloc, crr);
	    threads[t].crr[c] = crr;
	}
    }

    no_threads = 0;
    for (t = 0; t < TEST_NO_THREADS; t++) {
    	threads[t].tid = THR_CREATE(thread_func, (void *) threads[t].crr);
	if (threads[t].tid) {
	    testcase_printf(tcs, "Successfully created thread %d\n", t);
	    no_threads++;
	}
	else {
	    testcase_printf(tcs, "Failed to create thread %d\n", t);
	    break;
	}
    }

    for (t = 0; t < no_threads; t++)
	THR_JOIN(threads[t].tid);

    FATAL_ASSERT(CPOOL_IS_EMPTY(alloc));

    FREE(alloc, block);

    ASSERT(tcs, no_threads == TEST_NO_THREADS);
}
Beispiel #4
0
void
testcase_run(TestCaseState_t *tcs)
{
    char *argv_org[] = {"-tmmbcs1024", "-tsbct2048", "-trmbcmt100", "-tas", NULL, NULL};
    char *alg[] = {"af", "gf", "bf", "aobf", "aoff", NULL};
    int i;

    for (i = 0; alg[i]; i++) {
	Ulong sz;
	Allctr_t *a;
	char *argv[sizeof(argv_org)/sizeof(argv_org[0])];
	memcpy((void *) argv, (void *) argv_org, sizeof(argv_org));

	argv[4] = alg[i];
	testcase_printf(tcs, " *** Starting \"%s\" allocator *** \n", alg[i]);
	a = START_ALC("coalesce_", 0, argv);
	ASSERT(tcs, a);
	tcs->extra = (void *) a;

	sz = MIN_BLK_SZ(a) - ABLK_HDR_SZ;
	test_free(tcs, a, sz);
	sz += 1;
	test_free(tcs, a, sz);
	sz *= 4; 
	test_free(tcs, a, sz);
	sz += 1;
	test_free(tcs, a, sz);
	sz *= 10;
	test_free(tcs, a, sz);

	sz = MIN_BLK_SZ(a)*4 - ABLK_HDR_SZ;
	test_realloc(tcs, a, sz);
	sz += 1;
	test_realloc(tcs, a, sz);
	sz *= 4; 
	test_realloc(tcs, a, sz);
	sz += 1;
	test_realloc(tcs, a, sz);
	sz *= 10;
	test_realloc(tcs, a, sz);

	testcase_printf(tcs, " *** Stopping \"%s\" allocator *** \n", alg[i]);
	STOP_ALC(a);
	tcs->extra = NULL;
    }
}
Beispiel #5
0
void
setup_sequence(TestCaseState_t *tcs, Allctr_t *a, Ulong bsz, int no,
	       void *res[])
{
    Carrier_t *c;
    Block_t *blk;
    int i;

    testcase_printf(tcs,
		    "Setting up a sequence of %d blocks of size %lu\n",
		    no, bsz);
    c = FIRST_MBC(a);
    ASSERT(tcs, !NEXT_C(c));
    blk = MBC2FBLK(a, c);
    ASSERT(tcs, IS_LAST_BLK(blk));

    for (i = 0; i < no; i++)
	res[i] = ALLOC(a, bsz);
    for (i = 0; i < no; i++)
	ASSERT(tcs, res[i]);

    testcase_printf(tcs, "Checking that sequence was set up as expected\n");

    for (i = 1; i < no; i++)
	ASSERT(tcs, NXT_BLK(UMEM2BLK(res[i-1])) == UMEM2BLK(res[i]));

    blk = NXT_BLK(UMEM2BLK(res[no-1]));
    ASSERT(tcs, IS_LAST_BLK(blk));

    testcase_printf(tcs, "Sequence ok\n");

    /* If we fail in setup_sequence(), it doesn't mean that something is
       wrong. It is just a faulty assumption in setup_sequence() about
       how blocks are going to be placed.
       Fix setup_sequence()... */
}
Beispiel #6
0
void
testcase_run(TestCaseState_t *tcs)
{
    struct {
	erts_thread tid;
	ThreadData arg;
    } threads[NO_OF_THREADS+1] = {{0}};
    int no_threads;
    int i;
    char sbct_buf[10];
    char *argv_org[] = {"-tasaobf", "-tmmsbc5000", "-tmmmbc5000", "-tsbct",
			&sbct_buf[0], NULL};
    char *argv[sizeof(argv_org)/sizeof(argv_org[0])];

    if (!IS_THREADS_ENABLED)
	testcase_skipped(tcs, "Threads not enabled");

    alloc_not_ts = NULL;
    alloc_ts_1 = NULL;
    alloc_ts_2 = NULL;

    err_buf[0] = '\0';

    sprintf(sbct_buf, "%d", SBC_THRESHOLD/1024);
    
    memcpy((void *) argv, argv_org, sizeof(argv_org));
    alloc_not_ts = START_ALC("threads_not_ts", 0, argv);
    ASSERT(tcs, alloc_not_ts);
    memcpy((void *) argv, argv_org, sizeof(argv_org));
    alloc_ts_1 = START_ALC("threads_ts_1", 1, argv);
    ASSERT(tcs, alloc_ts_1);
    memcpy((void *) argv, argv_org, sizeof(argv_org));
    alloc_ts_2 = START_ALC("threads_ts_2", 1, argv);
    ASSERT(tcs, alloc_ts_2);

    ASSERT(tcs, !IS_ALLOC_THREAD_SAFE(alloc_not_ts));
    ASSERT(tcs, IS_ALLOC_THREAD_SAFE(alloc_ts_1));
    ASSERT(tcs, IS_ALLOC_THREAD_SAFE(alloc_ts_2));

    tc_mutex = THR_MTX_CREATE();
    tc_cond = THR_COND_CREATE();

    THR_MTX_LOCK(tc_mutex);

    dead_thread_no = -1;
    no_threads = 0;

    for(i = 1; i <= NO_OF_THREADS; i++) {
	char *alc;

	threads[i].arg.no_ops_per_bl = NO_OF_OPS_PER_BL;

	if (i == 1) {
	    alc = "threads_not_ts";
	    threads[i].arg.no_ops_per_bl *= 2;
	    threads[i].arg.a = alloc_not_ts;
	}
	else if (i % 2 == 0) {
	    alc = "threads_ts_1";
	    threads[i].arg.a = alloc_ts_1;
	}
	else {
	    alc = "threads_ts_2";
	    threads[i].arg.a = alloc_ts_2;
	}
	threads[i].arg.t_no = i;

	threads[i].tid = THR_CREATE(thread_func, (void *) &threads[i].arg);
	if (threads[i].tid) {
	    testcase_printf(tcs, "Successfully created thread %d "
			    "using %s_alloc\n", i, alc);
	    no_threads++;
	}
	else {
	    tc_failed = 1;
	    sprintf(err_buf, "Failed to create thread %d\n", i);
	    break;
	}

    }

    while (no_threads) {
	THR_COND_WAIT(tc_cond, tc_mutex);
	if (dead_thread_no >= 0) {
	    no_threads--;
	    THR_JOIN(threads[dead_thread_no].tid);
	    testcase_printf(tcs, "Thread %d died\n", dead_thread_no);
	    dead_thread_no = -1;
	    THR_COND_BCAST(tc_cond);
	}
    }

    THR_MTX_UNLOCK(tc_mutex);
    THR_MTX_DESTROY(tc_mutex);
    THR_COND_DESTROY(tc_cond);

    stop_allocators();

    if (tc_failed)
	testcase_failed(tcs, "%s", err_buf);
}
Beispiel #7
0
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;
}
Beispiel #8
0
static void
test_realloc(TestCaseState_t *tcs, Allctr_t *a, Ulong bsz)
{
    Block_t *blk;
    void *ptr;
    void *p[3];
    Ulong nbsz;

    testcase_printf(tcs," --- Testing realloc() with block size %lu ---\n",
		    bsz);

    setup_sequence(tcs, a, bsz, 3, p);

    check_ablk(tcs, a, p[0], bsz);
    check_ablk(tcs, a, p[1], bsz);
    check_ablk(tcs, a, p[2], bsz);

    /* Grow to the end of the carrier */
    blk = NXT_BLK(UMEM2BLK(p[2]));
    ASSERT(tcs, IS_FREE_BLK(blk));
    ASSERT(tcs, IS_LAST_BLK(blk));
    nbsz = bsz + BLK_SZ(blk);
    ptr = REALLOC(a, p[2], nbsz);
    ASSERT(tcs, p[2] == ptr);
    check_ablk(tcs, a, p[2], nbsz);
    blk = UMEM2BLK(p[2]);
    ASSERT(tcs, IS_LAST_BLK(blk));

    /* Shrink from the end of the carrier */
    ptr = REALLOC(a, p[2], bsz);
    ASSERT(tcs, p[2] == ptr);
    blk = UMEM2BLK(p[2]);
    ASSERT(tcs, !IS_LAST_BLK(blk));
    blk = NXT_BLK(blk);
    ASSERT(tcs, IS_LAST_BLK(blk));
    check_ablk(tcs, a, p[2], bsz);

    /* Shrink and coalecse with next free */

    FREE(a, p[1]);

    blk = NXT_BLK(UMEM2BLK(p[0]));
    ASSERT(tcs, IS_FREE_BLK(blk));

    nbsz = bsz/2;
    ptr = REALLOC(a, p[0], nbsz);
    ASSERT(tcs, p[0] == ptr);

    check_ablk(tcs, a, p[0], nbsz);

    blk = NXT_BLK(UMEM2BLK(p[0]));
    ASSERT(tcs, IS_FREE_BLK(blk));
    ASSERT(tcs, NXT_BLK(blk) == UMEM2BLK(p[2]));

    /* Grow into next free; but leave free block at end */

    nbsz *= 3;
    ptr = REALLOC(a, p[0], nbsz);
    ASSERT(tcs, p[0] == ptr);

    check_ablk(tcs, a, p[0], nbsz);
    blk = NXT_BLK(UMEM2BLK(p[0]));

    ASSERT(tcs, IS_FREE_BLK(blk));
    ASSERT(tcs, NXT_BLK(blk) == UMEM2BLK(p[2]));

    /* Grow upto next alloced block by allocating just enough so that no
       free block fits between them */
    nbsz = BLK_SZ(blk) + UMEM_SZ(UMEM2BLK(p[0]));
    nbsz -= MIN_BLK_SZ(a) - 1;

    ptr = REALLOC(a, p[0], nbsz);
    ASSERT(tcs, p[0] == ptr);
    check_ablk(tcs, a, p[0], nbsz);
    blk = NXT_BLK(UMEM2BLK(p[0]));
    ASSERT(tcs, !IS_FREE_BLK(blk));
    ASSERT(tcs, blk == UMEM2BLK(p[2]));

    /* Grow into unused part at end */
    nbsz += MIN_BLK_SZ(a) - 1;
    ptr = REALLOC(a, p[0], nbsz);
    ASSERT(tcs, p[0] == ptr);
    check_ablk(tcs, a, p[0], nbsz);
    ASSERT(tcs, !IS_FREE_BLK(blk));
    ASSERT(tcs, blk == UMEM2BLK(p[2]));

    /* Shrink *almost* as much so that a free block would fit between the
       allocated blocks, and make sure that we don't get a free block
       in between */
    nbsz -= MIN_BLK_SZ(a) - 1;
    ptr = REALLOC(a, p[0], nbsz);
    ASSERT(tcs, p[0] == ptr);
    check_ablk(tcs, a, p[0], nbsz);
    blk = NXT_BLK(UMEM2BLK(p[0]));
    ASSERT(tcs, !IS_FREE_BLK(blk));
    ASSERT(tcs, blk == UMEM2BLK(p[2]));

    /* Shrink just as much so that a free block can fit between
       the alloced blocks */
    nbsz -= 1;
    ptr = REALLOC(a, p[0], nbsz);
    ASSERT(tcs, p[0] == ptr);
    check_ablk(tcs, a, p[0], nbsz);
    blk = NXT_BLK(UMEM2BLK(p[0]));
    ASSERT(tcs, IS_FREE_BLK(blk));
    ASSERT(tcs, blk < UMEM2BLK(p[2]));
    ASSERT(tcs, NXT_BLK(blk) == UMEM2BLK(p[2]));

    /* Shrink so little that no free block would fit between allocated
       blocks, and make sure that we shrink the allocated block and
       coalesce the extra free part with the next free block. */
    nbsz -= MIN_BLK_SZ(a) - 1;
    ptr = REALLOC(a, p[0], nbsz);
    ASSERT(tcs, p[0] == ptr);
    check_ablk(tcs, a, p[0], nbsz);
    blk = NXT_BLK(UMEM2BLK(p[0]));
    ASSERT(tcs, IS_FREE_BLK(blk));
    ASSERT(tcs, blk < UMEM2BLK(p[2]));
    ASSERT(tcs, NXT_BLK(blk) == UMEM2BLK(p[2]));

    /* Cleanup */
    FREE(a, p[0]);
    FREE(a, p[2]);

    testcase_printf(tcs, " --- realloc() with block size %lu succeded ---\n",
		    bsz);

}