Quite a bit of code restructuring.

This commit is contained in:
sethdelliott 2010-07-07 21:54:24 +00:00
parent b68ac00ee9
commit f1b3bd81f9
9 changed files with 179 additions and 153 deletions

View File

@ -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)

View File

@ -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;
}
}
}
}
}

View File

@ -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

View File

@ -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);
}
}
}
}

View File

@ -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;
}
/**************************************************************************/

View File

@ -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
* ------------------------------------------------------------------- */

View File

@ -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[] ;

View File

@ -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;

View File

@ -24,4 +24,6 @@ int64_t timer_remaining(struct timer *tp);
void free_timer(struct timer *tp);
int timer_expired(struct timer *);
#endif