int main(void) { parent_ready = create_cond_var(); int i; thread_t threads[NUM_PARENT_THREADS]; for (i = 0; i < NUM_PARENT_THREADS; ++i) threads[i] = create_thread(parent_func, NULL); /* We setup and start at once to avoid process memory changing much between * the two. */ dr_app_setup_and_start(); wait_cond_var(parent_ready); thread_sleep(50); dr_app_stop_and_cleanup(); parent_exit = true; for (i = 0; i < NUM_PARENT_THREADS; ++i) join_thread(threads[i]); destroy_cond_var(parent_ready); print("all done\n"); return 0; }
int main(int argc, const char *argv[]) { #ifdef UNIX pthread_t thread[num_threads]; #else uintptr_t thread[num_threads]; #endif /* While the start/stop thread only runs 4 iters, the other threads end up * running more and their trace files get up to 65MB or more, with the * merged result several GB's: too much for a test. We thus cap each thread. */ if (!my_setenv("DYNAMORIO_OPTIONS", "-stderr_mask 0xc -client_lib ';;" "-offline -max_trace_size 256K'")) std::cerr << "failed to set env var!\n"; burst_owner_finished = create_cond_var(); for (uint i = 0; i < num_threads; i++) { #ifdef UNIX pthread_create(&thread[i], NULL, thread_func, (void *)(uintptr_t)i); #else thread[i] = _beginthreadex(NULL, 0, thread_func, (void *)(uintptr_t)i, 0, NULL); #endif } for (uint i = 0; i < num_threads; i++) { #ifdef UNIX pthread_join(thread[i], NULL); #else WaitForSingleObject((HANDLE)thread[i], INFINITE); #endif } for (int i = 0; i < num_threads; ++i) { if (!finished[i]) std::cerr << "thread " << i << " failed to finish\n"; } std::cerr << "all done\n"; destroy_cond_var(burst_owner_finished); return 0; }