From: wessels <> Date: Fri, 29 May 1998 05:35:29 +0000 (+0000) Subject: auto-tuning incoming_interval for comm_incoming call frequency X-Git-Tag: SQUID_3_0_PRE1~3211 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=309ad3b6ea1f3ce34e13feff668734456987f349;p=thirdparty%2Fsquid.git auto-tuning incoming_interval for comm_incoming call frequency --- diff --git a/src/client_side.cc b/src/client_side.cc index 6c992e1607..f549a07b9f 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.319 1998/05/28 15:25:18 rousskov Exp $ + * $Id: client_side.cc,v 1.320 1998/05/28 23:35:29 wessels Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -2292,7 +2292,7 @@ httpAccept(int sock, void *data) ConnStateData *connState = NULL; struct sockaddr_in peer; struct sockaddr_in me; - int max = 10; + int max = INCOMING_HTTP_MAX; while (max-- && !httpAcceptDefer()) { memset(&peer, '\0', sizeof(struct sockaddr_in)); memset(&me, '\0', sizeof(struct sockaddr_in)); diff --git a/src/comm.cc b/src/comm.cc index 87da8e8790..a5535a5dd7 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -1,7 +1,7 @@ /* - * $Id: comm.cc,v 1.265 1998/05/28 22:16:36 wessels Exp $ + * $Id: comm.cc,v 1.266 1998/05/28 23:35:31 wessels Exp $ * * DEBUG: section 5 Socket Functions * AUTHOR: Harvest Derived @@ -118,10 +118,6 @@ #define MAX_POLL_TIME 1000 #endif -#define commCheckIncoming \ - ((++incoming_counter & \ - (lastinc > 0 ? Config.incoming_rate.max : Config.incoming_rate.min)) == 0) - typedef struct { char *host; u_short port; @@ -160,9 +156,61 @@ static void commConnectCallback(ConnectStateData * cs, int status); static int commDeferRead(int fd); static int commResetFD(ConnectStateData * cs); static int commRetryConnect(ConnectStateData * cs); +static OBJH commIncomingStats; static struct timeval zero_tv; +/* + * Automatic tuning for incoming requests: + * + * INCOMING sockets are the ICP and HTTP ports. We need to check these + * fairly regularly, but how often? When the load increases, we + * want to check the incoming sockets more often. If we have a lot + * of incoming ICP, then we need to check these sockets more than + * if we just have HTTP. + * + * The variable 'incoming_interval' determines how many normal I/O + * events to process before checking incoming sockets again. + * Note we store the incoming_interval multipled by a factor + * of 16 (e.g. <<4) to have some pseudo-floating point precision. + * + * The variable 'io_events' counts how many normal I/O events have + * been processed. When io_events > incoming_interval, its time + * to check incoming sockets. + * + * Every time we check incoming sockets, we count how many new messages + * or connections were processed. This is used to adjust the + * incoming_interval for the next iteration. The new incoming_interval + * is calculated as the average of the current incoming_interval and + * 32 divided by the number of incoming events just processed. e.g. + * + * 1 1 32 + * incoming_interval = - incoming_interval + - ----------------- + * 2 2 incoming_events + * + * You can see the current value of incoming_interval, as well as + * a histogram of 'incoming_events' by asking the cache manager + * for 'comm_incoming', e.g.: + * + * % ./client mgr:comm_incoming + * + * Bugs: + * + * - We have 32 as a magic upper limit on incoming_interval. + * - INCOMING_TOTAL_MAX = INCOMING_ICP_MAX + INCOMING_HTTP_MAX, + * but this assumes only one ICP socket and one HTTP socket. + * If there are multiple incoming HTTP sockets, the we could + * conceivably process more than INCOMING_TOTAL_MAX events + * in comm_incoming(). + * + * The 'invert32[]' array is a pre-calculated array of division for 32/i + * + */ +static int io_events = 0; +static int incoming_interval = 16 << 4; +static int invert32[INCOMING_TOTAL_MAX]; +#define commCheckIncoming (++io_events > (incoming_interval>>4)) + static void CommWriteStateCallbackAndFree(int fd, int code) { @@ -715,166 +763,15 @@ commDeferRead(int fd) return F->defer_check(fd, F->defer_data); } -#if OLD_CODE -#if HAVE_POLL - -/* poll() version by: - * Stewart Forster , and - * Anthony Baxter */ - -static void -comm_poll_incoming(void) -{ - int fd; - int fds[4]; - struct pollfd pfds[3 + MAXHTTPPORTS]; - unsigned long N = 0; - unsigned long i, nfds; - int j; - PF *hdl = NULL; - polledinc = 0; - if (theInIcpConnection >= 0) - fds[N++] = theInIcpConnection; - if (theInIcpConnection != theOutIcpConnection) - if (theOutIcpConnection >= 0) - fds[N++] = theOutIcpConnection; - for (j = 0; j < NHttpSockets; j++) { - if (HttpSockets[j] < 0) - continue; - if (commDeferRead(HttpSockets[j])) - continue; - fds[N++] = HttpSockets[j]; - } - for (i = nfds = 0; i < N; i++) { - int events; - fd = fds[i]; - events = 0; - if (fd_table[fd].read_handler) - events |= POLLRDNORM; - if (fd_table[fd].write_handler) - events |= POLLWRNORM; - if (events) { - pfds[nfds].fd = fd; - pfds[nfds].events = events; - pfds[nfds].revents = 0; - nfds++; - } - } - if (!nfds) - return; -#if !ALARM_UPDATES_TIME - getCurrentTime(); -#endif - polledinc = poll(pfds, nfds, 0); - if (polledinc < 1) { - polledinc = 0; - return; - } - for (i = 0; i < nfds; i++) { - int revents; - if (((revents = pfds[i].revents) == 0) || ((fd = pfds[i].fd) == -1)) - continue; - if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR)) { - if (hdl = fd_table[fd].read_handler) { - fd_table[fd].read_handler = NULL; - hdl(fd, fd_table[fd].read_data); - } else - debug(5, 1) ("comm_poll_incoming: NULL read handler\n"); - } - if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)) { - if (hdl = fd_table[fd].write_handler) { - fd_table[fd].write_handler = NULL; - hdl(fd, fd_table[fd].write_data); - } else - debug(5, 1) ("comm_poll_incoming: NULL write handler\n"); - } - } - /* TO FIX: repoll ICP connection here */ -} -#else - -static void -comm_select_incoming(void) -{ - fd_set read_mask; - fd_set write_mask; - int maxfd = 0; - int fd = 0; - int fds[3 + MAXHTTPPORTS]; - int N = 0; - int i = 0; - PF *hdl = NULL; - polledinc = 0; - FD_ZERO(&read_mask); - FD_ZERO(&write_mask); - for (i = 0; i < NHttpSockets; i++) { - if (HttpSockets[i] < 0) - continue; - if (commDeferRead(HttpSockets[i])) - continue; - fds[N++] = HttpSockets[i]; - } - if (theInIcpConnection >= 0) - fds[N++] = theInIcpConnection; - if (theInIcpConnection != theOutIcpConnection) - if (theOutIcpConnection >= 0) - fds[N++] = theOutIcpConnection; - fds[N++] = 0; - for (i = 0; i < N; i++) { - fd = fds[i]; - if (fd_table[fd].read_handler) { - FD_SET(fd, &read_mask); - if (fd > maxfd) - maxfd = fd; - } - if (fd_table[fd].write_handler) { - FD_SET(fd, &write_mask); - if (fd > maxfd) - maxfd = fd; - } - } - if (maxfd++ == 0) - return; -#if !ALARM_UPDATES_TIME - getCurrentTime(); -#endif - polledinc = select(maxfd, &read_mask, &write_mask, NULL, &zero_tv); - if (polledinc < 1) { - polledinc = 0; - return; - } - for (i = 0; i < N; i++) { - fd = fds[i]; - if (FD_ISSET(fd, &read_mask)) { - if ((hdl = fd_table[fd].read_handler) != NULL) { - fd_table[fd].read_handler = NULL; - hdl(fd, fd_table[fd].read_data); - } else { - debug(5, 1) ("comm_select_incoming: NULL read handler\n"); - } - } - if (FD_ISSET(fd, &write_mask)) { - if ((hdl = fd_table[fd].write_handler) != NULL) { - fd_table[fd].write_handler = NULL; - hdl(fd, fd_table[fd].write_data); - } else { - debug(5, 1) ("comm_select_incoming: NULL write handler\n"); - } - } - } -} -#endif - -#endif /* OLD_CODE */ - static void comm_incoming(void) { int j; incame = 0; + io_events = 0; if (theInIcpConnection > 0) { icpHandleUdp(theInIcpConnection, &incame); - if (theInIcpConnection != theOutIcpConnection) + if (theInIcpConnection != theOutIcpConnection) icpHandleUdp(theOutIcpConnection, &incame); } for (j = 0; j < NHttpSockets; j++) { @@ -883,6 +780,8 @@ comm_incoming(void) httpAccept(HttpSockets[j], &incame); } statHistCount(&Counter.comm_incoming, incame); + if (incame < INCOMING_TOTAL_MAX) + incoming_interval = (incoming_interval >> 1) + (invert32[incame] << 3); } static int @@ -914,7 +813,6 @@ comm_poll(int msec) int num; static time_t last_timeout = 0; static int lastinc = 0; - static int incoming_counter = 0; double timeout = current_dtime + (msec / 1000.0); do { #if !ALARM_UPDATES_TIME @@ -1053,7 +951,6 @@ comm_select(int msec) int maxfd; int nfds; int num; - static int incoming_counter = 0; static time_t last_timeout = 0; struct timeval poll_time; static int lastinc; @@ -1294,6 +1191,7 @@ commSetTcpNoDelay(int fd) void comm_init(void) { + int i; fd_table = xcalloc(Squid_MaxFD, sizeof(fde)); /* XXX account fd_table */ /* Keep a few file descriptors free so that we don't run out of FD's @@ -1302,6 +1200,12 @@ comm_init(void) RESERVED_FD = XMIN(100, Squid_MaxFD / 4); zero_tv.tv_sec = 0; zero_tv.tv_usec = 0; + invert32[0] = 32; + for (i = 1; i < INCOMING_TOTAL_MAX; i++) + invert32[i] = (int) (32.0 / (double) i + 0.5); + cachemgrRegister("comm_incoming", + "comm_incoming() stats", + commIncomingStats, 0); } @@ -1510,3 +1414,15 @@ ignoreErrno(int ierrno) } /* NOTREACHED */ } + +static void +commIncomingStats(StoreEntry * sentry) +{ + StatCounters *f = &Counter; + storeAppendPrintf(sentry, "Current incoming_interval: %d\n", + incoming_interval >> 4); + storeAppendPrintf(sentry, "\n"); + storeAppendPrintf(sentry, "Histogram of number of incoming sockets or\n"); + storeAppendPrintf(sentry, "Messages handled per comm_incoming() call:\n"); + statHistDump(&f->comm_incoming, sentry, statHistIntDumper); +} diff --git a/src/defines.h b/src/defines.h index ede07b856d..4374ab82e4 100644 --- a/src/defines.h +++ b/src/defines.h @@ -221,3 +221,14 @@ /* handy to determine the #elements in a static array */ #define countof(arr) (sizeof(arr)/sizeof(*arr)) + +/* + * Max number of ICP messages to receive per call to icpHandleUdp + */ +#define INCOMING_ICP_MAX 15 +/* + * Max number of HTTP connections to accept per call to httpAccept + * and PER HTTP PORT + */ +#define INCOMING_HTTP_MAX 10 +#define INCOMING_TOTAL_MAX (INCOMING_ICP_MAX+INCOMING_HTTP_MAX) diff --git a/src/icp_v2.cc b/src/icp_v2.cc index 74d1548fda..4b20a3aaa5 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -306,7 +306,7 @@ icpHandleUdp(int sock, void *data) LOCAL_ARRAY(char, buf, SQUID_UDP_SO_RCVBUF); int len; int icp_version; - int max = 16; + int max = INCOMING_ICP_MAX; commSetSelect(sock, COMM_SELECT_READ, icpHandleUdp, NULL, 0); while (max--) { from_len = sizeof(from); diff --git a/src/stat.cc b/src/stat.cc index 048567d8e6..478af4adbf 100644 --- a/src/stat.cc +++ b/src/stat.cc @@ -1,6 +1,6 @@ /* - * $Id: stat.cc,v 1.256 1998/05/27 20:31:37 wessels Exp $ + * $Id: stat.cc,v 1.257 1998/05/28 23:35:33 wessels Exp $ * * DEBUG: section 18 Cache Manager Statistics * AUTHOR: Harvest Derived @@ -883,7 +883,7 @@ statCountersInitSpecial(StatCounters * C) * Cache Digest Stuff */ statHistEnumInit(&C->cd.on_xition_count, CacheDigestHashFuncCount); - statHistEnumInit(&C->comm_incoming, 20); + statHistEnumInit(&C->comm_incoming, INCOMING_TOTAL_MAX); } /* add special cases here as they arrive */ @@ -928,7 +928,6 @@ static void statCountersHistograms(StoreEntry * sentry) { StatCounters *f = &Counter; -#if TOO_MUCH_OUTPUT storeAppendPrintf(sentry, "client_http.all_svc_time histogram:\n"); statHistDump(&f->client_http.all_svc_time, sentry, NULL); storeAppendPrintf(sentry, "client_http.miss_svc_time histogram:\n"); @@ -943,9 +942,6 @@ statCountersHistograms(StoreEntry * sentry) statHistDump(&f->icp.reply_svc_time, sentry, NULL); storeAppendPrintf(sentry, "dns.svc_time histogram:\n"); statHistDump(&f->dns.svc_time, sentry, NULL); -#endif - storeAppendPrintf(sentry, "comm_incoming histogram:\n"); - statHistDump(&f->comm_incoming, sentry, statHistIntDumper); } static void diff --git a/src/structs.h b/src/structs.h index 8cb8acc97e..edd8709884 100644 --- a/src/structs.h +++ b/src/structs.h @@ -355,10 +355,6 @@ struct _SquidConfig { struct { size_t limit; } MemPools; - struct { - int min; - int max; - } incoming_rate; }; struct _SquidConfig2 {