Try to improve slirp performance again (though passive mode is still slower)

This commit is contained in:
gbeauche 2006-04-02 21:06:50 +00:00
parent 7c68ef5418
commit 896ada92dc
3 changed files with 42 additions and 30 deletions

View File

@ -33,6 +33,9 @@
#define USE_POLL 1 #define USE_POLL 1
#endif #endif
// Define to let the slirp library determine the right timeout for select()
#define USE_SLIRP_TIMEOUT 1
#ifdef HAVE_SYS_POLL_H #ifdef HAVE_SYS_POLL_H
#include <sys/poll.h> #include <sys/poll.h>
#endif #endif
@ -801,9 +804,12 @@ void *slirp_receive_func(void *arg)
FD_ZERO(&rfds); FD_ZERO(&rfds);
FD_ZERO(&wfds); FD_ZERO(&wfds);
FD_ZERO(&xfds); FD_ZERO(&xfds);
slirp_select_fill(&nfds, &rfds, &wfds, &xfds); int timeout = slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
#if ! USE_SLIRP_TIMEOUT
timeout = 10000;
#endif
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = 10000; tv.tv_usec = timeout;
if (select(nfds + 1, &rfds, &wfds, &xfds, &tv) >= 0) if (select(nfds + 1, &rfds, &wfds, &xfds, &tv) >= 0)
slirp_select_poll(&rfds, &wfds, &xfds); slirp_select_poll(&rfds, &wfds, &xfds);
@ -865,7 +871,7 @@ static void *receive_func(void *arg)
// Wait for interrupt acknowledge by EtherInterrupt() // Wait for interrupt acknowledge by EtherInterrupt()
sem_wait(&int_ack); sem_wait(&int_ack);
} else } else
usleep(20000); Delay_usec(20000);
} }
return NULL; return NULL;
} }

View File

@ -15,7 +15,7 @@ extern "C" {
int slirp_init(void); int slirp_init(void);
void slirp_select_fill(int *pnfds, int slirp_select_fill(int *pnfds,
fd_set *readfds, fd_set *writefds, fd_set *xfds); fd_set *readfds, fd_set *writefds, fd_set *xfds);
void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds); void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds);

View File

@ -183,13 +183,12 @@ static void updtime(void)
} }
#endif #endif
void slirp_select_fill(int *pnfds, int slirp_select_fill(int *pnfds,
fd_set *readfds, fd_set *writefds, fd_set *xfds) fd_set *readfds, fd_set *writefds, fd_set *xfds)
{ {
struct socket *so, *so_next; struct socket *so, *so_next;
struct timeval timeout;
int nfds; int nfds;
int tmp_time; int timeout, tmp_time;
/* fail safe */ /* fail safe */
global_readfds = NULL; global_readfds = NULL;
@ -301,36 +300,43 @@ void slirp_select_fill(int *pnfds,
* Setup timeout to use minimum CPU usage, especially when idle * Setup timeout to use minimum CPU usage, especially when idle
*/ */
timeout = -1;
/* /*
* First, see the timeout needed by *timo * If a slowtimo is needed, set timeout to 5ms from the last
*/
timeout.tv_sec = 0;
timeout.tv_usec = -1;
/*
* If a slowtimo is needed, set timeout to 500ms from the last
* slow timeout. If a fast timeout is needed, set timeout within * slow timeout. If a fast timeout is needed, set timeout within
* 200ms of when it was requested. * 2ms of when it was requested.
*/ */
# define SLOW_TIMO 5
# define FAST_TIMO 2
if (do_slowtimo) { if (do_slowtimo) {
/* XXX + 10000 because some select()'s aren't that accurate */ timeout = (SLOW_TIMO - (curtime - last_slowtimo)) * 1000;
timeout.tv_usec = ((500 - (curtime - last_slowtimo)) * 1000) + 10000; if (timeout < 0)
if (timeout.tv_usec < 0) timeout = 0;
timeout.tv_usec = 0; else if (timeout > (SLOW_TIMO * 1000))
else if (timeout.tv_usec > 510000) timeout = SLOW_TIMO * 1000;
timeout.tv_usec = 510000;
/* Can only fasttimo if we also slowtimo */ /* Can only fasttimo if we also slowtimo */
if (time_fasttimo) { if (time_fasttimo) {
tmp_time = (200 - (curtime - time_fasttimo)) * 1000; tmp_time = (FAST_TIMO - (curtime - time_fasttimo)) * 1000;
if (tmp_time < 0) if (tmp_time < 0)
tmp_time = 0; tmp_time = 0;
/* Choose the smallest of the 2 */ /* Choose the smallest of the 2 */
if (tmp_time < timeout.tv_usec) if (tmp_time < timeout)
timeout.tv_usec = (u_int)tmp_time; timeout = tmp_time;
} }
} }
*pnfds = nfds; *pnfds = nfds;
/*
* Adjust the timeout to make the minimum timeout
* 2ms (XXX?) to lessen the CPU load
*/
if (timeout < FAST_TIMO)
timeout = FAST_TIMO;
return timeout;
} }
void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
@ -349,11 +355,11 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
* See if anything has timed out * See if anything has timed out
*/ */
if (link_up) { if (link_up) {
if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) { if (time_fasttimo && ((curtime - time_fasttimo) >= FAST_TIMO)) {
tcp_fasttimo(); tcp_fasttimo();
time_fasttimo = 0; time_fasttimo = 0;
} }
if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) { if (do_slowtimo && ((curtime - last_slowtimo) >= SLOW_TIMO)) {
ip_slowtimo(); ip_slowtimo();
tcp_slowtimo(); tcp_slowtimo();
last_slowtimo = curtime; last_slowtimo = curtime;