[Xenomai-git] Gilles Chanteperdrix : nucleus: defer selector block deletion to an APC.

2009-12-05 Thread GIT version control
Module: xenomai-2.4
Branch: master
Commit: 3d4e22a501b33979f3be98d6ed2e3947f2361567
URL:
http://git.xenomai.org/?p=xenomai-2.4.git;a=commit;h=3d4e22a501b33979f3be98d6ed2e3947f2361567

Author: Gilles Chanteperdrix 
Date:   Thu Nov  5 23:49:43 2009 +0100

nucleus: defer selector block deletion to an APC.

Avoid creating reschedulings in the middle of xnpod_delete_thread.

---

 include/nucleus/select.h |5 +++
 ksrc/nucleus/module.c|   19 +++--
 ksrc/nucleus/pod.c   |4 ---
 ksrc/nucleus/select.c|   64 ++
 4 files changed, 74 insertions(+), 18 deletions(-)

diff --git a/include/nucleus/select.h b/include/nucleus/select.h
index b098b63..20eefbe 100644
--- a/include/nucleus/select.h
+++ b/include/nucleus/select.h
@@ -41,6 +41,7 @@ struct xnselector {
fd_set expected;
fd_set pending;
} fds [XNSELECT_MAX_TYPES];
+   xnholder_t destroy_link;
xnqueue_t bindings; /* only used by xnselector_destroy */
 };
 
@@ -106,6 +107,10 @@ int xnselect(struct xnselector *selector,
 
 void xnselector_destroy(struct xnselector *selector);
 
+int xnselect_mount(void);
+
+int xnselect_umount(void);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/ksrc/nucleus/module.c b/ksrc/nucleus/module.c
index bc3bc59..cde32f9 100644
--- a/ksrc/nucleus/module.c
+++ b/ksrc/nucleus/module.c
@@ -34,6 +34,7 @@
 #ifdef CONFIG_XENO_OPT_PERVASIVE
 #include 
 #endif /* CONFIG_XENO_OPT_PERVASIVE */
+#include 
 #include 
 
 MODULE_DESCRIPTION("Xenomai nucleus");
@@ -1171,11 +1172,18 @@ int __init __xeno_sys_init(void)
goto cleanup_arch;
 #endif /* CONFIG_XENO_OPT_PIPE */
 
+#ifdef CONFIG_XENO_OPT_SELECT
+   err = xnselect_mount();
+
+   if (err)
+   goto cleanup_pipe;
+#endif /* CONFIG_XENO_OPT_SELECT */
+
 #ifdef CONFIG_XENO_OPT_PERVASIVE
err = xnshadow_mount();
 
if (err)
-   goto cleanup_pipe;
+   goto cleanup_select;
 
err = xnheap_mount();
 
@@ -1201,10 +1209,15 @@ int __init __xeno_sys_init(void)
 
xnshadow_cleanup();
 
-  cleanup_pipe:
-
+  cleanup_select:
 #endif /* CONFIG_XENO_OPT_PERVASIVE */
 
+#ifdef CONFIG_XENO_OPT_SELECT
+   xnselect_umount();
+   
+  cleanup_pipe:
+#endif /* CONFIG_XENO_OPT_SELECT */
+
 #ifdef CONFIG_XENO_OPT_PIPE
xnpipe_umount();
 
diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c
index bee6a04..386f86a 100644
--- a/ksrc/nucleus/pod.c
+++ b/ksrc/nucleus/pod.c
@@ -1208,8 +1208,6 @@ void xnpod_delete_thread(xnthread_t *thread)
 #ifdef CONFIG_XENO_OPT_SELECT
if (thread->selector) {
xnselector_destroy(thread->selector);
-   xnheap_schedule_free(&kheap, thread->selector, 
-(xnholder_t *)thread->selector);
thread->selector = NULL;
}
 #endif /* CONFIG_XENO_OPT_SELECT */
@@ -1293,8 +1291,6 @@ void xnpod_abort_thread(xnthread_t *thread)
if (!xnpod_current_p(thread))
xnpod_suspend_thread(thread, XNDORMANT, XN_INFINITE, 
XN_RELATIVE, NULL);
xnpod_delete_thread(thread);
-   /* FIXME: in case thread has a selector, the xnfree(selector)
-  happens with nklock locked. */
xnlock_put_irqrestore(&nklock, s);
 }
 
diff --git a/ksrc/nucleus/select.c b/ksrc/nucleus/select.c
index 502e7f6..d63503f 100644
--- a/ksrc/nucleus/select.c
+++ b/ksrc/nucleus/select.c
@@ -53,6 +53,9 @@
 #include 
 #include   /* For hweight_long */
 
