Module: xenomai-3
Branch: master
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(&current->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

Reply via email to