Quite a bit of code restructuring.
This commit is contained in:
parent
b68ac00ee9
commit
f1b3bd81f9
@ -137,15 +137,22 @@ struct iperf_test
|
||||
|
||||
int (*accept) (struct iperf_test *);
|
||||
struct iperf_stream *(*new_stream) (struct iperf_test *);
|
||||
|
||||
|
||||
/* Interval related members */
|
||||
int stats_interval;
|
||||
int reporter_interval;
|
||||
void (*stats_callback) (struct iperf_test *);
|
||||
void (*reporter_callback) (struct iperf_test *);
|
||||
struct timer *timer;
|
||||
struct timer *stats_timer;
|
||||
struct timer *reporter_timer;
|
||||
|
||||
|
||||
int num_streams; /* total streams in the test (-P) */
|
||||
int streams_accepted; /* total number of streams accepted (server only) */
|
||||
|
||||
iperf_size_t bytes_sent;
|
||||
|
||||
/* iperf error reporting
|
||||
* - errtype: (0,1,2)
|
||||
* 0: use perror(errno)
|
||||
|
262
src/iperf_api.c
262
src/iperf_api.c
@ -56,136 +56,49 @@ usage_long()
|
||||
fprintf(stderr, usage_long2);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: should probably just compute this as we go and store it in the
|
||||
* iperf_test structure -blt
|
||||
*/
|
||||
int
|
||||
all_data_sent(struct iperf_test * test)
|
||||
{
|
||||
if (test->default_settings->bytes == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
uint64_t total_bytes = 0;
|
||||
struct iperf_stream *sp;
|
||||
|
||||
sp = test->streams;
|
||||
|
||||
while (sp) {
|
||||
total_bytes += sp->result->bytes_sent;
|
||||
sp = sp->next;
|
||||
}
|
||||
|
||||
if (total_bytes >= (test->num_streams * test->default_settings->bytes)) {
|
||||
if (test->default_settings->bytes > 0) {
|
||||
if (test->bytes_sent >= (test->num_streams * test->default_settings->bytes)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
iperf_send(struct iperf_test *test)
|
||||
{
|
||||
int result;
|
||||
char *prot;
|
||||
iperf_size_t bytes_sent;
|
||||
fd_set temp_write_set;
|
||||
struct timeval tv;
|
||||
int64_t delayus, adjustus, dtargus;
|
||||
struct iperf_stream *sp;
|
||||
static struct timer *timer, *stats_interval, *reporter_interval;
|
||||
|
||||
if (test->state == TEST_START) {
|
||||
timer = stats_interval = reporter_interval = NULL;
|
||||
memcpy(&temp_write_set, &test->write_set, sizeof(fd_set));
|
||||
tv.tv_sec = 15;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
// Not sure what the following code does yet. It's UDP, so I'll get to fixing it eventually
|
||||
if (test->protocol == Pudp) {
|
||||
prot = "UDP";
|
||||
dtargus = (int64_t) (test->default_settings->blksize) * SEC_TO_US * 8;
|
||||
dtargus /= test->default_settings->rate;
|
||||
|
||||
assert(dtargus != 0);
|
||||
|
||||
delayus = dtargus;
|
||||
adjustus = 0;
|
||||
|
||||
printf("iperf_run_client: adjustus: %lld, delayus %lld \n", adjustus, delayus);
|
||||
|
||||
for (sp = test->streams; sp != NULL; sp = sp->next)
|
||||
sp->send_timer = new_timer(0, dtargus);
|
||||
|
||||
} else {
|
||||
prot = "TCP";
|
||||
}
|
||||
|
||||
/* if -n specified, set zero timer */
|
||||
// Set timers and print usage message
|
||||
if (test->default_settings->bytes == 0) {
|
||||
timer = new_timer(test->duration, 0);
|
||||
printf("Starting Test: protocol: %s, %d streams, %d byte blocks, %d second test \n",
|
||||
prot, test->num_streams, test->default_settings->blksize, test->duration);
|
||||
} else {
|
||||
timer = new_timer(0, 0);
|
||||
printf("Starting Test: protocol: %s, %d streams, %d byte blocks, %d bytes to send\n",
|
||||
prot, test->num_streams, test->default_settings->blksize, (int) test->default_settings->bytes);
|
||||
}
|
||||
if (test->stats_interval != 0)
|
||||
stats_interval = new_timer(test->stats_interval, 0);
|
||||
if (test->reporter_interval != 0)
|
||||
reporter_interval = new_timer(test->reporter_interval, 0);
|
||||
|
||||
test->state = TEST_RUNNING;
|
||||
if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) {
|
||||
perror("Nwrite TEST_RUNNING");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
} else if (test->state == TEST_RUNNING) {
|
||||
memcpy(&temp_write_set, &test->write_set, sizeof(fd_set));
|
||||
tv.tv_sec = 15;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
result = select(test->max_fd + 1, NULL, &temp_write_set, NULL, &tv);
|
||||
if (result < 0 && errno != EINTR) {
|
||||
perror("select iperf_send");
|
||||
return -1;
|
||||
}
|
||||
if (result > 0) {
|
||||
if (!all_data_sent(test) && !timer->expired(timer)) {
|
||||
for (sp = test->streams; sp != NULL; sp = sp->next) {
|
||||
if (FD_ISSET(sp->socket, &temp_write_set)) {
|
||||
if (sp->snd(sp) < 0) {
|
||||
// XXX: Do better error handling
|
||||
perror("iperf_client_start: snd");
|
||||
}
|
||||
FD_CLR(sp->socket, &temp_write_set);
|
||||
}
|
||||
}
|
||||
|
||||
// Perform callbacks
|
||||
if ((test->stats_interval != 0) && stats_interval->expired(stats_interval)) {
|
||||
test->stats_callback(test);
|
||||
update_timer(stats_interval, test->stats_interval, 0);
|
||||
}
|
||||
if ((test->reporter_interval != 0) && reporter_interval->expired(reporter_interval)) {
|
||||
test->reporter_callback(test);
|
||||
update_timer(reporter_interval, test->reporter_interval, 0);
|
||||
}
|
||||
} else {
|
||||
free_timer(timer);
|
||||
free_timer(stats_interval);
|
||||
free_timer(reporter_interval);
|
||||
|
||||
test->state = TEST_END;
|
||||
if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) {
|
||||
perror("Nwrite TEST_END");
|
||||
result = select(test->max_fd + 1, NULL, &temp_write_set, NULL, &tv);
|
||||
if (result < 0 && errno != EINTR) {
|
||||
perror("select iperf_send");
|
||||
return -1;
|
||||
}
|
||||
if (result > 0) {
|
||||
for (sp = test->streams; sp != NULL; sp = sp->next) {
|
||||
if (FD_ISSET(sp->socket, &temp_write_set)) {
|
||||
if ((bytes_sent = sp->snd(sp)) < 0) {
|
||||
// XXX: Do better error handling
|
||||
perror("iperf stream->snd");
|
||||
return -1;
|
||||
}
|
||||
test->stats_callback(test);
|
||||
test->bytes_sent += bytes_sent;
|
||||
FD_CLR(sp->socket, &temp_write_set);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -194,29 +107,30 @@ int
|
||||
iperf_recv(struct iperf_test *test)
|
||||
{
|
||||
int result;
|
||||
iperf_size_t bytes_sent;
|
||||
fd_set temp_read_set;
|
||||
struct timeval tv;
|
||||
struct iperf_stream *sp;
|
||||
|
||||
if (test->state == TEST_RUNNING) {
|
||||
memcpy(&temp_read_set, &test->read_set, sizeof(fd_set));
|
||||
tv.tv_sec = 15;
|
||||
tv.tv_usec = 0;
|
||||
memcpy(&temp_read_set, &test->read_set, sizeof(fd_set));
|
||||
tv.tv_sec = 15;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
result = select(test->max_fd + 1, &temp_read_set, NULL, NULL, &tv);
|
||||
if (result < 0) {
|
||||
perror("select iperf_recv");
|
||||
return -1;
|
||||
}
|
||||
if (result > 0) {
|
||||
for (sp = test->streams; sp != NULL; sp = sp->next) {
|
||||
if (FD_ISSET(sp->socket, &temp_read_set)) {
|
||||
if (sp->rcv(sp) < 0) {
|
||||
// XXX: Do better error handling
|
||||
perror("sp->rcv(sp)");
|
||||
}
|
||||
FD_CLR(sp->socket, &temp_read_set);
|
||||
result = select(test->max_fd + 1, &temp_read_set, NULL, NULL, &tv);
|
||||
if (result < 0) {
|
||||
perror("select iperf_recv");
|
||||
return -1;
|
||||
}
|
||||
if (result > 0) {
|
||||
for (sp = test->streams; sp != NULL; sp = sp->next) {
|
||||
if (FD_ISSET(sp->socket, &temp_read_set)) {
|
||||
if ((bytes_sent = sp->rcv(sp)) < 0) {
|
||||
// XXX: Do better error handling
|
||||
perror("sp->rcv(sp)");
|
||||
return -1;
|
||||
}
|
||||
test->bytes_sent += bytes_sent;
|
||||
FD_CLR(sp->socket, &temp_read_set);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -224,6 +138,58 @@ iperf_recv(struct iperf_test *test)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
iperf_init_test(struct iperf_test *test)
|
||||
{
|
||||
char *prot;
|
||||
struct iperf_stream *sp;
|
||||
|
||||
/* XXX: These variables were used in the old UDP code
|
||||
int64_t delayus, adjustus, dtargus;
|
||||
*/
|
||||
|
||||
if (test->protocol == Pudp) {
|
||||
prot = "UDP";
|
||||
|
||||
/* XXX: This code isn't currently used and will most likely be changed
|
||||
dtargus = (int64_t) (test->default_settings->blksize) * SEC_TO_US * 8;
|
||||
dtargus /= test->default_settings->rate;
|
||||
|
||||
assert(dtargus != 0);
|
||||
|
||||
delayus = dtargus;
|
||||
adjustus = 0;
|
||||
|
||||
printf("iperf_run_client: adjustus: %lld, delayus %lld \n", adjustus, delayus);
|
||||
|
||||
for (sp = test->streams; sp != NULL; sp = sp->next)
|
||||
sp->send_timer = new_timer(0, dtargus);
|
||||
*/
|
||||
|
||||
} else {
|
||||
prot = "TCP";
|
||||
}
|
||||
|
||||
/* Set timers */
|
||||
if (test->default_settings->bytes == 0) {
|
||||
test->timer = new_timer(test->duration, 0);
|
||||
printf(test_start_time, prot, test->num_streams, test->default_settings->blksize,
|
||||
test->duration);
|
||||
} else {
|
||||
printf(test_start_bytes, prot, test->num_streams, test->default_settings->blksize,
|
||||
test->default_settings->bytes);
|
||||
}
|
||||
|
||||
if (test->stats_interval != 0)
|
||||
test->stats_timer = new_timer(test->stats_interval, 0);
|
||||
if (test->reporter_interval != 0)
|
||||
test->reporter_timer = new_timer(test->reporter_interval, 0);
|
||||
|
||||
/* Set start time */
|
||||
for (sp = test->streams; sp; sp = sp->next)
|
||||
gettimeofday(&sp->result->start_time, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
@ -733,16 +699,10 @@ iperf_handle_message_client(struct iperf_test *test)
|
||||
iperf_create_streams(test);
|
||||
break;
|
||||
case TEST_START:
|
||||
iperf_init_test(test);
|
||||
break;
|
||||
case TEST_RUNNING:
|
||||
break;
|
||||
case TEST_END:
|
||||
if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) {
|
||||
perror("Nwrite TEST_END\n");
|
||||
return -1;
|
||||
}
|
||||
test->stats_callback(test);
|
||||
break;
|
||||
case EXCHANGE_RESULTS:
|
||||
iperf_exchange_results(test);
|
||||
break;
|
||||
@ -800,6 +760,9 @@ void
|
||||
iperf_free_test(struct iperf_test * test)
|
||||
{
|
||||
free(test->default_settings);
|
||||
free_timer(test->timer);
|
||||
free_timer(test->stats_timer);
|
||||
free_timer(test->reporter_timer);
|
||||
|
||||
test->streams = NULL;
|
||||
test->accept = NULL;
|
||||
@ -904,7 +867,6 @@ iperf_reporter_callback(struct iperf_test * test)
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case TEST_END:
|
||||
case DISPLAY_RESULTS:
|
||||
/* print final summary for all intervals */
|
||||
|
||||
@ -1212,12 +1174,34 @@ iperf_run_client(struct iperf_test * test)
|
||||
FD_CLR(test->ctrl_sck, &temp_read_set);
|
||||
}
|
||||
|
||||
if (test->reverse) {
|
||||
// Reverse mode. Client receives.
|
||||
iperf_recv(test);
|
||||
} else {
|
||||
// Regular mode. Client sends.
|
||||
iperf_send(test);
|
||||
if (test->state == TEST_RUNNING) {
|
||||
if (test->reverse) {
|
||||
// Reverse mode. Client receives.
|
||||
iperf_recv(test);
|
||||
} else {
|
||||
// Regular mode. Client sends.
|
||||
iperf_send(test);
|
||||
}
|
||||
|
||||
/* Perform callbacks */
|
||||
if (timer_expired(test->stats_timer)) {
|
||||
test->stats_callback(test);
|
||||
update_timer(test->stats_timer, test->stats_interval, 0);
|
||||
}
|
||||
if (timer_expired(test->reporter_timer)) {
|
||||
test->reporter_callback(test);
|
||||
update_timer(test->reporter_timer, test->reporter_interval, 0);
|
||||
}
|
||||
|
||||
/* Send TEST_END if all data has been sent or timer expired */
|
||||
if (all_data_sent(test) || timer_expired(test->timer)) {
|
||||
test->stats_callback(test);
|
||||
test->state = TEST_END;
|
||||
if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) {
|
||||
perror("Nwrite TEST_END");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -132,6 +132,7 @@ int iperf_create_streams(struct iperf_test *);
|
||||
int iperf_handle_message_client(struct iperf_test *);
|
||||
int iperf_exchange_results(struct iperf_test *);
|
||||
int parse_results(struct iperf_test *, char *);
|
||||
void iperf_init_test(struct iperf_test *);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -159,6 +159,7 @@ iperf_accept(struct iperf_test *test)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (Nwrite(s, &rbuf, sizeof(int), Ptcp) < 0) {
|
||||
perror("Nwrite ACCESS_DENIED");
|
||||
@ -243,9 +244,8 @@ iperf_handle_message_server(struct iperf_test *test)
|
||||
switch(test->state) {
|
||||
case TEST_START:
|
||||
break;
|
||||
case TEST_RUNNING:
|
||||
break;
|
||||
case TEST_END:
|
||||
test->stats_callback(test);
|
||||
for (sp = test->streams; sp; sp = sp->next) {
|
||||
FD_CLR(sp->socket, &test->read_set);
|
||||
FD_CLR(sp->socket, &test->write_set);
|
||||
@ -262,7 +262,6 @@ iperf_handle_message_server(struct iperf_test *test)
|
||||
perror("Nwrite DISPLAY_RESULTS");
|
||||
exit(1);
|
||||
}
|
||||
test->stats_callback(test);
|
||||
test->reporter_callback(test);
|
||||
break;
|
||||
case IPERF_DONE:
|
||||
@ -291,6 +290,12 @@ iperf_test_reset(struct iperf_test *test)
|
||||
np = sp->next;
|
||||
iperf_free_stream(sp);
|
||||
}
|
||||
free_timer(test->timer);
|
||||
free_timer(test->stats_timer);
|
||||
free_timer(test->reporter_timer);
|
||||
test->timer = NULL;
|
||||
test->stats_timer = NULL;
|
||||
test->reporter_timer = NULL;
|
||||
|
||||
test->streams = NULL;
|
||||
|
||||
@ -303,6 +308,8 @@ iperf_test_reset(struct iperf_test *test)
|
||||
test->ctrl_sck = -1;
|
||||
test->prot_listener = 0;
|
||||
|
||||
test->bytes_sent = 0;
|
||||
|
||||
test->reverse = 0;
|
||||
test->no_delay = 0;
|
||||
|
||||
@ -401,15 +408,33 @@ iperf_run_server(struct iperf_test *test)
|
||||
perror("Nwrite TEST_START");
|
||||
return -1;
|
||||
}
|
||||
iperf_init_test(test);
|
||||
test->state = TEST_RUNNING;
|
||||
if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) {
|
||||
perror("Nwrite TEST_RUNNING");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (test->reverse) {
|
||||
// Reverse mode. Server sends.
|
||||
iperf_send(test);
|
||||
} else {
|
||||
// Regular mode. Server receives.
|
||||
iperf_recv(test);
|
||||
if (test->state == TEST_RUNNING) {
|
||||
if (test->reverse) {
|
||||
// Reverse mode. Server sends.
|
||||
iperf_send(test);
|
||||
} else {
|
||||
// Regular mode. Server receives.
|
||||
iperf_recv(test);
|
||||
}
|
||||
|
||||
/* Perform callbacks */
|
||||
if (timer_expired(test->stats_timer)) {
|
||||
test->stats_callback(test);
|
||||
update_timer(test->stats_timer, test->stats_interval, 0);
|
||||
}
|
||||
if (timer_expired(test->reporter_timer)) {
|
||||
test->reporter_callback(test);
|
||||
update_timer(test->reporter_timer, test->reporter_interval, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ iperf_tcp_recv(struct iperf_stream * sp)
|
||||
sp->result->bytes_received += result;
|
||||
sp->result->bytes_received_this_interval += result;
|
||||
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
@ -167,6 +167,13 @@ const char window_default[] =
|
||||
const char wait_server_threads[] =
|
||||
"Waiting for server threads to complete. Interrupt again to force quit.\n";
|
||||
|
||||
const char test_start_time[] =
|
||||
"Starting Test: protocol: %s, %d streams, %d byte blocks, %d second test\n";
|
||||
|
||||
const char test_start_bytes[] =
|
||||
"Starting Test: protocol: %s, %d streams, %d byte blocks, %llu bytes to send\n";
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* reports
|
||||
* ------------------------------------------------------------------- */
|
||||
|
@ -20,6 +20,8 @@ extern char tcp_window_size[] ;
|
||||
extern char udp_buffer_size[] ;
|
||||
extern char window_default[] ;
|
||||
extern char wait_server_threads[] ;
|
||||
extern char test_start_time[];
|
||||
extern char test_start_bytes[];
|
||||
|
||||
extern char report_read_lengths[] ;
|
||||
extern char report_read_length_times[] ;
|
||||
|
@ -28,10 +28,8 @@ timeval_diff(struct timeval * tv0, struct timeval * tv1)
|
||||
int
|
||||
timer_expired(struct timer * tp)
|
||||
{
|
||||
/* for timer with zero time */
|
||||
if (tp->end.tv_sec == tp->begin.tv_sec && tp->end.tv_usec == tp->begin.tv_usec) {
|
||||
if (tp == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct timeval now;
|
||||
int64_t end = 0, current = 0;
|
||||
|
@ -24,4 +24,6 @@ int64_t timer_remaining(struct timer *tp);
|
||||
|
||||
void free_timer(struct timer *tp);
|
||||
|
||||
int timer_expired(struct timer *);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user