+static xnqueue_t xnselectors;
+static int xnselect_apc;
+
 #define link2binding(baddr, memb)  \
container_of(baddr, struct xnselect_binding, memb)
 
@@ -388,28 +391,67 @@ EXPORT_SYMBOL(xnselect);
  */
 void xnselector_destroy(struct xnselector *selector)
 {
-   xnholder_t *holder;
spl_t s;
 
+   inith(&selector->destroy_link);
xnlock_get_irqsave(&nklock, s);
-   while ((holder = getq(&selector->bindings))) {
-   struct xnselect_binding *binding;
-   struct xnselect *fd;
+   appendq(&xnselectors, &selector->destroy_link);
+   xnlock_put_irqrestore(&nklock, s);
+
+   rthal_apc_schedule(xnselect_apc);
+}
+EXPORT_SYMBOL_GPL(xnselector_destroy);
+
+static void xnselector_destroy_loop(void *cookie)
+{
+   struct xnselector *selector;
+   xnholder_t *holder;
+   int resched;
+   spl_t s;
 
-   binding = link2binding(holder, slink);
-   fd = binding->fd;
-   removeq(&fd->bindings, &binding->link);
+   xnlock_get_irqsave(&nklock, s);
+   while ((holder = getq(&xnselectors))) {
+   selector = container_of(holder, struct xnselector, 
destroy_link);
+   while ((holder = getq(&selector->bindings))) {
+   struct xnselect_binding *binding;
+   struct xnselect *fd;
+
+   binding = link2bindi

[Xenomai-git] Gilles Chanteperdrix : nucleus: defer selector block deletion to an APC.

2009-12-04 Thread GIT version control
Module: xenomai-gch
Branch: for-2.4
Commit: 3d4e22a501b33979f3be98d6ed2e3947f2361567
URL:
http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=3d4e22a501b33979f3be98d6ed2e3947f2361567

Author: Gilles Chanteperdrix 
Date:   Thu Nov  5 23:49:43 2009 +0100

nucleus: defer selector block deletion to an APC.

Avoid creating reschedulings in the middle of xnpod_delete_thread.

---

 include/nucleus/select.h |5 +++
 ksrc/nucleus/module.c|   19 +++--
 ksrc/nucleus/pod.c   |4 ---
 ksrc/nucleus/select.c|   64 ++
 4 files changed, 74 insertions(+), 18 deletions(-)

diff --git a/include/nucleus/select.h b/include/nucleus/select.h
index b098b63..20eefbe 100644
--- a/include/nucleus/select.h
+++ b/include/nucleus/select.h
@@ -41,6 +41,7 @@ struct xnselector {
fd_set expected;
fd_set pending;
} fds [XNSELECT_MAX_TYPES];
+   xnholder_t destroy_link;
xnqueue_t bindings; /* only used by xnselector_destroy */
 };
 
@@ -106,6 +107,10 @@ int xnselect(struct xnselector *selector,
 
 void xnselector_destroy(struct xnselector *selector);
 
+int xnselect_mount(void);
+
+int xnselect_umount(void);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/ksrc/nucleus/module.c b/ksrc/nucleus/module.c
index bc3bc59..cde32f9 100644
--- a/ksrc/nucleus/module.c
+++ b/ksrc/nucleus/module.c
@@ -34,6 +34,7 @@
 #ifdef CONFIG_XENO_OPT_PERVASIVE
 #include 
 #endif /* CONFIG_XENO_OPT_PERVASIVE */
+#include 
 #include 
 
 MODULE_DESCRIPTION("Xenomai nucleus");
@@ -1171,11 +1172,18 @@ int __init __xeno_sys_init(void)
goto cleanup_arch;
 #endif /* CONFIG_XENO_OPT_PIPE */
 
+#ifdef CONFIG_XENO_OPT_SELECT
+   err = xnselect_mount();
+
+   if (err)
+   goto cleanup_pipe;
+#endif /* CONFIG_XENO_OPT_SELECT */
+
 #ifdef CONFIG_XENO_OPT_PERVASIVE
err = xnshadow_mount();
 
if (err)
-   goto cleanup_pipe;
+   goto cleanup_select;
 
err = xnheap_mount();
 
@@ -1201,10 +1209,15 @@ int __init __xeno_sys_init(void)
 
xnshadow_cleanup();
 
-  cleanup_pipe:
-
+  cleanup_select:
 #endif /* CONFIG_XENO_OPT_PERVASIVE */
 
+#ifdef CONFIG_XENO_OPT_SELECT
+   xnselect_umount();
+   
+  cleanup_pipe:
+#endif /* CONFIG_XENO_OPT_SELECT */
+
 #ifdef CONFIG_XENO_OPT_PIPE
xnpipe_umount();
 
diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c
index bee6a04..386f86a 100644
--- a/ksrc/nucleus/pod.c
+++ b/ksrc/nucleus/pod.c
@@ -1208,8 +1208,6 @@ void xnpod_delete_thread(xnthread_t *thread)
 #ifdef CONFIG_XENO_OPT_SELECT
if (thread->selector) {
xnselector_destroy(thread->selector);
-   xnheap_schedule_free(&kheap, thread->selector, 
-(xnholder_t *)thread->selector);
thread->selector = NULL;
}
 #endif /* CONFIG_XENO_OPT_SELECT */
@@ -1293,8 +1291,6 @@ void xnpod_abort_thread(xnthread_t *thread)
if (!xnpod_current_p(thread))
xnpod_suspend_thread(thread, XNDORMANT, XN_INFINITE, 
XN_RELATIVE, NULL);
xnpod_delete_thread(thread);
-   /* FIXME: in case thread has a selector, the xnfree(selector)
-  happens with nklock locked. */
xnlock_put_irqrestore(&nklock, s);
 }
 
diff --git a/ksrc/nucleus/select.c b/ksrc/nucleus/select.c
index 502e7f6..d63503f 100644
--- a/ksrc/nucleus/select.c
+++ b/ksrc/nucleus/select.c
@@ -53,6 +53,9 @@
 #include 
 #include   /* For hweight_long */
 
+static xnqueue_t xnselectors;
+static int xnselect_apc;
+
 #define link2binding(baddr, memb)  \
container_of(baddr, struct xnselect_binding, memb)
 
@@ -388,28 +391,67 @@ EXPORT_SYMBOL(xnselect);
  */
 void xnselector_destroy(struct xnselector *selector)
 {
-   xnholder_t *holder;
spl_t s;
 
+   inith(&selector->destroy_link);
xnlock_get_irqsave(&nklock, s);
-   while ((holder = getq(&selector->bindings))) {
-   struct xnselect_binding *binding;
-   struct xnselect *fd;
+   appendq(&xnselectors, &selector->destroy_link);
+   xnlock_put_irqrestore(&nklock, s);
+
+   rthal_apc_schedule(xnselect_apc);
+}
+EXPORT_SYMBOL_GPL(xnselector_destroy);
+
+static void xnselector_destroy_loop(void *cookie)
+{
+   struct xnselector *selector;
+   xnholder_t *holder;
+   int resched;
+   spl_t s;
 
-   binding = link2binding(holder, slink);
-   fd = binding->fd;
-   removeq(&fd->bindings, &binding->link);
+   xnlock_get_irqsave(&nklock, s);
+   while ((holder = getq(&xnselectors))) {
+   selector = container_of(holder, struct xnselector, 
destroy_link);
+   while ((holder = getq(&selector->bindings))) {
+   struct xnselect_binding *binding;
+   struct xnselect *fd;
+
+   binding = link2bind

[Xenomai-git] Gilles Chanteperdrix : nucleus: defer selector block deletion to an APC.

2009-11-05 Thread GIT version control
Module: xenomai-gch
Branch: for-head
Commit: 36247dec656766b6eebb481462c5019097892e05
URL:
http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=36247dec656766b6eebb481462c5019097892e05

Author: Gilles Chanteperdrix 
Date:   Thu Nov  5 23:49:43 2009 +0100

nucleus: defer selector block deletion to an APC.

Avoid creating reschedulings in the middle of xnpod_delete_thread.

---

 include/nucleus/select.h |5 +++
 ksrc/nucleus/module.c|   18 ++--
 ksrc/nucleus/pod.c   |4 --
 ksrc/nucleus/select.c|   69 -
 4 files changed, 75 insertions(+), 21 deletions(-)

diff --git a/include/nucleus/select.h b/include/nucleus/select.h
index b098b63..20eefbe 100644
--- a/include/nucleus/select.h
+++ b/include/nucleus/select.h
@@ -41,6 +41,7 @@ struct xnselector {
fd_set expected;
fd_set pending;
} fds [XNSELECT_MAX_TYPES];
+   xnholder_t destroy_link;
xnqueue_t bindings; /* only used by xnselector_destroy */
 };
 
@@ -106,6 +107,10 @@ int xnselect(struct xnselector *selector,
 
 void xnselector_destroy(struct xnselector *selector);
 
+int xnselect_mount(void);
+
+int xnselect_umount(void);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/ksrc/nucleus/module.c b/ksrc/nucleus/module.c
index 141276a..620ee9b 100644
--- a/ksrc/nucleus/module.c
+++ b/ksrc/nucleus/module.c
@@ -33,6 +33,7 @@
 #ifdef CONFIG_XENO_OPT_PIPE
 #include 
 #endif /* CONFIG_XENO_OPT_PIPE */
+#include 
 #include 
 
 MODULE_DESCRIPTION("Xenomai nucleus");
@@ -115,10 +116,16 @@ int __init __xeno_sys_init(void)
goto cleanup_proc;
 #endif /* CONFIG_XENO_OPT_PIPE */
 
+#ifdef CONFIG_XENO_OPT_SELECT
+   ret = xnselect_mount();
+   if (ret)
+   goto cleanup_pipe;
+#endif /* CONFIG_XENO_OPT_SELECT */
+
 #ifdef CONFIG_XENO_OPT_PERVASIVE
ret = xnshadow_mount();
if (ret)
-   goto cleanup_pipe;
+   goto cleanup_select;
 
ret = xnheap_mount();
if (ret)
@@ -151,10 +158,15 @@ int __init __xeno_sys_init(void)
 
xnshadow_cleanup();
 
-  cleanup_pipe:
-
+  cleanup_select:
 #endif /* CONFIG_XENO_OPT_PERVASIVE */
 
+#ifdef CONFIG_XENO_OPT_SELECT
+   xnselect_umount();
+   
+  cleanup_pipe:
+#endif CONFIG_XENO_OPT_SELECT
+
 #ifdef CONFIG_XENO_OPT_PIPE
xnpipe_umount();
 
diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c
index 77c69fd..7daf0f7 100644
--- a/ksrc/nucleus/pod.c
+++ b/ksrc/nucleus/pod.c
@@ -1190,8 +1190,6 @@ void xnpod_delete_thread(xnthread_t *thread)
 #ifdef CONFIG_XENO_OPT_SELECT
if (thread->selector) {
xnselector_destroy(thread->selector);
-   xnheap_schedule_free(&kheap, thread->selector, 
-(xnholder_t *)thread->selector);
thread->selector = NULL;
}
 #endif /* CONFIG_XENO_OPT_SELECT */
@@ -1284,8 +1282,6 @@ void xnpod_abort_thread(xnthread_t *thread)
 XN_INFINITE, XN_RELATIVE, NULL);
xnthread_set_info(thread, XNABORT);
xnpod_delete_thread(thread);
-   /* FIXME: in case thread has a selector, the xnfree(selector)
-  happens with nklock locked. */
xnlock_put_irqrestore(&nklock, s);
 }
 EXPORT_SYMBOL_GPL(xnpod_abort_thread);
diff --git a/ksrc/nucleus/select.c b/ksrc/nucleus/select.c
index 10355bf..fd56bfb 100644
--- a/ksrc/nucleus/select.c
+++ b/ksrc/nucleus/select.c
@@ -53,6 +53,9 @@
 #include 
 #include   /* For hweight_long */
 
+static xnqueue_t xnselectors;
+static int xnselect_apc;
+
 #define link2binding(baddr, memb)  \
container_of(baddr, struct xnselect_binding, memb)
 
@@ -388,29 +391,67 @@ EXPORT_SYMBOL_GPL(xnselect);
  */
 void xnselector_destroy(struct xnselector *selector)
 {
-   xnholder_t *holder;
spl_t s;
 
+   inith(&selector->destroy_link);
xnlock_get_irqsave(&nklock, s);
-   while ((holder = getq(&selector->bindings))) {
-   struct xnselect_binding *binding;
-   struct xnselect *fd;
-   spl_t dummy;
+   appendq(&xnselectors, &selector->destroy_link);
+   xnlock_put_irqrestore(&nklock, s);
 
-   binding = link2binding(holder, slink);
-   fd = binding->fd;
-   removeq(&fd->bindings, &binding->link);
-   xnlock_clear_irqon(&nklock);
+   rthal_apc_schedule(xnselect_apc);
+}
+EXPORT_SYMBOL_GPL(xnselector_destroy);
 
-   xnfree(binding);
+static void xnselector_destroy_loop(void *cookie)
+{
+   struct xnselector *selector;
+   xnholder_t *holder;
+   int resched;
+   spl_t s;
 
-   xnlock_get_irqsave(&nklock, dummy);
+   xnlock_get_irqsave(&nklock, s);
+   while ((holder = getq(&xnselectors))) {
+   selector = container_of(holder, struct xnselector, 
destroy_link);
+   while ((holder = ge