Module: xenomai-forge
Branch: master
Commit: 6410988c1ea883daaaa011ba021f295f564d9b40
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=6410988c1ea883daaaa011ba021f295f564d9b40

Author: Philippe Gerum <r...@xenomai.org>
Date:   Sun Aug  4 16:28:53 2013 +0200

cobalt/posix/select: move implementation to dedicated file

---

 kernel/cobalt/posix/Makefile  |    1 +
 kernel/cobalt/posix/select.c  |  212 +++++++++++++++++++++++++++++++++++++++++
 kernel/cobalt/posix/select.h  |   31 ++++++
 kernel/cobalt/posix/syscall.c |  192 +------------------------------------
 4 files changed, 246 insertions(+), 190 deletions(-)

diff --git a/kernel/cobalt/posix/Makefile b/kernel/cobalt/posix/Makefile
index 070bb90..d08442d 100644
--- a/kernel/cobalt/posix/Makefile
+++ b/kernel/cobalt/posix/Makefile
@@ -12,6 +12,7 @@ posix-y :=            \
        mutex_attr.o    \
        registry.o      \
        sem.o           \
+       select.o        \
        signal.o        \
        syscall.o       \
        thread.o        \
diff --git a/kernel/cobalt/posix/select.c b/kernel/cobalt/posix/select.c
new file mode 100644
index 0000000..ff94f98
--- /dev/null
+++ b/kernel/cobalt/posix/select.c
@@ -0,0 +1,212 @@
+/**
+ * @file
+ * This file is part of the Xenomai project.
+ *
+ * Copyright (C) 2005 Philippe Gerum <r...@xenomai.org>
+ * Copyright (C) 2005 Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/types.h>
+#include <linux/err.h>
+#include <rtdm/rtdm_driver.h>
+#include "internal.h"
+#include "clock.h"
+#include "mqueue.h"
+#include "select.h"
+
+#define RTDM_FD_MAX CONFIG_XENO_OPT_RTDM_FILDES
+
+static int fd_valid_p(int fd)
+{
+       const int rtdm_fd_start = __FD_SETSIZE - RTDM_FD_MAX;
+       struct rtdm_dev_context *ctx;
+       struct cobalt_process *cc;
+
+       if (fd >= rtdm_fd_start) {
+               ctx = rtdm_context_get(fd - rtdm_fd_start);
+               if (ctx == NULL)
+                       return 0;
+               rtdm_context_unlock(ctx);
+               return 1;
+       }
+
+       cc = cobalt_process_context();
+       if (cc == NULL)
+               return 0;
+
+       return cobalt_assoc_lookup(&cc->uqds, fd) != NULL;
+}
+
+static int first_fd_valid_p(fd_set *fds[XNSELECT_MAX_TYPES], int nfds)
+{
+       int i, fd;
+
+       for (i = 0; i < XNSELECT_MAX_TYPES; i++)
+               if (fds[i]
+                   && (fd = find_first_bit(fds[i]->fds_bits, nfds)) < nfds)
+                       return fd_valid_p(fd);
+
+       /* All empty is correct, used as a "sleep" mechanism by strange
+          applications. */
+       return 1;
+}
+
+static int select_bind_one(struct xnselector *selector, unsigned type, int fd)
+{
+       const int rtdm_fd_start = __FD_SETSIZE - RTDM_FD_MAX;
+       struct cobalt_process *cc;
+       cobalt_assoc_t *assoc;
+
+       if (fd >= rtdm_fd_start)
+               return rtdm_select_bind(fd - rtdm_fd_start,
+                                       selector, type, fd);
+
+       cc = cobalt_process_context();
+       if (cc == NULL)
+               return -EPERM;
+
+       assoc = cobalt_assoc_lookup(&cc->uqds, fd);
+       if (assoc == NULL)
+               return -EBADF;
+
+       return cobalt_mq_select_bind(assoc2ufd(assoc)->kfd, selector, type, fd);
+}
+
+static int select_bind_all(struct xnselector *selector,
+                          fd_set *fds[XNSELECT_MAX_TYPES], int nfds)
+{
+       unsigned fd, type;
+       int err;
+
+       for (type = 0; type < XNSELECT_MAX_TYPES; type++) {
+               fd_set *set = fds[type];
+               if (set)
+                       for (fd = find_first_bit(set->fds_bits, nfds);
+                            fd < nfds;
+                            fd = find_next_bit(set->fds_bits, nfds, fd + 1)) {
+                               err = select_bind_one(selector, type, fd);
+                               if (err)
+                                       return err;
+                       }
+       }
+
+       return 0;
+}
+
+/* int select(int, fd_set *, fd_set *, fd_set *, struct timeval *) */
+int cobalt_select(int nfds,
+                 fd_set __user *u_rfds,
+                 fd_set __user *u_wfds,
+                 fd_set __user *u_xfds,
+                 struct timeval __user *u_tv)
+{
+       fd_set __user *ufd_sets[XNSELECT_MAX_TYPES] = {
+               [XNSELECT_READ] = u_rfds,
+               [XNSELECT_WRITE] = u_wfds,
+               [XNSELECT_EXCEPT] = u_xfds
+       };
+       fd_set *in_fds[XNSELECT_MAX_TYPES] = {NULL, NULL, NULL};
+       fd_set *out_fds[XNSELECT_MAX_TYPES] = {NULL, NULL, NULL};
+       fd_set in_fds_storage[XNSELECT_MAX_TYPES],
+               out_fds_storage[XNSELECT_MAX_TYPES];
+       xnticks_t timeout = XN_INFINITE;
+       xntmode_t mode = XN_RELATIVE;
+       struct xnselector *selector;
+       struct timeval tv;
+       xnthread_t *thread;
+       size_t fds_size;
+       int i, err;
+
+       thread = xnsched_current_thread();
+       if (!thread)
+               return -EPERM;
+
+       if (u_tv) {
+               if (!access_wok(u_tv, sizeof(tv))
+                   || __xn_copy_from_user(&tv, u_tv, sizeof(tv)))
+                       return -EFAULT;
+
+               if (tv.tv_usec > 1000000)
+                       return -EINVAL;
+
+               timeout = clock_get_ticks(CLOCK_MONOTONIC) + tv2ns(&tv);
+               mode = XN_ABSOLUTE;
+       }
+
+       fds_size = __FDELT__(nfds + __NFDBITS__ - 1) * sizeof(long);
+
+       for (i = 0; i < XNSELECT_MAX_TYPES; i++)
+               if (ufd_sets[i]) {
+                       in_fds[i] = &in_fds_storage[i];
+                       out_fds[i] = & out_fds_storage[i];
+                       if (!access_wok((void __user *) ufd_sets[i],
+                                       sizeof(fd_set))
+                           || __xn_copy_from_user(in_fds[i],
+                                                  (void __user *) ufd_sets[i],
+                                                  fds_size))
+                               return -EFAULT;
+               }
+
+       selector = thread->selector;
+       if (!selector) {
+               /* This function may be called from pure Linux fd_sets, we want
+                  to avoid the xnselector allocation in this case, so, we do a
+                  simple test: test if the first file descriptor we find in the
+                  fd_set is an RTDM descriptor or a message queue descriptor. 
*/
+               if (!first_fd_valid_p(in_fds, nfds))
+                       return -EBADF;
+
+               selector = xnmalloc(sizeof(*thread->selector));
+               if (selector == NULL)
+                       return -ENOMEM;
+               xnselector_init(selector);
+               thread->selector = selector;
+
+               /* Bind directly the file descriptors, we do not need to go
+                  through xnselect returning -ECHRNG */
+               if ((err = select_bind_all(selector, in_fds, nfds)))
+                       return err;
+       }
+
+       do {
+               err = xnselect(selector, out_fds, in_fds, nfds, timeout, mode);
+
+               if (err == -ECHRNG) {
+                       int err = select_bind_all(selector, out_fds, nfds);
+                       if (err)
+                               return err;
+               }
+       } while (err == -ECHRNG);
+
+       if (u_tv && (err > 0 || err == -EINTR)) {
+               xnsticks_t diff = timeout - clock_get_ticks(CLOCK_MONOTONIC);
+               if (diff > 0)
+                       ticks2tv(&tv, diff);
+               else
+                       tv.tv_sec = tv.tv_usec = 0;
+
+               if (__xn_copy_to_user(u_tv, &tv, sizeof(tv)))
+                       return -EFAULT;
+       }
+
+       if (err >= 0)
+               for (i = 0; i < XNSELECT_MAX_TYPES; i++)
+                       if (ufd_sets[i]
+                           && __xn_copy_to_user((void __user *) ufd_sets[i],
+                                                out_fds[i], sizeof(fd_set)))
+                               return -EFAULT;
+       return err;
+}
diff --git a/kernel/cobalt/posix/select.h b/kernel/cobalt/posix/select.h
new file mode 100644
index 0000000..0131ba9
--- /dev/null
+++ b/kernel/cobalt/posix/select.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2013 Philippe Gerum <r...@xenomai.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _COBALT_POSIX_SELECT_H
+#define _COBALT_POSIX_SELECT_H
+
+#include <linux/types.h>
+#include <linux/time.h>
+
+int cobalt_select(int nfds,
+                 fd_set __user *u_rfds,
+                 fd_set __user *u_wfds,
+                 fd_set __user *u_xfds,
+                 struct timeval __user *u_tv);
+
+#endif /* !_COBALT_POSIX_SELECT_H */
diff --git a/kernel/cobalt/posix/syscall.c b/kernel/cobalt/posix/syscall.c
index 5b96f9c..7123dee 100644
--- a/kernel/cobalt/posix/syscall.c
+++ b/kernel/cobalt/posix/syscall.c
@@ -37,198 +37,10 @@
 #include "monitor.h"
 #include "clock.h"
 #include "event.h"
