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++; }
int testcase_assertion_failed(TestCaseState_t *tcs, char *file, int line, char *assertion) { testcase_failed(tcs, "%s:%d: Assertion failed: \"%s\"", file, line, assertion); return 0; }
static void check_block_data(char *file, int line, TestCaseState_t *tcs, unsigned char *p, Ulong sz, int d) { Ulong i; for (i = 0; i < sz; i++) if (p[i] != (unsigned char) d) testcase_failed(tcs, "%s:%d: Data clobbered! found id=%d; " "expected id=%d\n", file, line, (int) p[i], d); }
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); }