int main(int argc, char** argv) { HANDY_CONFIG_JSON("{\"metrics-dump\":{\"interval\": 20}}"); HANDY_INIT(); run_test_gauge(); run_test_counter(); run_test_scoped_counter(); run_test_timer(); run_test_scoped_timer(); run_test_attr(); int ret = check_tests(argc, argv); HANDY_FINALIZE(); return ret; }
int run_ntttcp_receiver(struct ntttcp_test_endpoint *tep) { int err_code = NO_ERROR; struct ntttcp_test *test = tep->test; char *log = NULL; bool verbose_log = test->verbose; int threads_created = 0; struct ntttcp_stream_server *ss; int rc, t; uint64_t nbytes = 0, total_bytes = 0; struct timeval now; double actual_test_time = 0; struct cpu_usage *init_cpu_usage, *final_cpu_usage; struct tcp_retrans *init_tcp_retrans, *final_tcp_retrans; /* for calculate the resource usage */ init_cpu_usage = (struct cpu_usage *) malloc(sizeof(struct cpu_usage)); if (!init_cpu_usage) { PRINT_ERR("receiver: error when creating cpu_usage struct"); return ERROR_MEMORY_ALLOC; } final_cpu_usage = (struct cpu_usage *) malloc(sizeof(struct cpu_usage)); if (!final_cpu_usage) { free (init_cpu_usage); PRINT_ERR("receiver: error when creating cpu_usage struct"); return ERROR_MEMORY_ALLOC; } /* for calculate the TCP re-transmit */ init_tcp_retrans = (struct tcp_retrans *) malloc(sizeof(struct tcp_retrans)); if (!init_tcp_retrans) { free (init_cpu_usage); free (final_cpu_usage); PRINT_ERR("sender: error when creating tcp_retrans struct"); return ERROR_MEMORY_ALLOC; } final_tcp_retrans = (struct tcp_retrans *) malloc(sizeof(struct tcp_retrans)); if (!final_tcp_retrans) { free (init_cpu_usage); free (final_cpu_usage); free (init_tcp_retrans); PRINT_ERR("sender: error when creating tcp_retrans struct"); return ERROR_MEMORY_ALLOC; } /* create threads */ for (t = 0; t < test->parallel; t++) { ss = tep->server_streams[t]; ss->server_port = test->server_base_port + t; if (test->protocol == TCP) { rc = pthread_create(&tep->threads[t], NULL, run_ntttcp_receiver_tcp_stream, (void*)ss); } else { rc = pthread_create(&tep->threads[t], NULL, run_ntttcp_receiver_udp_stream, (void*)ss); } if (rc) { PRINT_ERR("pthread_create() create thread failed"); err_code = ERROR_PTHREAD_CREATE; continue; } threads_created++; } /* create synch thread */ if (test->no_synch == false) { /* ss struct is not used in sync thread, because: * we are only allowed to pass one param to the thread in pthread_create(); * but the information stored in ss, is not enough to be used for synch; * so we pass *tep to the pthread_create(). * notes: * 1) we will calculate the tcp port for synch stream in create_receiver_sync_socket(). * the synch_port = base_port -1 * 2) we will assign the protocol for synch stream to TCP, always, in create_receiver_sync_socket() */ ss = tep->server_streams[test->parallel]; ss->server_port = test->server_base_port - 1; //just for bookkeeping ss->protocol = TCP; //just for bookkeeping ss->is_sync_thread = 1; rc = pthread_create(&tep->threads[t], NULL, create_receiver_sync_socket, (void*)tep); if (rc) { PRINT_ERR("pthread_create() create thread failed"); err_code = ERROR_PTHREAD_CREATE; } else { threads_created++; } } asprintf(&log, "%d threads created", threads_created); PRINT_DBG_FREE(log); while ( 1 ) { /* for receiver, there are two ways to trigger test start: * a) if synch enabled, then sync thread will trigger loght_on after sync completed; * see create_receiver_sync_socket() * b) if no synch enabled, then any tcp server accept client connections, the ligh_on will be triggered; * see ntttcp_server_epoll(), or ntttcp_server_select() */ wait_light_on(); /* reset server side perf counters at the begining, after light-is-on * this is to handle the case when: receiver in sync mode, but sender connected as no_sync mode * in this case, before loght_no, the threads have some data counted already */ for (t=0; t < threads_created; t++) __atomic_store_n( &(tep->server_streams[t]->total_bytes_transferred), 0, __ATOMIC_SEQ_CST ); get_cpu_usage( init_cpu_usage ); get_tcp_retrans( init_tcp_retrans ); /* run the timer. it will trigger turn_off_light() after timer timeout */ run_test_timer(tep->confirmed_duration); tep->state = TEST_RUNNING; gettimeofday(&now, NULL); tep->start_time = now; /* wait test done */ wait_light_off(); tep->state = TEST_FINISHED; gettimeofday(&now, NULL); tep->end_time = now; /* calculate the actual test run time */ actual_test_time = get_time_diff(&tep->end_time, &tep->start_time); /* calculate resource usage */ get_cpu_usage( final_cpu_usage ); get_tcp_retrans( final_tcp_retrans ); //sleep(1); //looks like server needs more time to receive data ... /* calculate server side throughput */ total_bytes = 0; print_thread_result(-1, 0, 0); for (t=0; t < threads_created; t++){ /* exclude the sync thread */ if (tep->server_streams[t]->is_sync_thread) continue; nbytes = (uint64_t)__atomic_load_n( &(tep->server_streams[t]->total_bytes_transferred), __ATOMIC_SEQ_CST ); total_bytes += nbytes; print_thread_result(t, nbytes, actual_test_time); } print_total_result(tep->test, total_bytes, actual_test_time, init_cpu_usage, final_cpu_usage, init_tcp_retrans, final_tcp_retrans); } /* as receiver threads will keep listening on ports, so they will not exit */ for (t=0; t < threads_created; t++) { pthread_join(tep->threads[t], NULL); } free (init_cpu_usage); free (final_cpu_usage); free (init_tcp_retrans); free (final_tcp_retrans); return err_code; }
int run_ntttcp_sender(struct ntttcp_test_endpoint *tep) { int err_code = NO_ERROR; struct ntttcp_test *test = tep->test; char *log = NULL; bool verbose_log = test->verbose; int threads_created = 0; struct ntttcp_stream_client *cs; int rc, t, n, reply_received; uint64_t nbytes = 0, total_bytes = 0; void *p_retval; struct timeval now; double actual_test_time = 0; struct cpu_usage *init_cpu_usage, *final_cpu_usage; struct tcp_retrans *init_tcp_retrans, *final_tcp_retrans; /* for calculate the resource usage */ init_cpu_usage = (struct cpu_usage *) malloc(sizeof(struct cpu_usage)); if (!init_cpu_usage) { PRINT_ERR("sender: error when creating cpu_usage struct"); return ERROR_MEMORY_ALLOC; } final_cpu_usage = (struct cpu_usage *) malloc(sizeof(struct cpu_usage)); if (!final_cpu_usage) { free (init_cpu_usage); PRINT_ERR("sender: error when creating cpu_usage struct"); return ERROR_MEMORY_ALLOC; } /* for calculate the TCP re-transmit */ init_tcp_retrans = (struct tcp_retrans *) malloc(sizeof(struct tcp_retrans)); if (!init_tcp_retrans) { free (init_cpu_usage); free (final_cpu_usage); PRINT_ERR("sender: error when creating tcp_retrans struct"); return ERROR_MEMORY_ALLOC; } final_tcp_retrans = (struct tcp_retrans *) malloc(sizeof(struct tcp_retrans)); if (!final_tcp_retrans) { free (init_cpu_usage); free (final_cpu_usage); free (init_tcp_retrans); PRINT_ERR("sender: error when creating tcp_retrans struct"); return ERROR_MEMORY_ALLOC; } if (test->no_synch == false ) { /* Negotiate with receiver on: * 1) receiver state: is receiver busy with another test? * 2) submit sender's test duration time to receiver to negotiate * 3) request receiver to start the test */ reply_received = create_sender_sync_socket( tep ); if (reply_received == 0) { PRINT_ERR("sender: failed to create sync socket"); return ERROR_GENERAL; } tep->synch_socket = reply_received; reply_received = query_receiver_busy_state(tep->synch_socket); if (reply_received == -1) { PRINT_ERR("sender: failed to query receiver state"); return ERROR_GENERAL; } if (reply_received == 1) { PRINT_ERR("sender: receiver is busy with another test"); return ERROR_GENERAL; } reply_received = negotiate_test_duration(tep->synch_socket, test->duration); if (reply_received == -1) { PRINT_ERR("sender: failed to negotiate test duration with receiver"); return ERROR_GENERAL; } if (reply_received != test->duration) { asprintf(&log, "test duration negotiated is: %d seconds", reply_received); PRINT_INFO_FREE(log); } tep->confirmed_duration = reply_received; reply_received = request_to_start(tep->synch_socket); if (reply_received == -1) { PRINT_ERR("sender: failed to sync with receiver to start test"); return ERROR_GENERAL; } if (reply_received == 0) { PRINT_ERR("sender: receiver refuse to start test right now"); return ERROR_GENERAL; } /* if we go here, the pre-test sync has completed */ PRINT_INFO("Network activity progressing..."); } else { PRINT_INFO("Starting sender activity (no sync) ..."); } /* create threads */ for (t = 0; t < test->parallel; t++) { for (n = 0; n < test->conn_per_thread; n++ ) { cs = tep->client_streams[t * test->conn_per_thread + n]; /* in client side, multiple connections will (one thread for one connection) * connect to same port on server */ cs->server_port = test->server_base_port + t; /* If sender side is being asked to pin the client source port */ if (test->client_base_port > 0) cs->client_port = test->client_base_port + n * test->parallel + t; if (test->protocol == TCP) { rc = pthread_create(&tep->threads[threads_created], NULL, run_ntttcp_sender_tcp_stream, (void*)cs); } else { rc = pthread_create(&tep->threads[threads_created], NULL, run_ntttcp_sender_udp_stream, (void*)cs); } if (rc) { PRINT_ERR("pthread_create() create thread failed"); err_code = ERROR_PTHREAD_CREATE; continue; } else{ threads_created++; } } } asprintf(&log, "%d threads created", threads_created); PRINT_DBG_FREE(log); turn_on_light(); get_cpu_usage( init_cpu_usage ); get_tcp_retrans( init_tcp_retrans ); /* run the timer. it will trigger turn_off_light() after timer timeout */ run_test_timer(tep->confirmed_duration ); tep->state = TEST_RUNNING; gettimeofday(&now, NULL); tep->start_time = now; /* wait test done */ wait_light_off(); tep->state = TEST_FINISHED; gettimeofday(&now, NULL); tep->end_time = now; /* calculate the actual test run time */ actual_test_time = get_time_diff(&tep->end_time, &tep->start_time); /* * if actual_test_time < tep->confirmed_duration; * then this indicates that in the sender side, test is being interrupted. * hence, tell receiver about this. */ if (actual_test_time < tep->confirmed_duration) { tell_receiver_test_exit(tep->synch_socket); } close(tep->synch_socket); /* calculate resource usage */ get_cpu_usage( final_cpu_usage ); get_tcp_retrans( final_tcp_retrans ); /* calculate client side throughput, but exclude the last thread as it is synch thread */ print_thread_result(-1, 0, 0); for (n = 0; n < threads_created; n++) { if (pthread_join(tep->threads[n], &p_retval) !=0 ) { PRINT_ERR("sender: error when pthread_join"); continue; } nbytes = tep->client_streams[n]->total_bytes_transferred; total_bytes += nbytes; print_thread_result(n, nbytes, actual_test_time); } print_total_result(tep->test, total_bytes, actual_test_time, init_cpu_usage, final_cpu_usage, init_tcp_retrans, final_tcp_retrans); free (init_cpu_usage); free (final_cpu_usage); free (init_tcp_retrans); free (final_tcp_retrans); return err_code; }