You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/01/10 05:33:19 UTC

[nuttx] branch master updated: drivers/pipe:add PIPEIOC_POLLTHRES to set POLLIN/POLLOUT threshold

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 587305723e drivers/pipe:add PIPEIOC_POLLTHRES to set POLLIN/POLLOUT threshold
587305723e is described below

commit 587305723e85f1dd9aeb6d1aadafb60efc559a90
Author: 田昕 <ti...@xiaomi.com>
AuthorDate: Fri Jan 6 20:51:14 2023 +0800

    drivers/pipe:add PIPEIOC_POLLTHRES to set POLLIN/POLLOUT threshold
    
    Signed-off-by: 田昕 <ti...@xiaomi.com>
---
 drivers/pipes/pipe_common.c | 84 ++++++++++++++++++++++++++++++++++++---------
 drivers/pipes/pipe_common.h |  2 ++
 include/nuttx/fs/ioctl.h    | 36 ++++++++++++++-----
 3 files changed, 97 insertions(+), 25 deletions(-)

diff --git a/drivers/pipes/pipe_common.c b/drivers/pipes/pipe_common.c
index 1ab3ea427c..d68896dd1f 100644
--- a/drivers/pipes/pipe_common.c
+++ b/drivers/pipes/pipe_common.c
@@ -60,6 +60,26 @@
 #  define pipe_dumpbuffer(m,a,n)
 #endif
 
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: pipecommon_bufferused
+ ****************************************************************************/
+
+static pipe_ndx_t pipecommon_bufferused(FAR struct pipe_dev_s *dev)
+{
+  if (dev->d_wrndx >= dev->d_rdndx)
+    {
+      return dev->d_wrndx - dev->d_rdndx;
+    }
+  else
+    {
+      return dev->d_bufsize + dev->d_wrndx - dev->d_rdndx;
+    }
+}
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -417,9 +437,14 @@ ssize_t pipecommon_read(FAR struct file *filep, FAR char *buffer, size_t len)
       nread++;
     }
 
-  /* Notify all poll/select waiters that they can write to the FIFO */
+  /* Notify all poll/select waiters that they can write to the
+   * FIFO when buffer can accept more than d_polloutthrd bytes.
+   */
 
-  poll_notify(dev->d_fds, CONFIG_DEV_PIPE_NPOLLWAITERS, POLLOUT);
+  if (pipecommon_bufferused(dev) < (dev->d_bufsize - dev->d_polloutthrd))
+    {
+      poll_notify(dev->d_fds, CONFIG_DEV_PIPE_NPOLLWAITERS, POLLOUT);
+    }
 
   /* Notify all waiting writers that bytes have been removed from the
    * buffer.
@@ -527,10 +552,14 @@ ssize_t pipecommon_write(FAR struct file *filep, FAR const char *buffer,
           if ((size_t)nwritten >= len)
             {
               /* Notify all poll/select waiters that they can read from the
-               * FIFO.
+               * FIFO when buffer used exceeds poll threshold.
                */
 
-              poll_notify(dev->d_fds, CONFIG_DEV_PIPE_NPOLLWAITERS, POLLIN);
+              if (pipecommon_bufferused(dev) > dev->d_pollinthrd)
+                {
+                  poll_notify(dev->d_fds, CONFIG_DEV_PIPE_NPOLLWAITERS,
+                              POLLIN);
+                }
 
               /* Yes.. Notify all of the waiting readers that more data is
                * available.
@@ -661,28 +690,23 @@ int pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds,
        * First, determine how many bytes are in the buffer
        */
 
-      if (dev->d_wrndx >= dev->d_rdndx)
-        {
-          nbytes = dev->d_wrndx - dev->d_rdndx;
-        }
-      else
-        {
-          nbytes = dev->d_bufsize + dev->d_wrndx - dev->d_rdndx;
-        }
+      nbytes = pipecommon_bufferused(dev);
 
-      /* Notify the POLLOUT event if the pipe is not full, but only if
+      /* Notify the POLLOUT event if the pipe buffer can accept
+       * more than d_polloutthrd bytes, but only if
        * there is readers.
        */
 
       eventset = 0;
-      if ((filep->f_oflags & O_WROK) && (nbytes < (dev->d_bufsize - 1)))
+      if ((filep->f_oflags & O_WROK) &&
+          nbytes < (dev->d_bufsize - dev->d_polloutthrd))
         {
           eventset |= POLLOUT;
         }
 
-      /* Notify the POLLIN event if the pipe is not empty */
+      /* Notify the POLLIN event if buffer used exceeds poll threshold */
 
-      if ((filep->f_oflags & O_RDOK) && (nbytes > 0))
+      if ((filep->f_oflags & O_RDOK) && (nbytes > dev->d_pollinthrd))
         {
           eventset |= POLLIN;
         }
@@ -772,6 +796,34 @@ int pipecommon_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
         }
         break;
 
+      case PIPEIOC_POLLINTHRD:
+        {
+          pipe_ndx_t threshold = (pipe_ndx_t)arg;
+          if (threshold >= dev->d_bufsize)
+            {
+              ret = -EINVAL;
+              break;
+            }
+
+          dev->d_pollinthrd = threshold;
+          ret = OK;
+        }
+        break;
+
+      case PIPEIOC_POLLOUTTHRD:
+        {
+          pipe_ndx_t threshold = (pipe_ndx_t)arg;
+          if (threshold >= dev->d_bufsize)
+            {
+              ret = -EINVAL;
+              break;
+            }
+
+          dev->d_polloutthrd = threshold;
+          ret = OK;
+        }
+        break;
+
       case FIONWRITE:  /* Number of bytes waiting in send queue */
       case FIONREAD:   /* Number of bytes available for reading */
         {
diff --git a/drivers/pipes/pipe_common.h b/drivers/pipes/pipe_common.h
index ff579e81f6..eec1bac119 100644
--- a/drivers/pipes/pipe_common.h
+++ b/drivers/pipes/pipe_common.h
@@ -120,6 +120,8 @@ struct pipe_dev_s
   pipe_ndx_t d_wrndx;       /* Index in d_buffer to save next byte written */
   pipe_ndx_t d_rdndx;       /* Index in d_buffer to return the next byte read */
   pipe_ndx_t d_bufsize;     /* allocated size of d_buffer in bytes */
+  pipe_ndx_t d_pollinthrd;  /* Buffer threshold for POLLIN to occur */
+  pipe_ndx_t d_polloutthrd; /* Buffer threshold for POLLOUT to occur */
   uint8_t    d_nwriters;    /* Number of reference counts for write access */
   uint8_t    d_nreaders;    /* Number of reference counts for read access */
   uint8_t    d_flags;       /* See PIPE_FLAG_* definitions */
diff --git a/include/nuttx/fs/ioctl.h b/include/nuttx/fs/ioctl.h
index a231e85f82..12e52900ac 100644
--- a/include/nuttx/fs/ioctl.h
+++ b/include/nuttx/fs/ioctl.h
@@ -405,15 +405,33 @@
 
 /* FIFOs and pipe driver ioctl definitions **********************************/
 
-#define _PIPEIOCVALID(c)  (_IOC_TYPE(c)==_PIPEBASE)
-#define _PIPEIOC(nr)      _IOC(_PIPEBASE,nr)
-
-#define PIPEIOC_POLICY    _PIPEIOC(0x0001)  /* Set buffer policy
-                                             * IN: unsigned long integer
-                                             *     0=free on last close
-                                             *       (default)
-                                             *     1=fre when empty
-                                             * OUT: None */
+#define _PIPEIOCVALID(c)    (_IOC_TYPE(c)==_PIPEBASE)
+#define _PIPEIOC(nr)        _IOC(_PIPEBASE,nr)
+
+#define PIPEIOC_POLICY      _PIPEIOC(0x0001)  /* Set buffer policy
+                                               * IN: unsigned long integer
+                                               *     0=free on last close
+                                               *       (default)
+                                               *     1=fre when empty
+                                               * OUT: None */
+
+#define PIPEIOC_POLLINTHRD  _PIPEIOC(0x0002)  /* Set pipe POLLIN
+                                               * notifty buffer threshold.
+                                               * IN: unsigned long integer.
+                                               *     POLLIN only occurs when
+                                               *     buffer contains more
+                                               *     bytes than the
+                                               *     threshold.
+                                               * OUT: None */
+
+#define PIPEIOC_POLLOUTTHRD _PIPEIOC(0x0003)  /* Set pipe POLLOUT
+                                               * notifty buffer threshold.
+                                               * IN: unsigned long integer.
+                                               *     POLLOUT only occurs
+                                               *     when buffer can accept
+                                               *     more bytes than
+                                               *     threshold.
+                                               * OUT: None */
 
 /* RTC driver ioctl definitions *********************************************/