[PATCH v4 1/2] POSIX Asynchronous I/O support: aio files
Mark Geisert
mark@maxrnd.com
Tue Jul 24 05:03:00 GMT 2018
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
More information about the Cygwin-patches
mailing list