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 <gilles.chanteperd...@xenomai.org> 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 <nucleus/core.h> #endif /* CONFIG_XENO_OPT_PERVASIVE */ +#include <nucleus/select.h> #include <asm/xenomai/bits/init.h> 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 <linux/types.h> #include <linux/bitops.h> /* 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 = link2binding(holder, slink); + fd = binding->fd; + removeq(&fd->bindings, &binding->link); + xnlock_put_irqrestore(&nklock, s); + + xnfree(binding); + + xnlock_get_irqsave(&nklock, s); + } + resched = + xnsynch_destroy(&selector->synchbase) == XNSYNCH_RESCHED; xnlock_put_irqrestore(&nklock, s); - xnfree(binding); + xnfree(selector); + if (resched) + xnpod_schedule(); xnlock_get_irqsave(&nklock, s); } xnlock_put_irqrestore(&nklock, s); +} + +int xnselect_mount(void) +{ + initq(&xnselectors); + xnselect_apc = rthal_apc_alloc("xnselectors_destroy", + xnselector_destroy_loop, NULL); + if (xnselect_apc < 0) + return xnselect_apc; - if (xnsynch_destroy(&selector->synchbase) == XNSYNCH_RESCHED) - xnpod_schedule(); + return 0; +} + +int xnselect_umount(void) +{ + return rthal_apc_free(xnselect_apc); } -EXPORT_SYMBOL(xnselector_destroy); /*...@}*/ _______________________________________________ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git