Module: xenomai-3 Branch: next Commit: 81958c620029485f3533b72f42b31ffb05eae234 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=81958c620029485f3533b72f42b31ffb05eae234
Author: Philippe Gerum <r...@xenomai.org> Date: Thu Jul 16 21:24:33 2015 +0200 cobalt/thread, copperplate: fetch per-thread user window from the global heap The shared multi-processing mode requires user windows to be accessible from threads living in remote processes for signaling monitors. Therefore, the kernel memory this window is allocated from must belong to the global heap, instead of the per-process, private heap. --- include/cobalt/kernel/thread.h | 6 +++++- include/copperplate/threadobj.h | 24 +++++++++++++++++++++++- kernel/cobalt/posix/process.c | 10 +++++----- lib/cobalt/current.c | 4 ++-- lib/copperplate/syncobj.c | 3 ++- lib/copperplate/threadobj.c | 25 +++++++++++++++++++++++-- 6 files changed, 60 insertions(+), 12 deletions(-) diff --git a/include/cobalt/kernel/thread.h b/include/cobalt/kernel/thread.h index 1ba0c1b..2a06fd2 100644 --- a/include/cobalt/kernel/thread.h +++ b/include/cobalt/kernel/thread.h @@ -176,7 +176,11 @@ struct xnthread { void (*entry)(void *cookie); /* Thread entry routine */ void *cookie; /* Cookie to pass to the entry routine */ - struct xnthread_user_window *u_window; /* Data visible from userland. */ + /** + * Thread data visible from userland through a window on the + * global heap. + */ + struct xnthread_user_window *u_window; struct xnthread_personality *personality; diff --git a/include/copperplate/threadobj.h b/include/copperplate/threadobj.h index aa2c201..2ec0289 100644 --- a/include/copperplate/threadobj.h +++ b/include/copperplate/threadobj.h @@ -39,7 +39,14 @@ struct xnthread_user_window; struct threadobj_corespec { xnhandle_t handle; - struct xnthread_user_window *u_window; + union { + struct { + __u32 u_winoff; + } shrd; + struct { + struct xnthread_user_window *u_window; + } priv; + }; }; struct threadobj_stat { @@ -75,6 +82,21 @@ void threadobj_save_timeout(struct threadobj_corespec *corespec, */ } +#ifdef CONFIG_XENO_PSHARED + +struct xnthread_user_window * +threadobj_get_window(struct threadobj_corespec *corespec); + +#else /* !CONFIG_XENO_PSHARED */ + +static inline struct xnthread_user_window * +threadobj_get_window(struct threadobj_corespec *corespec) +{ + return corespec->priv.u_window; +} + +#endif /* !CONFIG_XENO_PSHARED */ + #else /* CONFIG_XENO_MERCURY */ #include <sys/time.h> diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c index 828e9e5..1d2309d 100644 --- a/kernel/cobalt/posix/process.c +++ b/kernel/cobalt/posix/process.c @@ -614,7 +614,7 @@ static inline int disable_ondemand_memory(void) * initialized by a call to xnthread_init(). * * @param u_winoff will receive the offset of the per-thread - * "u_window" structure in the process shared heap associated to @a + * "u_window" structure in the global heap associated to @a * thread. This structure reflects thread state information visible * from userland through a shared memory window. * @@ -649,8 +649,7 @@ int cobalt_map_user(struct xnthread *thread, __u32 __user *u_winoff) if (ret) return ret; - sys_ppd = cobalt_ppd_get(0); - umm = &sys_ppd->umm; + umm = &cobalt_kernel_ppd.umm; u_window = cobalt_umm_alloc(umm, sizeof(*u_window)); if (u_window == NULL) return -ENOMEM; @@ -672,6 +671,7 @@ int cobalt_map_user(struct xnthread *thread, __u32 __user *u_winoff) init_uthread_info(thread); xnthread_set_state(thread, XNMAPPED); xndebug_shadow_init(thread); + sys_ppd = cobalt_ppd_get(0); atomic_inc(&sys_ppd->refcnt); /* * ->map_thread() handler is invoked after the TCB is fully @@ -1030,9 +1030,9 @@ static int handle_taskexit_event(struct task_struct *p) /* p == current */ xnsched_run(); if (xnthread_test_state(thread, XNUSER)) { - sys_ppd = cobalt_ppd_get(0); - cobalt_umm_free(&sys_ppd->umm, thread->u_window); + cobalt_umm_free(&cobalt_kernel_ppd.umm, thread->u_window); thread->u_window = NULL; + sys_ppd = cobalt_ppd_get(0); if (atomic_dec_and_test(&sys_ppd->refcnt)) remove_process(cobalt_current_process()); } diff --git a/lib/cobalt/current.c b/lib/cobalt/current.c index 06888b0..a085456 100644 --- a/lib/cobalt/current.c +++ b/lib/cobalt/current.c @@ -39,7 +39,7 @@ static inline void __cobalt_set_tsd(xnhandle_t current, __u32 u_winoff) struct xnthread_user_window *window; cobalt_current = current; - window = cobalt_umm_private + u_winoff; + window = cobalt_umm_shared + u_winoff; cobalt_current_window = window; cobalt_commit_memory(cobalt_current_window); } @@ -67,7 +67,7 @@ static inline void __cobalt_set_tsd(xnhandle_t current, current = (current != XN_NO_HANDLE ? current : (xnhandle_t)0); pthread_setspecific(cobalt_current_key, (void *)(uintptr_t)current); - window = cobalt_umm_private + u_winoff; + window = cobalt_umm_shared + u_winoff; pthread_setspecific(cobalt_current_window_key, window); cobalt_commit_memory(window); } diff --git a/lib/copperplate/syncobj.c b/lib/copperplate/syncobj.c index 4716d46..1b3d545 100644 --- a/lib/copperplate/syncobj.c +++ b/lib/copperplate/syncobj.c @@ -97,7 +97,8 @@ int monitor_wait_drain(struct syncobj *sobj, static inline void monitor_grant(struct syncobj *sobj, struct threadobj *thobj) { - cobalt_monitor_grant(&sobj->core.monitor, thobj->core.u_window); + cobalt_monitor_grant(&sobj->core.monitor, + threadobj_get_window(&thobj->core)); } static inline diff --git a/lib/copperplate/threadobj.c b/lib/copperplate/threadobj.c index 88bb59e..335c9f8 100644 --- a/lib/copperplate/threadobj.c +++ b/lib/copperplate/threadobj.c @@ -248,14 +248,35 @@ static inline void threadobj_uninit_corespec(struct threadobj *thobj) { } +#ifdef CONFIG_XENO_PSHARED + static inline int threadobj_setup_corespec(struct threadobj *thobj) { thobj->core.handle = cobalt_get_current(); - thobj->core.u_window = cobalt_get_current_window(); + thobj->core.shrd.u_winoff = (void *)cobalt_get_current_window() - + cobalt_umm_shared; return 0; } +struct xnthread_user_window * +threadobj_get_window(struct threadobj_corespec *corespec) +{ + return cobalt_umm_shared + corespec->shrd.u_winoff; +} + +#else /* !CONFIG_XENO_PSHARED */ + +static inline int threadobj_setup_corespec(struct threadobj *thobj) +{ + thobj->core.handle = cobalt_get_current(); + thobj->core.priv.u_window = cobalt_get_current_window(); + + return 0; +} + +#endif /* !CONFIG_XENO_PSHARED */ + static inline void threadobj_cleanup_corespec(struct threadobj *thobj) { } @@ -335,7 +356,7 @@ int threadobj_resume(struct threadobj *thobj) /* thobj->lock held */ static inline int threadobj_unblocked_corespec(struct threadobj *current) { - return (current->core.u_window->info & XNBREAK) != 0; + return (threadobj_get_window(¤t->core)->info & XNBREAK) != 0; } int __threadobj_lock_sched(struct threadobj *current) _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git