This is the mail archive of the
cygwin-patches
mailing list for the Cygwin project.
Re: [PATCH v4 1/2] POSIX Asynchronous I/O support: aio files
Corinna Vinschen wrote:
Hi Mark,
there's just one problem left:
[...]
+
+ QueryUnbiasedInterruptTime (&time0);
Nice idea to use QueryUnbiasedInterruptTime. The problem here is just
that QueryUnbiasedInterruptTime has been introduced with Windows 7, but
we still support Windows Vista :}
We could just drop Vista support (is anybody actually using it?) but
there's an alternative: Include hires.h and use ntod, a global ns
counter object using Windows performance counters under the hood:
#include "hires.h"
time0 = ntod.nsecs (); /* ns, *not* 100ns */
...
With that single change I think your patch series can go in.
I don't want to be the one to say "drop Vista" because I tend to stay on the
trailing edge of Windows versions myself. Your idea of using ntod.nsecs() is a
nice fix, and dealing with nanoseconds all the way simplifies the code a bit:
static int
aiosuspend (const struct aiocb *const aiolist[],
int nent, const struct timespec *timeout)
{
/* Returns lowest list index of completed aios, else 'nent' if all completed.
* If none completed on entry, wait for interval specified by 'timeout'.
*/
int res;
sigset_t sigmask;
siginfo_t si;
ULONGLONG nsecs = 0;
ULONGLONG time0, time1;
struct timespec to = {0};
if (timeout)
{
to = *timeout;
if (to.tv_sec < 0 || to.tv_nsec < 0 || to.tv_nsec > NSPERSEC)
{
set_errno (EINVAL);
return -1;
}
nsecs = (NSPERSEC * to.tv_sec) + to.tv_nsec;
}
retry:
sigemptyset (&sigmask);
int aiocount = 0;
for (int i = 0; i < nent; ++i)
if (aiolist[i] && aiolist[i]->aio_liocb)
{
if (aiolist[i]->aio_errno == EINPROGRESS ||
aiolist[i]->aio_errno == ENOBUFS ||
aiolist[i]->aio_errno == EBUSY)
{
++aiocount;
if (aiolist[i]->aio_sigevent.sigev_notify == SIGEV_SIGNAL ||
aiolist[i]->aio_sigevent.sigev_notify == SIGEV_THREAD)
sigaddset (&sigmask, aiolist[i]->aio_sigevent.sigev_signo);
}
else
return i;
}
if (aiocount == 0)
return nent;
if (timeout && nsecs == 0)
{
set_errno (EAGAIN);
return -1;
}
time0 = ntod.nsecs ();
/* Note wait below is abortable even w/ empty sigmask and infinite timeout */
res = sigtimedwait (&sigmask, &si, timeout ? &to : NULL);
if (res == -1)
return -1; /* Return with errno set by failed sigtimedwait() */
time1 = ntod.nsecs ();
/* Adjust timeout to account for time just waited */
time1 -= time0;
if (time1 > nsecs)
nsecs = 0; // just in case we didn't get rescheduled very quickly
else
nsecs -= time1;
to.tv_sec = nsecs / NSPERSEC;
to.tv_nsec = nsecs % NSPERSEC;
goto retry;
}
The final patch set for the POSIX AIO feature will be appearing shortly.
Thanks & Regards,
..mark