-
-#define RTDM_FD_MAX CONFIG_XENO_OPT_RTDM_FILDES
+#include "select.h"
 
 int cobalt_muxid;
 
-static int fd_valid_p(int fd)
-{
-       const int rtdm_fd_start = __FD_SETSIZE - RTDM_FD_MAX;
-       struct rtdm_dev_context *ctx;
-       struct cobalt_process *cc;
-
-       if (fd >= rtdm_fd_start) {
-               ctx = rtdm_context_get(fd - rtdm_fd_start);
-               if (ctx == NULL)
-                       return 0;
-               rtdm_context_unlock(ctx);
-               return 1;
-       }
-
-       cc = cobalt_process_context();
-       if (cc == NULL)
-               return 0;
-
-       return cobalt_assoc_lookup(&cc->uqds, fd) != NULL;
-}
-
-static int first_fd_valid_p(fd_set *fds[XNSELECT_MAX_TYPES], int nfds)
-{
-       int i, fd;
-
-       for (i = 0; i < XNSELECT_MAX_TYPES; i++)
-               if (fds[i]
-                   && (fd = find_first_bit(fds[i]->fds_bits, nfds)) < nfds)
-                       return fd_valid_p(fd);
-
-       /* All empty is correct, used as a "sleep" mechanism by strange
-          applications. */
-       return 1;
-}
-
-static int select_bind_one(struct xnselector *selector, unsigned type, int fd)
-{
-       const int rtdm_fd_start = __FD_SETSIZE - RTDM_FD_MAX;
-       struct cobalt_process *cc;
-       cobalt_assoc_t *assoc;
-
-       if (fd >= rtdm_fd_start)
-               return rtdm_select_bind(fd - rtdm_fd_start,
-                                       selector, type, fd);
-
-       cc = cobalt_process_context();
-       if (cc == NULL)
-               return -EPERM;
-
-       assoc = cobalt_assoc_lookup(&cc->uqds, fd);
-       if (assoc == NULL)
-               return -EBADF;
-
-       return cobalt_mq_select_bind(assoc2ufd(assoc)->kfd, selector, type, fd);
-}
-
-static int select_bind_all(struct xnselector *selector,
-                          fd_set *fds[XNSELECT_MAX_TYPES], int nfds)
-{
-       unsigned fd, type;
-       int err;
-
-       for (type = 0; type < XNSELECT_MAX_TYPES; type++) {
-               fd_set *set = fds[type];
-               if (set)
-                       for (fd = find_first_bit(set->fds_bits, nfds);
-                            fd < nfds;
-                            fd = find_next_bit(set->fds_bits, nfds, fd + 1)) {
-                               err = select_bind_one(selector, type, fd);
-                               if (err)
-                                       return err;
-                       }
-       }
-
-       return 0;
-}
-
-/* int select(int, fd_set *, fd_set *, fd_set *, struct timeval *) */
-static int __select(int nfds,
-                   fd_set __user *u_rfds,
-                   fd_set __user *u_wfds,
-                   fd_set __user *u_xfds,
-                   struct timeval __user *u_tv)
-{
-       fd_set __user *ufd_sets[XNSELECT_MAX_TYPES] = {
-               [XNSELECT_READ] = u_rfds,
-               [XNSELECT_WRITE] = u_wfds,
-               [XNSELECT_EXCEPT] = u_xfds
-       };
-       fd_set *in_fds[XNSELECT_MAX_TYPES] = {NULL, NULL, NULL};
-       fd_set *out_fds[XNSELECT_MAX_TYPES] = {NULL, NULL, NULL};
-       fd_set in_fds_storage[XNSELECT_MAX_TYPES],
-               out_fds_storage[XNSELECT_MAX_TYPES];
-       xnticks_t timeout = XN_INFINITE;
-       xntmode_t mode = XN_RELATIVE;
-       struct xnselector *selector;
-       struct timeval tv;
-       xnthread_t *thread;
-       size_t fds_size;
-       int i, err;
-
-       thread = xnsched_current_thread();
-       if (!thread)
-               return -EPERM;
-
-       if (u_tv) {
-               if (!access_wok(u_tv, sizeof(tv))
-                   || __xn_copy_from_user(&tv, u_tv, sizeof(tv)))
-                       return -EFAULT;
-
-               if (tv.tv_usec > 1000000)
-                       return -EINVAL;
-
-               timeout = clock_get_ticks(CLOCK_MONOTONIC) + tv2ns(&tv);
-               mode = XN_ABSOLUTE;
-       }
-
-       fds_size = __FDELT__(nfds + __NFDBITS__ - 1) * sizeof(long);
-
-       for (i = 0; i < XNSELECT_MAX_TYPES; i++)
-               if (ufd_sets[i]) {
-                       in_fds[i] = &in_fds_storage[i];
-                       out_fds[i] = & out_fds_storage[i];
-                       if (!access_wok((void __user *) ufd_sets[i],
-                                       sizeof(fd_set))
-                           || __xn_copy_from_user(in_fds[i],
-                                                  (void __user *) ufd_sets[i],
-                                                  fds_size))
-                               return -EFAULT;
-               }
-
-       selector = thread->selector;
-       if (!selector) {
-               /* This function may be called from pure Linux fd_sets, we want
-                  to avoid the xnselector allocation in this case, so, we do a
-                  simple test: test if the first file descriptor we find in the
-                  fd_set is an RTDM descriptor or a message queue descriptor. 
*/
-               if (!first_fd_valid_p(in_fds, nfds))
-                       return -EBADF;
-
-               selector = xnmalloc(sizeof(*thread->selector));
-               if (selector == NULL)
-                       return -ENOMEM;
-               xnselector_init(selector);
-               thread->selector = selector;
-
-               /* Bind directly the file descriptors, we do not need to go
-                  through xnselect returning -ECHRNG */
-               if ((err = select_bind_all(selector, in_fds, nfds)))
-                       return err;
-       }
-
-       do {
-               err = xnselect(selector, out_fds, in_fds, nfds, timeout, mode);
-
-               if (err == -ECHRNG) {
-                       int err = select_bind_all(selector, out_fds, nfds);
-                       if (err)
-                               return err;
-               }
-       } while (err == -ECHRNG);
-
-       if (u_tv && (err > 0 || err == -EINTR)) {
-               xnsticks_t diff = timeout - clock_get_ticks(CLOCK_MONOTONIC);
-               if (diff > 0)
-                       ticks2tv(&tv, diff);
-               else
-                       tv.tv_sec = tv.tv_usec = 0;
-
-               if (__xn_copy_to_user(u_tv, &tv, sizeof(tv)))
-                       return -EFAULT;
-       }
-
-       if (err >= 0)
-               for (i = 0; i < XNSELECT_MAX_TYPES; i++)
-                       if (ufd_sets[i]
-                           && __xn_copy_to_user((void __user *) ufd_sets[i],
-                                                out_fds[i], sizeof(fd_set)))
-                               return -EFAULT;
-       return err;
-}
-
-int __cobalt_call_not_available(void)
-{
-       return -ENOSYS;
-}
-
 static struct xnshadow_ppd *cobalt_process_attach(void)
 {
        struct cobalt_process *cc;
@@ -340,7 +152,7 @@ static struct xnsyscall cobalt_syscalls[] = {
        SKINCALL_DEF(sc_cobalt_condattr_setclock, cobalt_condattr_setclock, 
any),
        SKINCALL_DEF(sc_cobalt_condattr_getpshared, cobalt_condattr_getpshared, 
any),
        SKINCALL_DEF(sc_cobalt_condattr_setpshared, cobalt_condattr_setpshared, 
any),
-       SKINCALL_DEF(sc_cobalt_select, __select, primary),
+       SKINCALL_DEF(sc_cobalt_select, cobalt_select, primary),
        SKINCALL_DEF(sc_cobalt_sched_minprio, cobalt_sched_min_prio, any),
        SKINCALL_DEF(sc_cobalt_sched_maxprio, cobalt_sched_max_prio, any),
        SKINCALL_DEF(sc_cobalt_monitor_init, cobalt_monitor_init, any),


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to