public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: "Stephen D. Williams" <sdw@lig.net>
To: James Antill <james@and.org>
Cc: Michael Lindner <mikel@att.net>, Chris Wedgwood <cw@f00f.org>,
	Dan Maas <dmaas@dcine.com>, Edgar Toernig <froese@gmx.de>,
	linux-kernel@vger.kernel.org
Subject: Re: PROBLEM: select() on TCP socket sleeps for 1 tick even if data     available
Date: Wed, 11 Apr 2001 17:03:34 -0400	[thread overview]
Message-ID: <3AD4C6A6.AB6F23F8@lig.net> (raw)
In-Reply-To: <fa.nc2eokv.1dj8r80@ifi.uio.no> <fa.dcei62v.1s5scos@ifi.uio.no> <015e01c082ac$4bf9c5e0$0701a8c0@morph> <3A69361F.EBBE76AA@att.net> <20010120200727.A1069@metastasis.f00f.org> <3A694254.B52AE20B@att.net> <3A6A09F2.8E5150E@gmx.de> <022f01c08342$088f67b0$0701a8c0@morph> <20010121133433.A1112@metastasis.f00f.org> <3A6A558D.5E0CF29E@att.net> <3AD1CD13.F1A917FA@lig.net> <nnbsq5opdz.fsf@code.and.org> <3AD35119.D1C5E90D@lig.net> <nng0fgmri0.fsf@code.and.org>

