You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2020/07/29 17:54:45 UTC

[GitHub] [incubator-nuttx] spiriou commented on a change in pull request #1479: fs/vfs: Add file descriptor based events support

spiriou commented on a change in pull request #1479:
URL: https://github.com/apache/incubator-nuttx/pull/1479#discussion_r462463770



##########
File path: fs/vfs/fs_eventfd.c
##########
@@ -0,0 +1,639 @@
+/****************************************************************************
+ * vfs/fs_eventfd.c
+ *
+ *   Copyright (C) 2020 Gregory Nutt. All rights reserved.
+ *   Author: Simon Piriou <sp...@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/

Review comment:
       done

##########
File path: fs/vfs/fs_eventfd.c
##########
@@ -0,0 +1,639 @@
+/****************************************************************************
+ * vfs/fs_eventfd.c
+ *
+ *   Copyright (C) 2020 Gregory Nutt. All rights reserved.
+ *   Author: Simon Piriou <sp...@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <stdio.h>
+#include <string.h>
+#include <poll.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <debug.h>
+
+#include <sys/ioctl.h>
+#include <sys/eventfd.h>
+
+#include "inode/inode.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define EVENTFD_FMT    "/dev/efd%d"
+
+#ifndef CONFIG_EVENT_FD_NPOLLWAITERS
+/* Maximum number of threads than can be waiting for POLL events */
+#  define CONFIG_EVENT_FD_NPOLLWAITERS 2
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* This structure describes the internal state of the driver */
+
+struct eventfd_priv_s
+{
+  sem_t     exclsem;        /* Enforces exclusive access to device counter */
+  sem_t     rdsem;          /* Empty buffer - Reader waits for data write */
+  sem_t     wrsem;          /* Full buffer - Writer waits for data read */
+  uint8_t   crefs;          /* References counts on eventfd (limited to 255) */
+  uint8_t   minor;          /* eventfd minor number */
+  uint8_t   mode_semaphore; /* eventfd mode (semaphore or counter) */
+  eventfd_t counter;        /* eventfd counter */
+
+  /* The following is a list if poll structures of threads waiting for
+   * driver events. The 'struct pollfd' reference for each open is also
+   * retained in the f_priv field of the 'struct file'.
+   */
+
+#ifdef CONFIG_EVENT_FD_POLL
+  struct pollfd *d_fds[CONFIG_EVENT_FD_NPOLLWAITERS];
+#endif
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int eventfd_open(FAR struct file *filep);
+static int eventfd_close(FAR struct file *filep);
+
+static ssize_t eventfd_do_read(FAR struct file *filep, FAR char *buffer,
+                               size_t len);
+static ssize_t eventfd_do_write(FAR struct file *filep,
+                                FAR const char *buffer, size_t len);
+static int eventfd_do_ioctl(FAR struct file *filep, int cmd,
+                            unsigned long arg);
+#ifdef CONFIG_EVENT_FD_POLL
+static int eventfd_poll(FAR struct file *filep, FAR struct pollfd *fds,
+                       bool setup);
+#endif
+
+static int eventfd_alloc_dev(eventfd_t counter, int flags);
+
+#ifdef CONFIG_EVENT_FD_POLL
+static void eventfd_pollnotify(FAR struct eventfd_priv_s *dev,
+                               pollevent_t eventset);
+#endif
+
+static int get_unique_minor(void);
+static void release_minor(int minor);
+
+static FAR struct eventfd_priv_s *eventfd_allocdev(void);
+static void eventfd_destroy(FAR struct eventfd_priv_s *dev);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct file_operations g_eventfd_fops =
+{
+  eventfd_open,     /* open */
+  eventfd_close,    /* close */
+  eventfd_do_read,  /* read */
+  eventfd_do_write, /* write */
+  0,                /* seek */
+  eventfd_do_ioctl  /* ioctl */
+#ifdef CONFIG_EVENT_FD_POLL
+  , eventfd_poll    /* poll */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+FAR struct eventfd_priv_s *eventfd_allocdev(void)
+{
+  FAR struct eventfd_priv_s *dev;
+
+  dev = (FAR struct eventfd_priv_s *)
+    kmm_malloc(sizeof(struct eventfd_priv_s));
+  if (dev)
+    {
+      /* Initialize the private structure */
+
+      memset(dev, 0, sizeof(struct eventfd_priv_s));
+      nxsem_init(&dev->exclsem, 0, 0);
+      nxsem_init(&dev->rdsem, 0, 0);
+      nxsem_init(&dev->wrsem, 0, 0);
+
+      /* The read/write wait semaphores are used for signaling
+       * and should not have priority inheritance enabled.
+       */
+
+      nxsem_set_protocol(&dev->rdsem, SEM_PRIO_NONE);
+      nxsem_set_protocol(&dev->wrsem, SEM_PRIO_NONE);
+    }
+
+  return dev;
+}
+
+void eventfd_destroy(FAR struct eventfd_priv_s *dev)
+{
+  nxsem_destroy(&dev->exclsem);
+  nxsem_destroy(&dev->rdsem);
+  nxsem_destroy(&dev->wrsem);
+  kmm_free(dev);
+}
+
+#ifdef CONFIG_EVENT_FD_POLL
+void eventfd_pollnotify(FAR struct eventfd_priv_s *dev,
+                               pollevent_t eventset)
+{
+  FAR struct pollfd *fds;
+  int i;
+
+  for (i = 0; i < CONFIG_EVENT_FD_NPOLLWAITERS; i++)
+    {
+      fds = dev->d_fds[i];
+      if (fds)
+        {
+          fds->revents |= eventset & fds->events;
+
+          if (fds->revents != 0)
+            {
+              nxsem_post(fds->sem);
+            }
+        }
+    }
+}
+#endif
+
+int get_unique_minor(void)
+{
+  static int minor = 0;
+
+  /* TODO reimplement this with minor bit map ? */
+
+  return (minor++) & 511;
+}
+
+void release_minor(int minor)
+{
+}
+
+int eventfd_open(FAR struct file *filep)
+{
+  FAR struct inode *inode = filep->f_inode;
+  FAR struct eventfd_priv_s *priv = inode->i_private;
+  int ret;
+
+  /* Get exclusive access to the device structures */
+
+  ret = nxsem_wait(&priv->exclsem);
+  if (ret < 0)
+    {
+      return -1;
+    }
+
+  finfo("crefs: %d <%s>\n", priv->crefs, inode->i_name);
+
+  if (priv->crefs >= 255)
+    {
+      /* More than 255 opens; uint8_t would overflow to zero */
+
+      ret = -EMFILE;
+    }
+  else
+    {
+      /* Save the new open count on success */
+
+      priv->crefs += 1;
+      ret = OK;
+    }
+
+  nxsem_post(&priv->exclsem);
+  return ret;
+}
+
+int eventfd_close(FAR struct file *filep)
+{
+  FAR struct inode *inode = filep->f_inode;
+  FAR struct eventfd_priv_s *priv = inode->i_private;
+  FAR char *devpath;
+  int ret;
+
+  /* Get exclusive access to the device structures */
+
+  ret = nxsem_wait(&priv->exclsem);
+  if (ret < 0)
+    {
+      return -errno;
+    }
+
+  finfo("crefs: %d <%s>\n", priv->crefs, inode->i_name);
+
+  /* Decrement the references to the driver.  If the reference count will
+   * decrement to 0, then uninitialize the driver.
+   */
+
+  if (priv->crefs > 1)
+    {
+      /* Just decrement the reference count and release the semaphore */
+
+      priv->crefs -= 1;
+      nxsem_post(&priv->exclsem);
+      return OK;
+    }
+
+  /* Re-create the path to the driver. */
+
+  finfo("destroy\n");
+  ret = asprintf(&devpath, EVENTFD_FMT, priv->minor);
+  if (ret < 0)
+    {
+      _err("ERROR: Failed to allocate the driver path\n");
+      nxsem_post(&priv->exclsem);
+      return -ENOMEM;
+    }
+
+  /* Will be unregistered later after close is done */
+
+  unregister_driver(devpath);
+
+  free(devpath);

Review comment:
       done

##########
File path: include/sys/eventfd.h
##########
@@ -0,0 +1,85 @@
+/****************************************************************************
+ * include/sys/eventfd.h
+ *
+ *   Copyright (C) 2020 Gregory Nutt. All rights reserved.
+ *   Author: Simon Piriou <sp...@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_SYS_EVENTFD_H
+#define __INCLUDE_SYS_EVENTFD_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <fcntl.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define EFD_NONBLOCK  O_NONBLOCK
+#define EFD_SEMAPHORE O_BINARY
+
+/****************************************************************************
+ * Public Type Declarations
+ ****************************************************************************/
+
+/* Type for event counter */
+
+typedef uint64_t eventfd_t;

Review comment:
       Let's use uint32_t for now as eventfd is not standard anyway.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org