On Wed, Jan 26, 2011 at 11:34:33PM -0200, Christiano F. Haesbaert wrote: > On Thu, Jan 27, 2011 at 11:31:39AM +1100, Damien Miller wrote: > > On Wed, 26 Jan 2011, Christiano F. Haesbaert wrote: > > > > > Hi there, > > > > > > This diff adds udp support with PPS (packet per second) accounting and > > > changes tcpbench to use libevent instead of poll(2). > > > > > > The sender/client is pretty stupid, it sends as much as possible until > > > a ENOBUFS is reached, then it sleeps for 50ms, I'm not sure this is > > > acceptable, we don't have sched_yield(2) which would do the work so I > > > chose this random value, please correct me. > > > > Instead of sleeping, can you not wait for the fd to be writable again? > > (I haven't tried this, just wondering) > > > > -d > > Indeed, but it seems that libevent ends up calling the callback before being > actually able to write, not sure if libevent isn't respecting the writable fd > state or if it's a timing issue, I did some tests returning instead of trying > again and sleeping: > > tcpbench: sent > tcpbench: sent > tcpbench: sent > tcpbench: sent > tcpbench: write: No buffer space available > tcpbench: write: No buffer space available > tcpbench: write: No buffer space available > tcpbench: write: No buffer space available > > In my understanding we shouldn't reach the write warning two times in a row. >
poll() or the other mechanisms to check if a socket is writable or not have no way to see if a ENOBUF error will be returned on the write. The problem is that the UDP sendbuffer is always empty (it is only used to copy in the packet from userland). Then the packet is sent down the network stack where it can not be queued on the interface because its output queue is full. In that case ENOBUF is returned to userland but the socket is still perfectly writable and a sendto() with a different destination address may actually work. If you want to get the maximum speed out of tcpbench in udp mode then you need to busywait around the write call. -- :wq Claudio