Added second concurrency model based on SIGALRM.
This commit is contained in:
parent
a6b3f26be1
commit
a27f6534b5
@ -34,6 +34,10 @@ main( int argc, char** argv )
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
iperf_defaults( test );
|
||||
|
||||
/* This main program doesn't use SIGALRM, so the iperf API may use it. */
|
||||
iperf_set_test_may_use_sigalrm(test, 1);
|
||||
|
||||
iperf_set_test_role( test, 'c' );
|
||||
iperf_set_test_server_hostname( test, host );
|
||||
iperf_set_test_server_port( test, port );
|
||||
|
@ -146,6 +146,9 @@ struct iperf_test
|
||||
int json_output; /* -J option - JSON output */
|
||||
int zerocopy; /* -Z option - use sendfile */
|
||||
|
||||
int multisend;
|
||||
int may_use_sigalrm;
|
||||
|
||||
/* Select related parameters */
|
||||
int max_fd;
|
||||
fd_set read_set; /* set of read sockets */
|
||||
|
@ -164,6 +164,12 @@ iperf_get_test_zerocopy(struct iperf_test *ipt)
|
||||
return ipt->zerocopy;
|
||||
}
|
||||
|
||||
int
|
||||
iperf_get_test_may_use_sigalrm(struct iperf_test *ipt)
|
||||
{
|
||||
return ipt->may_use_sigalrm;
|
||||
}
|
||||
|
||||
/************** Setter routines for some fields inside iperf_test *************/
|
||||
|
||||
void
|
||||
@ -256,6 +262,12 @@ iperf_set_test_zerocopy(struct iperf_test *ipt, int zerocopy)
|
||||
ipt->zerocopy = zerocopy;
|
||||
}
|
||||
|
||||
void
|
||||
iperf_set_test_may_use_sigalrm(struct iperf_test *ipt, int may_use_sigalrm)
|
||||
{
|
||||
ipt->may_use_sigalrm = may_use_sigalrm;
|
||||
}
|
||||
|
||||
/********************** Get/set test protocol structure ***********************/
|
||||
|
||||
struct protocol *
|
||||
@ -610,18 +622,18 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
||||
int
|
||||
iperf_send(struct iperf_test *test, fd_set *write_setP)
|
||||
{
|
||||
int multisend, r;
|
||||
register int multisend, r;
|
||||
register struct iperf_stream *sp;
|
||||
|
||||
/* Can we do multisend mode? */
|
||||
if (test->protocol->id == Pudp && test->settings->rate != 0)
|
||||
multisend = 1; /* nope */
|
||||
else
|
||||
multisend = 20; /* arbitrary */
|
||||
multisend = test->multisend;
|
||||
|
||||
for (; multisend > 0; --multisend) {
|
||||
SLIST_FOREACH(sp, &test->streams, streams) {
|
||||
if (FD_ISSET(sp->socket, write_setP)) {
|
||||
if (write_setP == NULL || FD_ISSET(sp->socket, write_setP)) {
|
||||
if ((r = sp->snd(sp)) < 0) {
|
||||
if (r == NET_SOFTERROR)
|
||||
break;
|
||||
@ -634,6 +646,7 @@ iperf_send(struct iperf_test *test, fd_set *write_setP)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (write_setP != NULL)
|
||||
SLIST_FOREACH(sp, &test->streams, streams)
|
||||
if (FD_ISSET(sp->socket, write_setP))
|
||||
FD_CLR(sp->socket, write_setP);
|
||||
@ -1182,6 +1195,9 @@ iperf_defaults(struct iperf_test *testp)
|
||||
testp->settings->bytes = 0;
|
||||
memset(testp->cookie, 0, COOKIE_SIZE);
|
||||
|
||||
testp->multisend = 10; /* arbitrary */
|
||||
testp->may_use_sigalrm = 0;
|
||||
|
||||
/* Set up protocol list */
|
||||
SLIST_INIT(&testp->streams);
|
||||
SLIST_INIT(&testp->protocols);
|
||||
@ -1315,6 +1331,7 @@ iperf_reset_test(struct iperf_test *test)
|
||||
test->settings->rate = RATE; /* UDP only */
|
||||
test->settings->mss = 0;
|
||||
memset(test->cookie, 0, COOKIE_SIZE);
|
||||
test->multisend = 10; /* arbitrary */
|
||||
}
|
||||
|
||||
|
||||
|
@ -58,6 +58,7 @@ char* iperf_get_test_server_hostname( struct iperf_test* ipt );
|
||||
int iperf_get_test_protocol_id( struct iperf_test* ipt );
|
||||
int iperf_get_test_json_output( struct iperf_test* ipt );
|
||||
int iperf_get_test_zerocopy( struct iperf_test* ipt );
|
||||
int iperf_get_test_may_use_sigalrm( struct iperf_test* ipt );
|
||||
|
||||
/* Setter routines for some fields inside iperf_test. */
|
||||
void iperf_set_control_socket( struct iperf_test* ipt, int ctrl_sck );
|
||||
@ -75,6 +76,7 @@ void iperf_set_test_server_hostname( struct iperf_test* ipt, char* server_hostna
|
||||
void iperf_set_test_json_output( struct iperf_test* ipt, int json_output );
|
||||
int iperf_has_zerocopy( void );
|
||||
void iperf_set_test_zerocopy( struct iperf_test* ipt, int zerocopy );
|
||||
void iperf_set_test_may_use_sigalrm( struct iperf_test* ipt, int may_use_sigalrm );
|
||||
|
||||
/**
|
||||
* exchange_parameters - handles the param_Exchange part for client
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/uio.h>
|
||||
@ -181,9 +182,22 @@ iperf_client_end(struct iperf_test *test)
|
||||
}
|
||||
|
||||
|
||||
static int sigalrm_triggered;
|
||||
|
||||
static void
|
||||
sigalrm_handler(int sig)
|
||||
{
|
||||
sigalrm_triggered = 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
iperf_run_client(struct iperf_test * test)
|
||||
{
|
||||
int concurrency_model;
|
||||
int startup;
|
||||
#define CM_SELECT 1
|
||||
#define CM_SIGALRM 2
|
||||
int result;
|
||||
fd_set read_set, write_set;
|
||||
struct timeval now;
|
||||
@ -205,15 +219,17 @@ iperf_run_client(struct iperf_test * test)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Begin calculating CPU utilization
|
||||
/* Begin calculating CPU utilization */
|
||||
cpu_util(NULL);
|
||||
|
||||
startup = 1;
|
||||
concurrency_model = CM_SELECT; /* always start in select mode */
|
||||
(void) gettimeofday(&now, NULL);
|
||||
while (test->state != IPERF_DONE) {
|
||||
|
||||
if (concurrency_model == CM_SELECT) {
|
||||
memcpy(&read_set, &test->read_set, sizeof(fd_set));
|
||||
memcpy(&write_set, &test->write_set, sizeof(fd_set));
|
||||
|
||||
result = select(test->max_fd + 1, &read_set, &write_set, NULL, tmr_timeout(&now));
|
||||
if (result < 0 && errno != EINTR) {
|
||||
i_errno = IESELECT;
|
||||
@ -226,8 +242,30 @@ iperf_run_client(struct iperf_test * test)
|
||||
}
|
||||
FD_CLR(test->ctrl_sck, &read_set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (test->state == TEST_RUNNING) {
|
||||
|
||||
/* Is this our first time in TEST_RUNNING mode? */
|
||||
if (startup) {
|
||||
startup = 0;
|
||||
/* Can we switch to SIGALRM mode? There are a bunch of
|
||||
** cases where either it won't work or it's ill-advised.
|
||||
*/
|
||||
if (test->may_use_sigalrm &&
|
||||
(test->protocol->id != Pudp || test->settings->rate == 0) &&
|
||||
(test->stats_interval == 0 || test->stats_interval > 1) &&
|
||||
(test->reporter_interval == 0 || test->reporter_interval > 1) &&
|
||||
! test->reverse) {
|
||||
concurrency_model = CM_SIGALRM;
|
||||
test->multisend = 1;
|
||||
signal(SIGALRM, sigalrm_handler);
|
||||
sigalrm_triggered = 0;
|
||||
alarm(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (test->reverse) {
|
||||
// Reverse mode. Client receives.
|
||||
if (iperf_recv(test, &read_set) < 0) {
|
||||
@ -235,14 +273,21 @@ iperf_run_client(struct iperf_test * test)
|
||||
}
|
||||
} else {
|
||||
// Regular mode. Client sends.
|
||||
if (iperf_send(test, &write_set) < 0) {
|
||||
if (iperf_send(test, concurrency_model == CM_SIGALRM ? NULL : &write_set) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (concurrency_model == CM_SELECT ||
|
||||
(concurrency_model == CM_SIGALRM && sigalrm_triggered)) {
|
||||
/* Run the timers. */
|
||||
(void) gettimeofday(&now, NULL);
|
||||
tmr_run(&now);
|
||||
if (concurrency_model == CM_SIGALRM) {
|
||||
sigalrm_triggered = 0;
|
||||
alarm(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Is the test done yet? */
|
||||
if (test->settings->bytes == 0) {
|
||||
@ -260,7 +305,8 @@ iperf_run_client(struct iperf_test * test)
|
||||
i_errno = IESENDMESSAGE;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* And if we were doing SIGALRM, go back to select for the end. */
|
||||
concurrency_model = CM_SELECT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,6 +78,9 @@ main(int argc, char **argv)
|
||||
iperf_errexit(NULL, "create new test error - %s", iperf_strerror(i_errno));
|
||||
iperf_defaults(test); /* sets defaults */
|
||||
|
||||
/* This main program doesn't use SIGALRM, so the iperf API may use it. */
|
||||
iperf_set_test_may_use_sigalrm(test, 1);
|
||||
|
||||
// XXX: Check signal for errors?
|
||||
signal(SIGINT, sig_handler);
|
||||
if (setjmp(env)) {
|
||||
|
Loading…
Reference in New Issue
Block a user