[newlib-cygwin] Cygwin: timerfd: implement TFD_IOC_SET_TICKS ioctl

Corinna Vinschen corinna@sourceware.org
Wed Jan 16 17:41:00 GMT 2019


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=173e067a31bde9812c0f0ad19de082fb5e176427

commit 173e067a31bde9812c0f0ad19de082fb5e176427
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Wed Jan 16 18:40:53 2019 +0100

    Cygwin: timerfd: implement TFD_IOC_SET_TICKS ioctl
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/fhandler_timerfd.cc | 18 ++++++++++++++++--
 winsup/cygwin/timer.cc            | 16 ++++++++++++++++
 winsup/cygwin/timer.h             |  2 ++
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/winsup/cygwin/fhandler_timerfd.cc b/winsup/cygwin/fhandler_timerfd.cc
index cbcbefd..360731c 100644
--- a/winsup/cygwin/fhandler_timerfd.cc
+++ b/winsup/cygwin/fhandler_timerfd.cc
@@ -176,15 +176,29 @@ int
 fhandler_timerfd::ioctl (unsigned int cmd, void *p)
 {
   int ret = -1;
+  uint64_t ov_cnt;
 
   switch (cmd)
     {
     case TFD_IOC_SET_TICKS:
-      /* TODO */
+      __try
+	{
+	  timer_tracker *tt = (timer_tracker *) timerid;
+
+	  ov_cnt = *(uint64_t *) p;
+	  if (!ov_cnt)
+	    {
+	      set_errno (EINVAL);
+	      break;
+	    }
+	  tt->set_event (ov_cnt);
+	}
+      __except (EFAULT) {}
+      __endtry
       ret = 0;
       break;
     default:
-      set_errno (EINVAL);
+      ret = fhandler_base::ioctl (cmd, p);
       break;
     }
   syscall_printf ("%d = ioctl_timerfd(%x, %p)", ret, cmd, p);
diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc
index be3fcf7..c972745 100644
--- a/winsup/cygwin/timer.cc
+++ b/winsup/cygwin/timer.cc
@@ -132,6 +132,22 @@ timer_tracker::arm_event ()
   return ret;
 }
 
+void
+timer_tracker::set_event (uint64_t ov_cnt)
+{
+  LONG ret;
+
+  while ((ret = InterlockedCompareExchange (&event_running, EVENT_LOCK,
+					    EVENT_DISARMED)) == EVENT_LOCK)
+    yield ();
+  InterlockedExchange64 (&overrun_count, ov_cnt);
+  if (ret == EVENT_DISARMED)
+    {
+      SetEvent (get_timerfd_handle ());
+      InterlockedExchange (&event_running, EVENT_ARMED);
+    }
+}
+
 LONG64
 timer_tracker::_disarm_event ()
 {
diff --git a/winsup/cygwin/timer.h b/winsup/cygwin/timer.h
index 3b426a3..b9a072e 100644
--- a/winsup/cygwin/timer.h
+++ b/winsup/cygwin/timer.h
@@ -55,7 +55,9 @@ class timer_tracker
 
   void gettime (itimerspec *);
   int settime (int, const itimerspec *, itimerspec *);
+
   LONG arm_event ();
+  void set_event (uint64_t ov_cnt);
   unsigned int disarm_event ();
 
   DWORD thread_func ();



More information about the Cygwin-cvs mailing list