www.smartbusinesschoices.com

Leading Business and Technology,
News and information


Part of the Identityscape.com network...

getxfactor.com jmoodmusic.com smartbusinesschoices.com mintdepot.com lowfaresalways.com evangelicalview.com shoppingpodder.com soproudlywehail.com webnews.ws currenthumor.com

 

 

change poll and select to epoll
   Smart Linux Business Choices! - the Best of UseNet Postings! Forum Index -> Linux Development - Applications  
View previous topic :: View next topic  
Author Message
yikaikai@gmail.com
Guest






PostPosted: Thu Nov 06, 2008 3:04 am    Post subject: change poll and select to epoll Reply with quote

hi all,

now I want change poll and select to epoll call in squid 2.5.6, is
it difficult to do that ? I know squid3.0 using epoll, but I have to
modify 2.5.6, I found in comm_select.c:
for (;Wink {
statCounter.syscalls.polls++;
num = poll(pfds, nfds, msec);


but I don't know how to change it to epoll, someone can give me an
example? thanks
Back to top
David Schwartz
Guest






PostPosted: Thu Nov 06, 2008 3:13 am    Post subject: Re: change poll and select to epoll Reply with quote

On Nov 5, 7:04 pm, "yikai...@gmail.com" <yikai...@gmail.com> wrote:
Quote:
hi all,

    now I want change poll and select to epoll call in squid 2.5.6, is
it difficult to do that ?  I know squid3.0 using epoll, but I have to
modify 2.5.6, I found in comm_select.c:
        for (;Wink {
            statCounter.syscalls.polls++;
            num = poll(pfds, nfds, msec);

but I don't know how to change it to epoll, someone can give me an
example?  thanks

I wouldn't bother. Either upgrade to Squid 3.0 or live with 'poll'.

If you absolutely, positively must, you can make a 'poll' wrapper. The
logic is like this:

1) Compare the input poll set to the poll set on the previous call to
'poll'. For any differences you find, use 'epoll_ctl' to update the
event set in the kernel to match that of squid.

2) Save a copy of the current poll set for the next call to 'poll'.

3) Call 'epoll_wait'.

4) Set the returned events in the input poll set to all zeroes. The
update the returned events in the input poll set based on any events
returned from 'epoll_wait'.

5) Return the appropriate return code.

This will only work if all calls to 'poll' are coming from
substantially the same code to substantially the same set of
descriptors. I would think this would be the case for squid2, but I
don't know for sure.

DS
Back to top
David Schwartz
Guest






PostPosted: Thu Nov 06, 2008 4:01 am    Post subject: Re: change poll and select to epoll Reply with quote

I got bored. Here's your 100% untested drop-in epoll-based replacement
for 'poll'. It may or may not work. It compiles, but is untested"

#include <sys/poll.h>
#include <sys/epoll.h>

/*
Drop in poll->epoll upgrader
By: David J. Schwartz, Copyright 2008, <davids@webmaster.com>
May or may not be suitable for your application! CAUTION!

Redistribution and use in source and binary forms, with or without
modification, are permitted. This software is provided 'as is' and
no representation is made that it is suitable for any purpose. It
has
not been debugged or tested in any way.

CAUTION: This drop-in replacement for 'poll' using 'epoll' may or
may not improve performance and may or may not break your code!
It is definitely inferior to modifying the code itself to use
'epoll'.
It will fail horribly if the program using it generates calls to
'poll_epoll' from more than one place with fundamentally different
'ufds' parameters!
*/

static int epoll_fd=-1;
static struct epoll_event epoll_ev[32768];
static int reg_ev[65536];