[-- Attachment #1: Type: text/plain, Size: 962 bytes --]

James Antill wrote:
...
> >                                                                    The
> > time went from 3.7 to 4.4 seconds per 100000.
> 
>  Ok here's a quick test that I've done. This passes data between 2
> processes. Obviously you can't compare this to your code or Michael's,
> however...

I've attached my version of his code with your suggested change. 
Possibly I didn't do it correctly.

>  The results with USE_DOUBLE_POLL on are...
> 
> % time ./pingpong
> ./pingpong  0.15s user 0.89s system 48% cpu 2.147 total
> % time ./pingpong
> ./pingpong  0.19s user 0.91s system 45% cpu 2.422 total
> % time ./pingpong
> ./pingpong  0.10s user 1.02s system 49% cpu 2.282 total
> 
>  The results with USE_DOUBLE_POLL off are...
> 
> % time ./pingpong
> ./pingpong  0.24s user 1.07s system 50% cpu 2.614 total
...

sdw
-- 
sdw@lig.net  http://sdw.st
Stephen D. Williams
43392 Wayside Cir,Ashburn,VA 20147-4622 703-724-0118W 703-995-0407Fax 
Dec2000

[-- Attachment #2: sockperf.c --]
[-- Type: text/plain, Size: 7448 bytes --]


#include <fcntl.h>
#include <memory.h>
#include <netdb.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdio.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <varargs.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <unistd.h>
#include <netinet/tcp.h>


#ifndef INADDR_NONE
#define INADDR_NONE     ~0
#endif

void
errexit(format, va_alist)
char    *format;
va_dcl
{
        va_list args;
        va_start(args);
        vfprintf(stderr, format, args);
        va_end(args);
        exit(1);
}

/*
 * passivesock - allocate & bind a server socket using TCP or UDP
 */

int
passivesock( service, protocol, qlen )
char    *service;       /* service associeted with the desired port     */
char    *protocol;      /* name of protocol to use ("tcp" or "udp")     */
int     qlen;           /* maximum length of the server request queue   */
{
        struct servent *pse;
        struct protoent *ppe;
        struct sockaddr_in sin;
        int     s, type;
        int     one = 1;
        int f=1;

        bzero((char *) & sin, sizeof(sin));
        sin.sin_family = AF_INET;
        sin.sin_addr.s_addr = INADDR_ANY;

        /* Map service name to port number */
        if ( pse = getservbyname(service, protocol) )
                sin.sin_port = htons(ntohs((u_short)pse->s_port));
        else if ( (sin.sin_port = htons((u_short)atoi(service))) == 0 )
                errexit("can't get \"%s\" service entry\n", service);

        /* Map protocol name to protocol number */
        if ( (ppe = getprotobyname(protocol)) == 0)
                errexit("can't get \"%s\" protocol entry\n", protocol);

        /* Use protocol to chose a socket type */
        if (strcmp(protocol, "udp") == 0)
                type = SOCK_DGRAM;
        else
                type = SOCK_STREAM;

        /* Allocate a socket */
        s = socket(PF_INET, type, ppe->p_proto);
        if (s < 0 )
                errexit("can't create socket: %s\n", strerror(errno));

        setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
        setsockopt(s, SOL_TCP, TCP_NODELAY, &f, sizeof(f));
        /* Bind the socket */
        if (bind(s, (struct sockaddr *) & sin, sizeof(sin)) < 0)
                errexit("can't bind to %s port: %s\n", service,
                    strerror(errno));
        if (type == SOCK_STREAM && listen(s, qlen) < 0)
                errexit("can't listen on %s port: %s\n", service,
                    strerror(errno));
        return s;
}

int
connectsock(host, service, protocol)
char    *host;
char    *service;
char    *protocol;
{
        struct hostent  *phe;
        struct servent  *pse;
        struct protoent *ppe;
        struct sockaddr_in      sin;
        int     s, type;
        int f=1;

        memset(&sin, 0, sizeof(sin));
        if (pse = getservbyname(service, protocol))
                sin.sin_port = pse->s_port;
        else if ((sin.sin_port = htons((u_short) atoi(service))) == 0) {
                fprintf(stderr, "can't get '%s' service entry\n", service);
                exit(1);
        }
        if (phe = gethostbyname(host)) 
                memcpy((char *) &sin.sin_addr, phe->h_addr, phe->h_length);
        else if ((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) {
                fprintf(stderr, "can't get '%s' host entry\n", host);
                exit(1);
        }
        /* if (ppe = getprotobyname(protocol)) {
                fprintf(stderr, "can't get '%s' protocol entry\n", protocol);
                exit(1);
        }
        if (strcmp(protocol, "udp") == 0)
                type = SOCK_DGRAM;
        else
                type = SOCK_STREAM;
        */
        sin.sin_family = AF_INET;
        s = socket(AF_INET, SOCK_STREAM, 6);
        setsockopt(s, SOL_TCP, TCP_NODELAY, &f, sizeof(f));
        if (s < 0) {
                perror("can't create socket\n");
                exit(1);
        }
        if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
                perror("can't connect to socket");
                exit(1);
        }
        return s;
}

void
pingpong(int r, int s, int ping)
{
        struct timeval then;
        struct timeval now;
        fd_set fds;
        fd_set readfds;
        int pings = 0;
	struct timeval zerotime;
	int ret;

        FD_ZERO(&fds);
        FD_SET(r, &fds);
        gettimeofday(&then, 0);
        if (ping) {
                send(s, ".", 1, 0);
                pings++;
        }
        readfds = fds;

	zerotime.tv_sec = 0;
	zerotime.tv_usec = 0;

	//	if (!(ret = select( ... , &zerotime)))
	//  ret = select( ... , NULL);
	//        while ((readfds=fds, ret = select(r+1, &readfds, 0, 0, 0)) ) {
	while ((ret = select(r+1, &readfds, 0, 0, &zerotime)) ||
	       (readfds=fds, ret = select(r+1, &readfds, 0, 0, 0)) ) {
	       if (FD_ISSET(r, &readfds)) {
                        char buf[1];
                        int n = read(r, buf, sizeof(buf));
                        if (n <= 0) {
                                break;
                        }
                        else {
                                if (pings++ < 100000) {
                                        send(s, ".", 1, 0);
                                }
                                else {
                                        break;
                                }
                        }
                }
                else {
                        fprintf(stderr, "fd not set!\n");
                }
                readfds = fds;
        }
        gettimeofday(&now, 0);
        fprintf(stderr, "elapsed time for 100000 pingpongs is %g\n", now.tv_sec - then.tv_sec + (now.tv_usec -
then.tv_usec) / 1000000.0);
        fprintf(stderr, "closing %d\n", r);
        close(r);
        fprintf(stderr, "closing %d\n", s);
        close(s);
}

main(argc, argv)
int     argc;
char    **argv;
{
        char    buf[1024];
        int     n;
        int     s;
        int     f;
        if (argc < 3) {
                errexit("usage: %s host port1 port2 [initiate]\n", argv[0]);
        }
        signal(SIGPIPE, SIG_IGN);
        f = passivesock(argv[2], "tcp", 2);
        if (f < 0) {
                errexit("listen failed: %s\n", strerror(errno));
        }
        for ( ; ; ) {
                struct sockaddr_in      fsin;
                int     alen = sizeof(fsin);
                if (argc < 5) {
                        int     r = accept(f, (struct sockaddr *) &fsin, &alen);
                        int     s = connectsock(argv[1], argv[3], "tcp");
                        if (r < 0)
                                errexit("accept failed: %s\n", strerror(errno));
                        if (s < 0)
                                errexit("connect failed: %s\n", strerror(errno));
                        pingpong(r, s, 0);
                }
                else {
                        int     s = connectsock(argv[1], argv[3], "tcp");
                        int     r = accept(f, (struct sockaddr *) &fsin, &alen);
                        if (r < 0)
                                errexit("accept failed: %s\n", strerror(errno));
                        if (s < 0)
                                errexit("connect failed: %s\n", strerror(errno));
                        pingpong(r, s, 1);
                        break;
                }
        }
        return 0;
}

  reply	other threads:[~2001-04-11 21:39 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <fa.nc2eokv.1dj8r80@ifi.uio.no>
     [not found] ` <fa.dcei62v.1s5scos@ifi.uio.no>
     [not found]   ` <015e01c082ac$4bf9c5e0$0701a8c0@morph>
2001-01-20  6:54     ` PROBLEM: select() on TCP socket sleeps for 1 tick even if data available Michael Lindner
2001-01-20  7:07       ` Chris Wedgwood
2001-01-20  7:46         ` Michael Lindner
2001-01-20 21:58           ` Edgar Toernig
2001-01-21  0:35             ` Dan Maas
2001-01-21  0:34               ` Chris Wedgwood
2001-01-21  1:22                 ` Michael Lindner
2001-01-21  1:29                   ` David Schwartz
2001-01-21  3:20                 ` Michael Lindner
2001-04-09 14:54                   ` Stephen D. Williams
2001-04-09 19:16                     ` James Antill
2001-04-10 18:29                       ` Stephen D. Williams
2001-04-10 20:25                         ` James Antill
2001-04-11 21:03                           ` Stephen D. Williams [this message]
2001-04-12  0:09                             ` James Antill
2001-01-24 20:31                 ` Boris Dragovic
     [not found]         ` <3A694357.1A7C6AAC@att.net>
2001-01-20  9:41           ` Dan Maas
2001-01-20 17:26             ` Michael Lindner
2001-01-24 23:56 Bernd Eckenfels
  -- strict thread matches above, loose matches on Subject: below --
2001-01-20 10:53 Bernd Eckenfels
2001-01-19 20:47 Michael Lindner
2001-01-19 23:20 ` David Schwartz
2001-01-20  2:30   ` Michael Lindner
2001-01-20  3:27     ` David Schwartz
2001-01-20  4:37       ` Michael Lindner
2001-01-20 12:26     ` Martin MaD Douda
2001-01-20 11:39       ` Bjorn Wesen
2001-01-19 23:31 ` Chris Wedgwood

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3AD4C6A6.AB6F23F8@lig.net \
    --to=sdw@lig.net \
    --cc=cw@f00f.org \
    --cc=dmaas@dcine.com \
    --cc=froese@gmx.de \
    --cc=james@and.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mikel@att.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox