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); }
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); }
void testcase_run(TestCaseState_t *tcs) { #ifdef __WIN32__ testcase_skipped(tcs, "Nothing to test; not supported on windows."); #else int i, r; void *tres[NO_OF_THREADS]; thr_arg_t ta[NO_OF_THREADS]; erl_thread_t t1; die = 0; cw_passed = 0; for (i = 0; i < NO_OF_THREADS; i++) need_join[i] = 0; res_tf0 = 17; res_tf1 = 17; cnd = mtx = NULL; /* Create mutex and cond */ mtx = erts_mutex_create(); ASSERT(tcs, mtx); cnd = erts_cond_create(); ASSERT(tcs, cnd); /* Create the threads */ ta[0].n = 0; r = erts_thread_create(&tid[0], tf0, (void *) &ta[0], 0); ASSERT(tcs, r == 0); need_join[0] = 1; ta[1].n = 1; r = erts_thread_create(&tid[1], tf1, (void *) &ta[1], 0); ASSERT(tcs, r == 0); need_join[1] = 1; /* Make sure the threads waits on cond wait */ sleep(1); r = erts_mutex_lock(mtx); ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); ASSERT_CLNUP(tcs, cw_passed == 0, (void) erts_mutex_unlock(mtx)); /* Let one thread pass one cond wait */ r = erts_cond_signal(cnd); ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); r = erts_mutex_unlock(mtx); ASSERT(tcs, r == 0); sleep(1); r = erts_mutex_lock(mtx); ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); ASSERT_CLNUP(tcs, cw_passed == 1, (void) erts_mutex_unlock(mtx)); /* Let both threads pass one cond wait */ r = erts_cond_broadcast(cnd); ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); r = erts_mutex_unlock(mtx); ASSERT(tcs, r == 0); sleep(1); r = erts_mutex_lock(mtx); ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); ASSERT_CLNUP(tcs, cw_passed == 3, (void) erts_mutex_unlock(mtx)); /* Let the thread that only have passed one cond wait pass the other one */ r = erts_cond_signal(cnd); ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); r = erts_mutex_unlock(mtx); ASSERT(tcs, r == 0); sleep(1); r = erts_mutex_lock(mtx); ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); ASSERT_CLNUP(tcs, cw_passed == 4, (void) erts_mutex_unlock(mtx)); /* Both threads should have passed both cond waits and exited; join them and check returned values */ r = erts_thread_join(tid[0], &tres[0]); ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); need_join[0] = 0; ASSERT_CLNUP(tcs, tres[0] == &res_tf0, (void) erts_mutex_unlock(mtx)); ASSERT_CLNUP(tcs, res_tf0 == 0, (void) erts_mutex_unlock(mtx)); r = erts_thread_join(tid[1], &tres[1]); ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); need_join[1] = 0; ASSERT_CLNUP(tcs, tres[1] == &res_tf1, (void) erts_mutex_unlock(mtx)); ASSERT_CLNUP(tcs, res_tf1 == 1, (void) erts_mutex_unlock(mtx)); /* Test signaling when noone waits */ r = erts_cond_signal(cnd); ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); /* Test broadcasting when noone waits */ r = erts_cond_broadcast(cnd); ASSERT_CLNUP(tcs, r == 0, (void) erts_mutex_unlock(mtx)); /* erts_cond_timedwait() not supported anymore */ r = erts_cond_timedwait(cnd, mtx, 1000); ASSERT_CLNUP(tcs, r != 0, (void) erts_mutex_unlock(mtx)); ASSERT_CLNUP(tcs, strcmp(erl_errno_id(r), "enotsup") == 0, (void) erts_mutex_unlock(mtx)); r = erts_mutex_unlock(mtx); ASSERT(tcs, r == 0); r = erts_mutex_destroy(mtx); ASSERT(tcs, r == 0); mtx = NULL; r = erts_cond_destroy(cnd); ASSERT(tcs, r == 0); cnd = NULL; /* ... */ t1 = erts_thread_self(); if (cw_passed == 4711) { /* We don't want to execute this just check that the symbol/symbols is/are defined */ erts_thread_kill(t1); } #endif /* #ifndef __WIN32__ */ }