int poll_epoll(struct pollfd *ufds, nfds_t nfds, int timeout)
{
int i, j, rc, ec;

/*
First step: Make sure we have an epoll fd. Sanity checks.
Initialization if needed.
*/

if(epoll_fd<0)
{
if(epoll_fd==-2) return poll(ufds, nfds, timeout);
epoll_fd=epoll_create(32768);
if(epoll_fd<0)
{
epoll_fd=-2;
return poll(ufds, nfds, timeout);
}
for(i=0; i<65536; i++) reg_ev[i]=0;
}

/*
Second step: Add any missing events.
Extra events are okay, we'll catch them in step four.
*/
for(i=0; i<nfds; i++)
{
ufds[i].revents=0;
int fd=ufds[i].fd;
if(fd>=0)
{ /* This is a valid test for events */
ufds[i].revents=0;
if(reg_ev[fd]!=ufds[i].events)
{
int missing_events=ufds[i].events&~reg_ev[i];
if(missing_events!=0)
{ /* we need to add at least one event */
struct epoll_event ev;
ev.data.fd=fd;
ev.events=reg_ev[i]|missing_events;
epoll_ctl(epoll_fd, (reg_ev[fd]==0) ? EPOLL_CTL_ADD :
EPOLL_CTL_MOD,
fd, &ev);
reg_ev[i]=ev.events;
}
}
}
}

/*
Third step: Call epoll. Return error, if any
*/
rc=epoll_wait(epoll_fd, epoll_ev, 32768, timeout);
if(rc<=0) return rc;

/*
Fourth step: Report events, unregister unwanted ones
*/
ec=0;
for(i=0; i<rc; i++)
{
int fd=epoll_ev[j].data.fd;
int needed_events=0;
int remaining_events=epoll_ev[j].events;
for(j=0; j<nfds; j++)
if(fd==ufds[i].fd)
{ /* we found a hit on an FD that we are interested in */
int report=ufds[i].events|POLLHUP|POLLNVAL|POLLERR;
needed_events|=report; // still interested in these
remaining_events&=~report; // still not interested in these
ufds[i].revents=epoll_ev[j].events&report;
if(ufds[i].revents!=0) ec++;
}
if(remaining_events)
{ /* we found some events we could not report */
struct epoll_event ev;
ev.data.fd=fd;
ev.events=needed_events;
epoll_ctl(epoll_fd, (needed_events==0) ? EPOLL_CTL_DEL :
EPOLL_CTL_MOD,
fd, &ev);
}
}

return ec;
}
Back to top
David Schwartz
Guest






PostPosted: Thu Nov 06, 2008 4:23 am    Post subject: Re: change poll and select to epoll Reply with quote

Sorry to reply to myself again. Here it is with some loop variable
bugs fixed. This passes, at least, the Apache APR poll test. I
verified with 'strace' that it was calling the various 'epoll'
functions.

#include <sys/poll.h>
#include <sys/epoll.h>

/*
Drop in poll->epoll upgrader
By: David J. Schwartz, Copyright 2008, <davids@webmaster.com>
May or may not be suitable for your application! CAUTION!

Redistribution and use in source and binary forms, with or without
modification, are permitted. This software is provided 'as is' and
no representation is made that it is suitable for any purpose. It
has
not been debugged or tested in any way.

CAUTION: This drop-in replacement for 'poll' using 'epoll' may or
may not improve performance and may or may not break your code!
It is definitely inferior to modifying the code itself to use
'epoll'.
It will fail horribly if the program using it generates calls to
'poll_epoll' from more than one place with fundamentally different
'ufds' parameters!
*/

static int epoll_fd=-1;
static struct epoll_event epoll_ev[32768];
static int reg_ev[65536];

int poll_epoll(struct pollfd *ufds, nfds_t nfds, int timeout)
{
int i, j, rc, ec;

/*
First step: Make sure we have an epoll fd. Sanity checks.
Initialization if needed.
*/

if(epoll_fd<0)
{
if(epoll_fd==-2) return poll(ufds, nfds, timeout);
epoll_fd=epoll_create(32768);
if(epoll_fd<0)
{
epoll_fd=-2;
return poll(ufds, nfds, timeout);
}
for(i=0; i<65536; i++) reg_ev[i]=0;
}

/*
Second step: Add any missing events.
Extra events are okay, we'll catch them in step four.
*/
for(i=0; i<nfds; i++)
{
ufds[i].revents=0;
int fd=ufds[i].fd;
if(fd>=0)
{ /* This is a valid test for events */
ufds[i].revents=0;
if(reg_ev[fd]!=ufds[i].events)
{
int missing_events=ufds[i].events&~reg_ev[i];
if(missing_events!=0)
{ /* we need to add at least one event */
struct epoll_event ev;
ev.data.fd=fd;
ev.events=reg_ev[i]|missing_events;
epoll_ctl(epoll_fd, (reg_ev[fd]==0) ? EPOLL_CTL_ADD :
EPOLL_CTL_MOD,
fd, &ev);
reg_ev[i]=ev.events;
}
}
}
}

/*
Third step: Call epoll. Return error, if any
*/
rc=epoll_wait(epoll_fd, epoll_ev, 32768, timeout);
if(rc<=0) return rc;

/*
Fourth step: Report events, unregister unwanted ones
*/
ec=0;
for(i=0; i<rc; i++)
{
int fd=epoll_ev[i].data.fd;
int needed_events=0;
int remaining_events=epoll_ev[i].events;
for(j=0; j<nfds; j++)
if(fd==ufds[j].fd)
{ /* we found a hit on an FD that we are interested in */
int report=ufds[j].events|POLLHUP|POLLNVAL|POLLERR;
needed_events|=report; // still interested in these
remaining_events&=~report; // still not interested in these
ufds[j].revents=epoll_ev[i].events&report;
if(ufds[j].revents!=0) ec++;
}
if(remaining_events)
{ /* we found some events we could not report */
struct epoll_event ev;
ev.data.fd=fd;
ev.events=needed_events;
epoll_ctl(epoll_fd, (needed_events==0) ? EPOLL_CTL_DEL :
EPOLL_CTL_MOD,
fd, &ev);
}
}

return ec;
}
Back to top
David Schwartz
Guest






PostPosted: Thu Nov 06, 2008 4:39 am    Post subject: Re: change poll and select to epoll Reply with quote

On Nov 5, 8:23 pm, David Schwartz <dav...@webmaster.com> wrote:

Sorry to reply to myself yet again, I'm starting to feel like Skybuck.
There was another serious bug. I should have just pointed to a web
page in the first place. Sorry. Here's the one-liner fix:


--- bad/poll_replace.c 2008-11-05 20:36:57.000000000 -0800
+++ good/poll_replace.c 2008-11-05 20:36:57.000000000 -0800
@@ -100,7 +100,7 @@ int poll_epoll(struct pollfd *ufds, nfds
{ /* we found some events we could not report */
struct epoll_event ev;
ev.data.fd=fd;
- ev.events=needed_events;
+ ev.events=ref_ev[j]=needed_events;
epoll_ctl(epoll_fd, (needed_events==0) ? EPOLL_CTL_DEL :
EPOLL_CTL_MOD,
fd, &ev);
}

Sadly, this is a serious bug. It could cause us to permanently lose
events. I will put maintain a version with a version number and all
current bugfixes at the following URL:
http://beta.webmaster.com/poll_replace.c

Sorry again.

DS
Back to top
David Schwartz
Guest






PostPosted: Thu Nov 06, 2008 7:09 am    Post subject: Re: change poll and select to epoll Reply with quote

On Nov 5, 8:39 pm, David Schwartz <dav...@webmaster.com> wrote:

Quote:
URL:http://beta.webmaster.com/poll_replace.c

I tested this version of the patch on an old IRC server codebase from
2005. Using 'poll' directly, it used 60% of the CPU, and still fell
behind, dropping many of the test clients due to send queues being
exceeded. With the patch, the CPU was at 40%, and no test clients were
dropped.

I found that very, very surprising.

DS
Back to top
yikaikai@gmail.com
Guest






PostPosted: Thu Nov 06, 2008 8:58 am    Post subject: Re: change poll and select to epoll Reply with quote

Thank you for your code

On Nov 6, 12:23 pm, David Schwartz <dav...@webmaster.com> wrote:
Back to top
Display posts from previous:   
   Smart Linux Business Choices! - the Best of UseNet Postings! Forum Index -> Linux Development - Applications  
Page 1 of 1
All times are GMT

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum