Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

#60 IOMETER not honoring "Delay" specs for network under Linux

open
nobody
None
5
2009-01-19
2009-01-19
Paul Drews
No

When IOMETER waits, it does so at the lowest level by calling aio_suspend() with a timeout and a list of outstanding asynchronous Ios (so that it can handle/complete any Ios that complete while it is waiting). It turns out that there is an obscurely documented feature of aio_suspend(): if there are no actual outstanding Ios in the list, aio_suspend() returns immediately without an error and without waiting for the timeout time. IOMETER propagates this up as if it were a timeout. The top-level logic also erroneously concludes that the entire timeout has elapsed and returns from the "Delay" procedure immediately. I fixed the loop in the "delay" procedure to (1) do a regular sleep instead of a wait-for-io operation if there are no outstanding Ios, and (2) to keep on doing either kind of wait until the full delay time has elapsed.

This problem was seen on the current 2008-06-22-rc2 release under Linux (Fedora 9) on an X86_64 platform.

A patch that fixes the problem is as follows:

Index: src/IOGrunt.cpp

===================================================================

--- src.orig/IOGrunt.cpp

+++ src/IOGrunt.cpp

@@ -977,8 +977,22 @@ void Grunt::Asynchronous_Delay(int trans

do {

_ftime(&start_wait_time);

- if (Complete_IO(transfer_delay) == ReturnTimeout)

- return;

+ // Complete_IO ultimately calls aio_suspend(). If there are

+ // no outstanding IOs, aio_suspend returns immediately without

+ // an error and higher software layers turn the return into

+ // an apparent timeout. So if there are no oustanding IOs

+ // we should do a plain Sleep instead of a Complete_IO,

+ // because a Complete_IO would turn this into a busy-polling

+ // loop.

+ //

+ // Furthermore, even some IOs complete, we need to keep on

+ // going through this loop until the entire transfer_delay

+ // has been honored.

+ if (outstanding_ios > 0) {

+ Complete_IO(transfer_delay);

+ } else {

+ Sleep(transfer_delay);

+ }

// More waiting is needed before allowing additional requests.

_ftime(&end_wait_time);

Discussion