/*---------------------------------------------------------------------------*/
int run_client_test(struct perf_parameters *user_param)
{
	struct session_data	sess_data;
	struct perf_comm	*comm;
	struct thread_data	*tdata;
	char			url[256];
	int			i = 0;
	int			max_cpus;
	pthread_t		statistics_thread_id;
	struct perf_command	command;
	int			size_log2;
	int			max_size_log2 = 24;


	/* client session attributes */
	struct xio_session_attr attr = {
		&ses_ops,
		NULL,
		0
	};
	xio_init();

	g_mhz		= get_cpu_mhz(0);
	max_cpus	= sysconf(_SC_NPROCESSORS_ONLN);
	threads_iter	= 1;
	size_log2	= 0;

	tdata = calloc(user_param->threads_num, sizeof(*tdata));
	if (tdata == NULL) {
		fprintf(fd, "malloc failed\n");
		return -1;
	}

	comm = create_comm_struct(user_param);
	if (establish_connection(comm)) {
		fprintf(stderr, "failed to establish connection\n");
		free(tdata);
		destroy_comm_struct(comm);
		return -1;
	}

	if (user_param->output_file) {
		fd = fopen(user_param->output_file, "w");
		if (fd == NULL) {
			fprintf(fd, "file open failed. %s\n",
				user_param->output_file);
			free(sess_data.tdata);
			destroy_comm_struct(comm);
			return -1;
		}
		fprintf(fd, "size, threads, tps, bw[Mbps], lat[usec]\n");
		fflush(fd);
	}


	printf("%s", RESULT_FMT);
	printf("%s", RESULT_LINE);


	while (threads_iter <= user_param->threads_num)  {
		data_len	= (uint64_t)1 << size_log2;

		memset(&sess_data, 0, sizeof(sess_data));
		memset(tdata, 0, user_param->threads_num*sizeof(*tdata));
		sess_data.tdata = tdata;

		command.test_param.machine_type	= user_param->machine_type;
		command.test_param.test_type	= user_param->test_type;
		command.test_param.verb		= user_param->verb;
		command.test_param.data_len	= data_len;
		command.command			= GetTestParams;

		ctx_write_data(comm, &command, sizeof(command));

		sprintf(url, "rdma://%s:%d", user_param->server_addr,
			user_param->server_port);
		sess_data.session = xio_session_create(XIO_SESSION_CLIENT,
				&attr, url, 0, 0, &sess_data);
		if (sess_data.session == NULL) {
			int error = xio_errno();
			fprintf(stderr,
				"session creation failed. reason %d - (%s)\n",
				error, xio_strerror(error));
			goto cleanup;
		}

		pthread_create(&statistics_thread_id, NULL,
			       statistics_thread_cb, &sess_data);

		/* spawn threads to handle connection */
		for (i = 0; i < threads_iter; i++) {
			sess_data.tdata[i].affinity		=
				((user_param->cpu + i) % max_cpus);
			sess_data.tdata[i].cid			= i;
			sess_data.tdata[i].sdata		= &sess_data;
			sess_data.tdata[i].user_param		= user_param;
			sess_data.tdata[i].data_len		= data_len;

			/* all threads are working on the same session */
			sess_data.tdata[i].session	= sess_data.session;
			pthread_create(&sess_data.tdata[i].thread_id, NULL,
				       worker_thread, &sess_data.tdata[i]);
		}

		pthread_join(statistics_thread_id, NULL);

		/* join the threads */
		for (i = 0; i < threads_iter; i++)
			pthread_join(sess_data.tdata[i].thread_id, NULL);

		/* close the session */
		xio_session_destroy(sess_data.session);

		if (sess_data.abort) {
			fprintf(stderr, "program aborted\n");
			goto cleanup;
		}

		/* send result to server */
		command.results.bytes		= data_len;
		command.results.threads		= threads_iter;
		command.results.tps		= sess_data.tps;
		command.results.avg_bw		= sess_data.avg_bw;
		command.results.avg_lat		= sess_data.avg_lat_us;
		command.results.min_lat		= sess_data.min_lat_us;
		command.results.max_lat		= sess_data.max_lat_us;
		command.command			= GetTestResults;

		/* sync point */
		ctx_write_data(comm, &command, sizeof(command));

		printf(REPORT_FMT,
		       data_len,
		       threads_iter,
		       sess_data.tps,
		       sess_data.avg_bw,
		       sess_data.avg_lat_us,
		       sess_data.min_lat_us,
		       sess_data.max_lat_us);
		if (fd)
			fprintf(fd, "%lu, %d, %lu, %.2lf, %.2lf\n",
				data_len,
				threads_iter,
				sess_data.tps,
				sess_data.avg_bw,
				sess_data.avg_lat_us);
		fflush(fd);

		/* sync point */
		ctx_read_data(comm, NULL, 0, NULL);

		if (++size_log2 < max_size_log2)
			continue;

		threads_iter++;
		size_log2 = 0;
	}

	printf("%s", RESULT_LINE);

cleanup:
	if (fd)
		fclose(fd);

	ctx_hand_shake(comm);

	ctx_close_connection(comm);

	destroy_comm_struct(comm);

	free(tdata);

	xio_shutdown();

	return 0;
}
Example #2
0
/*---------------------------------------------------------------------------*/
int run_server_test(struct perf_parameters *user_param)
{
	struct server_data	server_data;
	struct perf_command	command;
	int			i, len, retval;
	int			max_cpus;
	uint64_t		cpusmask;
	int			cpusnr;
	int			cpu;

	xio_init();

	max_cpus = sysconf(_SC_NPROCESSORS_ONLN);

	i = intf_name_best_cpus(user_param->intf_name, &cpusmask, &cpusnr);
	if (i == 0) {
		printf("best cpus [%d] %s\n", cpusnr,
		       intf_cpusmask_str(cpusmask, cpusnr, user_param->intf_name));
	}

	server_data.my_test_param.machine_type	= user_param->machine_type;
	server_data.my_test_param.test_type	= user_param->test_type;
	server_data.my_test_param.verb		= user_param->verb;
	server_data.my_test_param.data_len	= 0;


	server_data.tdata = calloc(user_param->threads_num,
				   sizeof(*server_data.tdata));

	/* spawn portals */
	for (i = 0, cpu = 0; i < user_param->threads_num; i++, cpu++) {
		while (1) {
			if (cpusmask_test_bit(cpu, &cpusmask))
				break;
			if (++cpu == max_cpus)
				cpu = 0;
		}
		server_data.tdata[i].affinity = cpu;

		server_data.tdata[i].portal_index =
					(i % user_param->portals_arr_len);
		server_data.tdata[i].user_param = user_param;

		pthread_create(&server_data.tdata[i].thread_id, NULL,
			       portal_server_cb, &server_data.tdata[i]);
	}

	server_data.user_param = user_param;
	pthread_create(&server_data.thread_id, NULL,
		       balancer_server_cb, &server_data);

	server_data.comm = create_comm_struct(user_param);
	if (establish_connection(server_data.comm)) {
		fprintf(stderr, "failed to establish connection\n");
		goto cleanup;
	}


	printf("%s", RESULT_FMT);
	printf("%s", RESULT_LINE);

	while (1) {
		/* sync test parameters */
		retval = ctx_read_data(server_data.comm, &command,
				       sizeof(command), &len);
		if (retval) {	/* disconnection */
			fprintf(stderr, "program aborted\n");
			break;
		}

		if (len == 0) { /* handshake */
			ctx_write_data(server_data.comm, NULL, 0);
			break;
		}
		switch (command.command) {
		case GetTestResults:
			on_test_results(&command.results);
			ctx_write_data(server_data.comm, NULL, 0);
			break;
		case  GetTestParams:
			break;
		default:
			fprintf(stderr, "unknown command %d\n", len);
			exit(0);
			break;
		};
	}
	if (retval == 0)
		printf("%s", RESULT_LINE);

	/* normal exit phase */
	ctx_close_connection(server_data.comm);

cleanup:
	for (i = 0; i < user_param->threads_num; i++)
		xio_context_stop_loop(server_data.tdata[i].ctx, 0);

	destroy_comm_struct(server_data.comm);

	/* join the threads */
	for (i = 0; i < user_param->threads_num; i++)
		pthread_join(server_data.tdata[i].thread_id, NULL);

	if (server_data.running)
		xio_context_stop_loop(server_data.ctx, 0);

	pthread_join(server_data.thread_id, NULL);

	free(server_data.tdata);

	xio_shutdown();

	return 0;
}