This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]