PDA

View Full Version : July 29 patch -> slow map updates on FreeBSD



jonseq
08-06-2002, 07:34 PM
gcc3.0,qt2.3.2

prior to july 29 packet handling rework, map updated in real time (10 fps without any difficulty)

afterwards, updates come roughly once every 5 seconds - possibly correlated with the output of the chat window.

i verified this by using

cvs -D '2002-07-29' co showeq

(this retrieves the version just before the july 29 commit)

and applying my freebsd patch to a fresh directory (can be found in patches section). as i expected, i got the old real time updates, but with the old crashing problems

is there any chance that the pcap code changed from using read in a thread to a select? there may be latency/buffering issues due to BSD's pcap and select:
http://www.tcpdump.org/lists/workers/2001/05/msg00060.html

i have attached my patch, which should not break non-FreeBSD compiles, and could probably stand to be committed

jonseq
08-06-2002, 07:56 PM
I will try changing the timeout from 0 to 1 ms as part of my FreeBSD patch. This seems to be the likely culprit.

+ /* A word about pcap_open_live() from the docs
+ ** to_ms specifies the read timeout in milliseconds. The
+ ** read timeout is used to arrange that the read not necessarily
+ ** return immediately when a packet is seen, but that it wait
+ ** for some amount of time to allow more packets to arrive and
+ ** to read multiple packets from the OS kernel in one operation.
+ ** Not all platforms support a read timeout; on platforms that
+ ** don't, the read timeout is ignored.
+ **
+ ** In Linux 2.4.x with the to_ms set to 0 we get packets immediatly,
+ ** and thats what we need in this application, so don't change it!!
+ **
+ ** a race condition exists between this thread and the main thread
+ ** any artificial delay in getting packets can cause filtering problems
+ ** and cause us to miss new stream when the player zones.
+ */
// initialize the pcap object
- m_pcache_pcap = pcap_open_live((char *) device, 1500, true, 100, ebuf);
+ m_pcache_pcap = pcap_open_live((char *) device, 1500, true, 0, ebuf);

Dedpoet
08-06-2002, 08:04 PM
You sound like you know what you're talking about, jonseq, but I just want to be sure you're not referring to the fact that the "animate spawn" setting is set to "off". This is in the FAQ here (http://www.macsrule.com/~seqfaq/seq-faq.html#4.10). I don't mean to offend if that's not your problem, just wanted to point it out.

jonseq
08-06-2002, 08:07 PM
Don't worry, I lost my ego years ago.

The problem is simply that I do not get any updates whatsoever for several seconds - including my own position on the map. I am aware of that setting.

Thanks for the suggestion, though!

jonseq
08-06-2002, 08:24 PM
Indeed, changing the timeout value from 0 to 1 ms returned my freebsd showeq back to its former snappy self. attached is my diff (let me know if after applying the diff, it doesn't compile or run on Linux. )

fee
08-06-2002, 09:01 PM
The timeout value definitly does not work the same way for Linux as it does for BSD. I'll borrow the real fix from SINS which will set the BSD kernel to return packets immediatly.

fee

fee
08-06-2002, 09:26 PM
Actually, add the following from SINS to your FreeBSD patch

after this,


m_pcache_pcap = pcap_open_live((char *) device, 1500, true, 0, ebuf);

if (!m_pcache_pcap)
{
fprintf(stderr, "pcap_error:pcap_open_live(%s): %s\n", device, ebuf);
if ((getuid() != 0) && (geteuid() != 0))
fprintf(stderr, "Make sure you are running ShowEQ as root.\n");
exit(0);
}


add the following,


#ifdef __FreeBSD__
// if we're on FreeBSD, we need to call ioctl on the file descriptor
// with BIOCIMMEDIATE to get the kernel Berkeley Packet Filter device
// to return packets to us immediately, rather than holding them in
// it's internal buffer... if we don't do this, we end up getting 32K
// worth of packets all at once, at long intervals -- if someone
// knows a less hacky way of doing this, I'd love to hear about it.
// the problem here is that libpcap doesn't expose an API to do this
// in any way
int fd = *((int*)m_pcache_pcap);
int temp = 1;
if ( ioctl( fd, BIOCIMMEDIATE, &temp ) < 0 )
fprintf( stderr, "PCAP couldn't set immediate mode on BSD\n" );
#endif



Change the #ifdef to match what you use in your patch.

jonseq
08-07-2002, 10:19 AM
It works. Probably less CPU wasted by busy-waiting, too. Thanks.