[Winpcap-users] Using threads.

Gianluca Varenni gianluca.varenni at cacetech.com
Thu Mar 16 15:47:34 GMT 2006


Well, first of all, if no packets are available, although you set a timeout 
of 1ms, pcap_next_ex will probably return after 10 or 15 ms, because this is 
the granularity of WaitForSingleObject when NO handles you are waiting on 
are signalled (and this the same for Sleep()). BTW 10 or 15 ms is the 
scheduling quantum on Windows (10 or 15 depends on the particular flavor of 
the kernel, UP or SMP and client or server version).

Generally speaking, "spinning" on a WaitForSingleObject with a timeout > 0 
does not take basically any CPU time (this is basically what happens when 
you do a "while(pcap_next_ex){}" loop).

Just try this and look at the CPU load.

int _tmain(int argc, _TCHAR* argv[])
{
  HANDLE hEvent;

  //create an event, initial state = NOT signalled
  hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  do
  {
     WaitForSingleObject(hEvent, 1);
  }
  while(TRUE);
  return 0;
}

Change the timeout from 1ms to 0ms, and the CPU will go 100% (if timeout is 
0, you ARE really spinning on the event).


Have a nice day.
GV


----- Original Message ----- 
From: "David Barnish" <david.barnish at spanlink.com>
To: <winpcap-users at winpcap.org>
Sent: Wednesday, March 15, 2006 12:07 PM
Subject: RE: [Winpcap-users] Using threads.


Whether the read call blocks or not depends on the read timeout value
passed to the pcap_openxxx() function and the SetMinToCopy() value if
used. If the pcap_openxxx() function was told to return immediately (a
-1 is passed I believe for param 4), the pcap_dispatch() and
pcap_next_ex() will return immediately whether there are any packets to
read or not. The code that Ramiro included showed that a 1 millisecond
read timeout is used. So, within his while loop, the code will wait at
most 1 millisecond (give or take a few milliseconds) before it returns.
When it returns, it may have a packet of data, or it may return a null
packet pointer if there were no packets to read. So, I still say that he
is spinning in his while loop and taking away CPU resources from other
threads. In fact, the problem should be worse when there are no packets
arriving at the interface being sniffed. I may be wrong, but this is how
I am reading the WinPCap code.

An easy test for this assumption would be to use a larger read timeout
value in the pcap_open_live(). Instead of using 1 millisecond, use
something like 1,000.


Thank you,
David Barnish

Senior Software Engineer R&D
Spanlink Communications


-----Original Message-----
From: winpcap-users-bounces at winpcap.org
[mailto:winpcap-users-bounces at winpcap.org] On Behalf Of Guy Harris
Sent: Wednesday, March 15, 2006 1:15 PM
To: winpcap-users at winpcap.org
Subject: Re: [Winpcap-users] Using threads.

David Barnish wrote:
> Just my opinion from quickly looking at the code, but I think your
> problem is thread contention/context switching.
>
> For each thread, you have an endless loop that calls pcap_next_ex(),
> processes the packet, then immediately loops and does the same thing.
> Each thread will be trying to run non-stop and processing incoming
> packets until the OS forces it out of the CPU queue so another thread
> can run. This is similar to two threads running a function like this
at
> the same time:
>
> While(true)
> {
> Printf("Hello World.\n");
> }
>
> Both threads are trying to use system resources and are not giving up
> control voluntarily.
>
> My suggestion is to use the pcap_dispatch() function (or something
> similar) so the thread will sleep for a bit, then wake up and process
> multiple packets.

The thread will only sleep in pcap_dispatch() if there are no packets
available to be read at that instant.

The same is true for pcap_next_ex(); the only difference between a loop
using pcap_dispatch() and a loop using pcap_loop_ex() is that the loop
using pcap_dispatch() could process more than one packet per
pcap_dispatch() call while the loop using pcap_loop_ex() processes only
one packet per pcap_loop_ex() call.

"Processes" here means "hands to the callback" in the case of
pcap_dispatch() and "returns to the caller" in the case of
pcap_next_ex().  Both pcap_dispatch() and pcap_loop_ex() ultimately call

the read op for the pcap_t; in WinPcap, the read op:

checks whether there are any packets left in its buffer and, if
there
aren't, reads a new batch of packets into the buffer - that read might
return immediately or might block;

processes all the packets in the buffer if called with a count
argument
of -1, or processes no more than the number of packets specified with a
positive count argument.

pcap_next_ex() calls it with a count of 1; pcap_dispatch() calls it with

the count specified to pcap_dispatch().

So there won't be a difference between the two loops with regard to when

they sleep - they'll sleep if the kernel code blocks waiting for enough
packets to arrive or for the timeout to expire.

The pcap_next_ex() loop makes more calls to the read op, as each call
asks it to process only one packet from its buffer, so it might consume
more CPU time; that's the only difference you should see.

> Another method would be to get the read event for the interface and
put
> a WaitForSingleObject() call at the top of the loop, waiting on this
> event and using a timeout of 500 milliseconds or so. In this way, the
> thread would voluntarily give up control for a short time

Not if there are packets ready to be read.
_______________________________________________
Winpcap-users mailing list
Winpcap-users at winpcap.org
https://www.winpcap.org/mailman/listinfo/winpcap-users

_______________________________________________
Winpcap-users mailing list
Winpcap-users at winpcap.org
https://www.winpcap.org/mailman/listinfo/winpcap-users



More information about the Winpcap-users mailing list