summaryrefslogtreecommitdiff
path: root/src/tools/operf/operf_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/operf/operf_client.c')
-rw-r--r--src/tools/operf/operf_client.c119
1 files changed, 71 insertions, 48 deletions
diff --git a/src/tools/operf/operf_client.c b/src/tools/operf/operf_client.c
index d299e239..c8873c54 100644
--- a/src/tools/operf/operf_client.c
+++ b/src/tools/operf/operf_client.c
@@ -36,6 +36,8 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+bool stop;
+
static void busy_wait_until(const struct timespec * deadline)
{
struct timespec now;
@@ -45,7 +47,6 @@ static void busy_wait_until(const struct timespec * deadline)
while (now.tv_sec == deadline->tv_sec
&& now.tv_nsec < deadline->tv_nsec)
clock_gettime(CLOCK_REALTIME, &now);
- pthread_testcancel();
}
void shutdown_client(int signo, siginfo_t * info, void * c)
@@ -57,8 +58,7 @@ void shutdown_client(int signo, siginfo_t * info, void * c)
case SIGINT:
case SIGTERM:
case SIGHUP:
- pthread_cancel(client.reader_pt);
- pthread_cancel(client.writer_pt);
+ stop = true;
default:
return;
}
@@ -74,7 +74,14 @@ void * reader(void * o)
fccntl(fd, FLOWSRCVTIMEO, &timeout);
- while ((msg_len = flow_read(fd, buf, OPERF_BUF_SIZE)) != -ETIMEDOUT) {
+ while (!stop) {
+ msg_len = flow_read(fd, buf, OPERF_BUF_SIZE);
+ if (msg_len == -ETIMEDOUT) {
+ printf("Server timed out.\n");
+ stop = true;
+ break;
+ }
+
if (msg_len != client.size) {
printf("Invalid message on fd %d.\n", fd);
continue;
@@ -96,7 +103,10 @@ void * writer(void * o)
struct timespec intv = {(gap / BILLION), gap % BILLION};
struct timespec end = {0, 0};
- char * buf = malloc(client.size);
+ char * buf;
+ struct msg * msg;
+
+ buf = malloc(client.size);
if (buf == NULL)
return (void *) -ENOMEM;
@@ -107,53 +117,49 @@ void * writer(void * o)
memset(buf, 0, client.size);
+ msg = (struct msg *) buf;
+
if (client.flood)
printf("Flooding %s with %d byte SDUs for %d seconds.\n\n",
- client.s_apn, client.size, client.duration / 1000);
+ client.server_name, client.size,
+ client.duration / 1000);
else
printf("Sending %d byte SDUs for %d s to %s at %.3lf Mb/s.\n\n",
- client.size, client.duration / 1000, client.s_apn,
+ client.size, client.duration / 1000,
+ client.server_name,
client.rate / (double) MILLION);
clock_gettime(CLOCK_REALTIME, &start);
clock_gettime(CLOCK_REALTIME, &now);
- pthread_cleanup_push((void (*) (void *)) free, buf);
-
- if (client.flood) {
- while (ts_diff_ms(&start, &now) < client.duration) {
- if (flow_write(*fdp, buf, client.size) == -1) {
- printf("Failed to send SDU.\n");
- flow_dealloc(*fdp);
- free(buf);
- return (void *) -1;
- }
+ while (!stop && ts_diff_ms(&start, &now) < client.duration) {
+ if (!client.flood) {
+ clock_gettime(CLOCK_REALTIME, &now);
+ ts_add(&now, &intv, &end);
+ }
- ++client.sent;
+ msg->id = client.sent;
- clock_gettime(CLOCK_REALTIME, &now);
+ if (flow_write(*fdp, buf, client.size) == -1) {
+ printf("Failed to send SDU.\n");
+ flow_dealloc(*fdp);
+ free(buf);
+ return (void *) -1;
}
- } else {
- while (ts_diff_ms(&start, &now) < client.duration) {
- clock_gettime(CLOCK_REALTIME, &now);
- ts_add(&now, &intv, &end);
- if (flow_write(*fdp, buf, client.size) == -1) {
- printf("Failed to send SDU.\n");
- flow_dealloc(*fdp);
- free(buf);
- return (void *) -1;
- }
+ ++client.sent;
- ++client.sent;
+ if (!client.flood) {
if (client.sleep)
nanosleep(&intv, NULL);
else
busy_wait_until(&end);
+ } else {
+ clock_gettime(CLOCK_REALTIME, &now);
}
}
- pthread_cleanup_pop(true);
+ free(buf);
printf("Test finished.\n");
@@ -183,34 +189,51 @@ int client_main(void)
client.sent = 0;
client.rcvd = 0;
+ stop = false;
- fd = flow_alloc(client.s_apn, NULL, NULL);
+ /* FIXME: Allow selecting QoS. */
+ fd = flow_alloc(client.server_name, NULL, NULL);
if (fd < 0) {
printf("Failed to allocate flow.\n");
return -1;
}
- clock_gettime(CLOCK_REALTIME, &tic);
+ if (client.conf.test_type == TEST_TYPE_BI)
+ printf("Doing a bidirectional test.\n");
+ else
+ printf("Doing a unidirectional test.\n");
- pthread_create(&client.reader_pt, NULL, reader, &fd);
- pthread_create(&client.writer_pt, NULL, writer, &fd);
+ if (flow_write(fd, &client.conf, sizeof(client.conf))) {
+ printf("Failed to send configuration.\n");
+ flow_dealloc(fd);
+ return -1;
+ }
- pthread_join(client.writer_pt, NULL);
+ sleep(1);
+
+ clock_gettime(CLOCK_REALTIME, &tic);
- clock_gettime(CLOCK_REALTIME, &toc);
+ if (client.conf.test_type == TEST_TYPE_BI)
+ pthread_create(&client.reader_pt, NULL, reader, &fd);
- pthread_join(client.reader_pt, NULL);
+ pthread_create(&client.writer_pt, NULL, writer, &fd);
+ pthread_join(client.writer_pt, NULL);
- printf("\n");
- printf("--- %s perf statistics ---\n", client.s_apn);
- printf("%ld SDUs transmitted, ", client.sent);
- printf("%ld received, ", client.rcvd);
- printf("%ld%% packet loss, ", client.sent == 0 ? 0 :
- 100 - ((100 * client.rcvd) / client.sent));
- printf("time: %.3f ms, ", ts_diff_us(&tic, &toc) / 1000.0);
- printf("bandwidth: %.3lf Mb/s.\n",
- (client.rcvd * client.size * 8)
- / (double) ts_diff_us(&tic, &toc));
+ if (client.conf.test_type == TEST_TYPE_BI){
+ clock_gettime(CLOCK_REALTIME, &toc);
+ pthread_join(client.reader_pt, NULL);
+
+ printf("\n");
+ printf("--- %s perf statistics ---\n", client.server_name);
+ printf("%ld SDUs transmitted, ", client.sent);
+ printf("%ld received, ", client.rcvd);
+ printf("%ld%% packet loss, ", client.sent == 0 ? 0 :
+ 100 - ((100 * client.rcvd) / client.sent));
+ printf("time: %.3f ms, ", ts_diff_us(&tic, &toc) / 1000.0);
+ printf("bandwidth: %.3lf Mb/s.\n",
+ (client.rcvd * client.size * 8)
+ / (double) ts_diff_us(&tic, &toc));
+ }
flow_dealloc(fd);