Module: xenomai-gch
Branch: u_mode
Commit: 95e5b6d403feacae87ae313dc2e102d51bb767c4
URL:    
http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=95e5b6d403feacae87ae313dc2e102d51bb767c4

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Sat Jun 18 19:05:51 2011 +0200

nucleus: allocate u_mode in process private heap

---

 include/asm-generic/bits/current.h |   23 +++++----
 include/asm-generic/syscall.h      |    3 +-
 include/nucleus/shadow.h           |    2 +-
 include/nucleus/thread.h           |    2 +-
 include/nucleus/vdso.h             |    7 +--
 ksrc/nucleus/shadow.c              |   74 ++++++++++-------------------
 ksrc/skins/native/syscall.c        |    2 +-
 ksrc/skins/posix/syscall.c         |   20 ++++----
 ksrc/skins/psos+/syscall.c         |    2 +-
 ksrc/skins/uitron/syscall.c        |    7 ++-
 ksrc/skins/vrtx/syscall.c          |    2 +-
 ksrc/skins/vxworks/syscall.c       |    2 +-
 src/skins/common/current.c         |   92 +++++++-----------------------------
 src/skins/common/sem_heap.c        |    2 -
 src/skins/native/task.c            |   13 ++---
 src/skins/posix/thread.c           |   62 ++++++------------------
 src/skins/psos+/task.c             |   11 +++-
 src/skins/uitron/task.c            |   11 +---
 src/skins/vrtx/task.c              |    4 +-
 src/skins/vxworks/taskLib.c        |    4 +-
 20 files changed, 117 insertions(+), 228 deletions(-)

diff --git a/include/asm-generic/bits/current.h 
b/include/asm-generic/bits/current.h
index 79123e8..0574c55 100644
--- a/include/asm-generic/bits/current.h
+++ b/include/asm-generic/bits/current.h
@@ -11,9 +11,10 @@ unsigned long xeno_slow_get_current_mode(void);
 void xeno_current_warn_old(void);
 
 #ifdef HAVE___THREAD
-extern __thread xnhandle_t xeno_current __attribute__ ((tls_model 
("initial-exec")));
-extern __thread unsigned long
-xeno_current_mode __attribute__ ((tls_model ("initial-exec")));
+extern __thread __attribute__ ((tls_model ("initial-exec")))
+xnhandle_t xeno_current;
+extern __thread __attribute__ ((tls_model ("initial-exec")))
+unsigned long *xeno_current_mode;
 
 static inline xnhandle_t xeno_get_current(void)
 {
@@ -24,9 +25,7 @@ static inline xnhandle_t xeno_get_current(void)
 
 static inline unsigned long xeno_get_current_mode(void)
 {
-       unsigned long mode = xeno_current_mode;
-
-       return mode == -1 ? xeno_slow_get_current_mode() : mode;
+       return *xeno_current_mode;
 }
 
 #else /* ! HAVE___THREAD */
@@ -53,17 +52,19 @@ static inline xnhandle_t xeno_get_current_fast(void)
 
 static inline unsigned long xeno_get_current_mode(void)
 {
-       unsigned long *mode = pthread_getspecific(xeno_current_mode_key);
+       unsigned long *mode;
+
+       mode = pthread_getspecific(xeno_current_mode_key);
 
-       return mode ? (*mode) : xeno_slow_get_current_mode();
+       return *mode;
 }
 
 #endif /* ! HAVE___THREAD */
 
-void xeno_set_current(void);
+void xeno_init_current_keys(void);
 
-unsigned long *xeno_init_current_mode(void);
+void xeno_set_current(void);
 
-void xeno_init_current_keys(void);
+void xeno_set_current_mode(unsigned long offset);
 
 #endif /* _XENO_ASM_GENERIC_CURRENT_H */
diff --git a/include/asm-generic/syscall.h b/include/asm-generic/syscall.h
index 89d148e..4154b46 100644
--- a/include/asm-generic/syscall.h
+++ b/include/asm-generic/syscall.h
@@ -35,8 +35,7 @@
 #define __xn_sys_sem_heap      7
 #define __xn_sys_current       8       /* threadh = xnthread_handle(cur) */
 #define __xn_sys_current_info  9       /* r = xnshadow_current_info(&info) */
-#define __xn_sys_drop_u_mode   10      /* stop updating thread->u_mode */
-#define __xn_sys_mayday        11      /* request mayday fixup */
+#define __xn_sys_mayday        10      /* request mayday fixup */
 
 #define XENOMAI_LINUX_DOMAIN  0
 #define XENOMAI_XENO_DOMAIN   1
diff --git a/include/nucleus/shadow.h b/include/nucleus/shadow.h
index ad93058..9c8784c 100644
--- a/include/nucleus/shadow.h
+++ b/include/nucleus/shadow.h
@@ -63,7 +63,7 @@ void xnshadow_release_events(void);
 
 int xnshadow_map(struct xnthread *thread,
                 xncompletion_t __user *u_completion,
-                unsigned long __user *u_mode);
+                unsigned long __user *u_mode_offset);
 
 void xnshadow_unmap(struct xnthread *thread);
 
diff --git a/include/nucleus/thread.h b/include/nucleus/thread.h
index 853a305..d5dc531 100644
--- a/include/nucleus/thread.h
+++ b/include/nucleus/thread.h
@@ -329,7 +329,7 @@ typedef struct xnthread {
        void *cookie;           /* Cookie to pass to the entry routine */
 
 #ifdef CONFIG_XENO_OPT_PERVASIVE
-       unsigned long __user *u_mode;   /* Thread mode variable in userland. */
+       unsigned long *u_mode;  /* Thread mode variable shared with userland. */
 #endif /* CONFIG_XENO_OPT_PERVASIVE */
 
     XNARCH_DECL_DISPLAY_CONTEXT();
diff --git a/include/nucleus/vdso.h b/include/nucleus/vdso.h
index 279574b..42d2263 100644
--- a/include/nucleus/vdso.h
+++ b/include/nucleus/vdso.h
@@ -51,12 +51,11 @@ struct xnvdso {
 #define XNVDSO_FEAT_C  0x0000000000000004ULL
 #define XNVDSO_FEATURES        (XNVDSO_FEAT_A | XNVDSO_FEAT_B | XVDSO_FEAT_C)
 */
-#define XNVDSO_FEAT_DROP_U_MODE 0x0000000000000001ULL
-#define XNVDSO_FEAT_HOST_REALTIME      0x0000000000000002ULL
+#define XNVDSO_FEAT_HOST_REALTIME      0x0000000000000001ULL
 #ifdef CONFIG_XENO_OPT_HOSTRT
-#define XNVDSO_FEATURES (XNVDSO_FEAT_DROP_U_MODE | XNVDSO_FEAT_HOST_REALTIME)
+#define XNVDSO_FEATURES XNVDSO_FEAT_HOST_REALTIME
 #else
-#define XNVDSO_FEATURES XNVDSO_FEAT_DROP_U_MODE
+#define XNVDSO_FEATURES 0
 #endif /* CONFIG_XENO_OPT_HOSTRT */
 
 extern struct xnvdso *nkvdso;
diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c
index e5dd421..dcda1e7 100644
--- a/ksrc/nucleus/shadow.c
+++ b/ksrc/nucleus/shadow.c
@@ -956,7 +956,7 @@ redo:
                return -ERESTARTSYS;
 
        if (thread->u_mode)
-               __xn_put_user(thread->state & ~XNRELAX, thread->u_mode);
+               *(thread->u_mode) = thread->state & ~XNRELAX;
 
        preempt_disable();
 
@@ -1154,7 +1154,7 @@ void xnshadow_relax(int notify, int reason)
           root thread. */
 
        if (thread->u_mode)
-               __xn_put_user(thread->state, thread->u_mode);
+               *(thread->u_mode) = thread->state;
 
        trace_mark(xn_nucleus, shadow_relaxed,
                  "thread %p thread_name %s comm %s",
@@ -1173,7 +1173,7 @@ void xnshadow_exit(void)
 /*!
  * \fn int xnshadow_map(xnthread_t *thread,
  *                      xncompletion_t __user *u_completion,
- *                      unsigned long __user *u_mode)
+ *                      unsigned long __user *u_mode_offset)
  * @internal
  * \brief Create a shadow thread context.
  *
@@ -1197,10 +1197,12 @@ void xnshadow_exit(void)
  * immediately started and "current" immediately resumes in the Xenomai
  * domain from this service.
  *
- * @param: u_mode is the address of a mode variable in user space that
- * will reflect the current thread mode (primary or secondary). The
- * nucleus will try to update the variable before switching to secondary
- * or after switching from primary mode.
+ * @param: u_mode_offset is the address of a user space address where
+ * we will store the offset of the "u_mode" thread variable in the
+ * process shared heap. This thread variable reflects the current
+ * thread mode (primary or secondary). The nucleus will try to update
+ * the variable before switching to secondary  or after switching from
+ * primary mode.
  *
  * @return 0 is returned on success. Otherwise:
  *
@@ -1231,11 +1233,13 @@ void xnshadow_exit(void)
  */
 
 int xnshadow_map(xnthread_t *thread, xncompletion_t __user *u_completion,
-                unsigned long __user *u_mode)
+                unsigned long __user *u_mode_offset)
 {
        struct xnthread_start_attr attr;
        xnarch_cpumask_t affinity;
        unsigned int muxid, magic;
+       unsigned long *u_mode;
+       xnheap_t *sem_heap;
        int ret;
 
        if (!xnthread_test_state(thread, XNSHADOW))
@@ -1244,7 +1248,7 @@ int xnshadow_map(xnthread_t *thread, xncompletion_t 
__user *u_completion,
        if (xnshadow_thread(current) || xnthread_test_state(thread, XNMAPPED))
                return -EBUSY;
 
-       if (!access_wok(u_mode, sizeof(*u_mode)))
+       if (!access_wok(u_mode_offset, sizeof(*u_mode_offset)))
                return -EFAULT;
 
 #ifdef CONFIG_MMU
@@ -1274,6 +1278,11 @@ int xnshadow_map(xnthread_t *thread, xncompletion_t 
__user *u_completion,
                }
        }
 
+       sem_heap = &xnsys_ppd_get(0)->sem_heap;
+       u_mode = xnheap_alloc(sem_heap, sizeof(*u_mode));
+       if (!u_mode)
+               return -ENOMEM;
+
        /* Restrict affinity to a single CPU of nkaffinity & current set. */
        xnarch_cpus_and(affinity, current->cpus_allowed, nkaffinity);
        affinity = xnarch_cpumask_of_cpu(xnarch_first_cpu(affinity));
@@ -1286,7 +1295,10 @@ int xnshadow_map(xnthread_t *thread, xncompletion_t 
__user *u_completion,
 
        xnarch_init_shadow_tcb(xnthread_archtcb(thread), thread,
                               xnthread_name(thread));
+
        thread->u_mode = u_mode;
+       __xn_put_user(xnheap_mapped_offset(sem_heap, u_mode), u_mode_offset);
+
        xnthread_set_state(thread, XNMAPPED);
        xnpod_suspend_thread(thread, XNRELAX, XN_INFINITE, XN_RELATIVE, NULL);
 
@@ -1340,7 +1352,7 @@ int xnshadow_map(xnthread_t *thread, xncompletion_t 
__user *u_completion,
                return ret;
 
        if (thread->u_mode)
-               __xn_put_user(thread->state, u_mode);
+               *(thread->u_mode) = thread->state;
 
        ret = xnshadow_harden();
 
@@ -1384,6 +1396,9 @@ void xnshadow_unmap(xnthread_t *thread)
 
        xnshadow_thrptd(p) = NULL;
 
+       xnheap_free(&xnsys_ppd_get(0)->sem_heap, thread->u_mode);
+       thread->u_mode = NULL;
+
        schedule_linux_call(LO_UNMAP_REQ, p, xnthread_get_magic(thread));
 }
 EXPORT_SYMBOL_GPL(xnshadow_unmap);
@@ -2050,18 +2065,6 @@ static int xnshadow_sys_current_info(struct pt_regs 
*regs)
        return __xn_safe_copy_to_user(us_info, &info, sizeof(*us_info));
 }
 
-static int xnshadow_sys_drop_u_mode(struct pt_regs *regs)
-{
-       xnthread_t *cur = xnshadow_thread(current);
-
-       if (!cur)
-               return -EPERM;
-
-       cur->u_mode = NULL;
-
-       return 0;
-}
-
 static xnsysent_t __systab[] = {
        [__xn_sys_migrate] = {&xnshadow_sys_migrate, __xn_exec_current},
        [__xn_sys_arch] = {&xnshadow_sys_arch, __xn_exec_any},
@@ -2074,8 +2077,6 @@ static xnsysent_t __systab[] = {
        [__xn_sys_current] = {&xnshadow_sys_current, __xn_exec_any},
        [__xn_sys_current_info] =
                {&xnshadow_sys_current_info, __xn_exec_shadow},
-       [__xn_sys_drop_u_mode] =
-               {&xnshadow_sys_drop_u_mode, __xn_exec_shadow},
        [__xn_sys_mayday] = {&xnshadow_sys_mayday, 
__xn_exec_any|__xn_exec_norestart},
 };
 
@@ -2143,34 +2144,9 @@ static struct xnskin_props __props = {
        .module = NULL
 };
 
-static void handle_shadow_exit(void)
-{
-       xnthread_t *thread = xnshadow_thread(current);
-       static int warned;
-
-       /*
-        * If user space did not deregister u_mode at this point, we
-        * are confronted with old libraries and should warn about
-        * potential instabilities.
-        */
-       if (thread->u_mode && !warned) {
-               warned = 1;
-#ifdef CONFIG_MMU
-               printk(KERN_WARNING
-                      "Xenomai: User-space support anterior to 2.5.2"
-                      " detected, may corrupt memory upon\n"
-                      "thread termination. Upgrade is recommended\n");
-#endif
-       }
-       thread->u_mode = NULL;
-}
-
 static inline int
 substitute_linux_syscall(struct pt_regs *regs)
 {
-       if (unlikely(__xn_linux_mux_p(regs, __NR_exit)))
-               handle_shadow_exit();
-
        /* No real-time replacement for now -- let Linux handle this call. */
        return 0;
 }
diff --git a/ksrc/skins/native/syscall.c b/ksrc/skins/native/syscall.c
index 4b29e2e..17071da 100644
--- a/ksrc/skins/native/syscall.c
+++ b/ksrc/skins/native/syscall.c
@@ -126,7 +126,7 @@ static RT_TASK *__rt_task_current(struct task_struct *p)
  * a3: int prio;
  * a4: int mode;
  * a5: pthread_t opaque;
- * a6: thread mode writeback area;
+ * a6: thread mode offset writeback area;
  * }
  */
 
diff --git a/ksrc/skins/posix/syscall.c b/ksrc/skins/posix/syscall.c
index 3c7f7ee..b8c5628 100644
--- a/ksrc/skins/posix/syscall.c
+++ b/ksrc/skins/posix/syscall.c
@@ -197,7 +197,7 @@ static int __pthread_create(struct pt_regs *regs)
 
 static pthread_t __pthread_shadow(struct task_struct *p,
                                  struct pse51_hkey *hkey,
-                                 unsigned long __user *u_mode)
+                                 unsigned long __user *u_mode_offset)
 {
        pthread_attr_t attr;
        pthread_t k_tid;
@@ -212,7 +212,7 @@ static pthread_t __pthread_shadow(struct task_struct *p,
        if (err)
                return ERR_PTR(-err);
 
-       err = xnshadow_map(&k_tid->threadbase, NULL, u_mode);
+       err = xnshadow_map(&k_tid->threadbase, NULL, u_mode_offset);
 
        if (!err && !__pthread_hash(hkey, k_tid))
                err = -EAGAIN;
@@ -228,13 +228,13 @@ static pthread_t __pthread_shadow(struct task_struct *p,
 static int __pthread_setschedparam(struct pt_regs *regs)
 {
        int policy, err, promoted = 0;
-       unsigned long __user *u_mode;
+       unsigned long __user *u_mode_offset;
        struct sched_param param;
        struct pse51_hkey hkey;
        pthread_t k_tid;
 
        policy = __xn_reg_arg2(regs);
-       u_mode = (unsigned long __user *)__xn_reg_arg4(regs);
+       u_mode_offset = (unsigned long __user *)__xn_reg_arg4(regs);
 
        if (__xn_safe_copy_from_user(&param,
                                     (void __user *)__xn_reg_arg3(regs), 
sizeof(param)))
@@ -244,10 +244,10 @@ static int __pthread_setschedparam(struct pt_regs *regs)
        hkey.mm = current->mm;
        k_tid = __pthread_find(&hkey);
 
-       if (!k_tid && u_mode) {
+       if (!k_tid && u_mode_offset) {
                /* If the syscall applies to "current", and the latter is not
                   a Xenomai thread already, then shadow it. */
-               k_tid = __pthread_shadow(current, &hkey, u_mode);
+               k_tid = __pthread_shadow(current, &hkey, u_mode_offset);
                if (IS_ERR(k_tid))
                        return PTR_ERR(k_tid);
 
@@ -271,13 +271,13 @@ static int __pthread_setschedparam(struct pt_regs *regs)
 static int __pthread_setschedparam_ex(struct pt_regs *regs)
 {
        int policy, err, promoted = 0;
-       unsigned long __user *u_mode;
+       unsigned long __user *u_mode_offset;
        struct sched_param_ex param;
        struct pse51_hkey hkey;
        pthread_t k_tid;
 
        policy = __xn_reg_arg2(regs);
-       u_mode = (unsigned long __user *)__xn_reg_arg4(regs);
+       u_mode_offset = (unsigned long __user *)__xn_reg_arg4(regs);
 
        if (__xn_safe_copy_from_user(&param,
                                     (void __user *)__xn_reg_arg3(regs), 
sizeof(param)))
@@ -287,8 +287,8 @@ static int __pthread_setschedparam_ex(struct pt_regs *regs)
        hkey.mm = current->mm;
        k_tid = __pthread_find(&hkey);
 
-       if (!k_tid && u_mode) {
-               k_tid = __pthread_shadow(current, &hkey, u_mode);
+       if (!k_tid && u_mode_offset) {
+               k_tid = __pthread_shadow(current, &hkey, u_mode_offset);
                if (IS_ERR(k_tid))
                        return PTR_ERR(k_tid);
 
diff --git a/ksrc/skins/psos+/syscall.c b/ksrc/skins/psos+/syscall.c
index 3f03b5e..496ee2b 100644
--- a/ksrc/skins/psos+/syscall.c
+++ b/ksrc/skins/psos+/syscall.c
@@ -67,7 +67,7 @@ static psostask_t *__psos_task_current(struct task_struct *p)
  * a1: const char *name;
  * a2: u_long prio;
  * a3: u_long flags;
- * a4: unsigned long *mode;
+ * a4: unsigned long *mode_offset;
  * a5: unsigned long ptid;
  */
 
diff --git a/ksrc/skins/uitron/syscall.c b/ksrc/skins/uitron/syscall.c
index 3bf9581..0d7a6ee 100644
--- a/ksrc/skins/uitron/syscall.c
+++ b/ksrc/skins/uitron/syscall.c
@@ -39,7 +39,7 @@ static int __ui_cre_tsk(struct pt_regs *regs)
 {
        xncompletion_t __user *u_completion;
        struct task_struct *p = current;
-       unsigned long __user *u_mode;
+       unsigned long __user *u_mode_offset;
        uitask_t *task;
        T_CTSK pk_ctsk;
        ID tskid;
@@ -56,7 +56,7 @@ static int __ui_cre_tsk(struct pt_regs *regs)
        /* Completion descriptor our parent thread is pending on. */
        u_completion = (xncompletion_t __user *)__xn_reg_arg3(regs);
 
-       u_mode = (unsigned long __user *)__xn_reg_arg4(regs);
+       u_mode_offset = (unsigned long __user *)__xn_reg_arg4(regs);
 
        err = cre_tsk(tskid, &pk_ctsk);
 
@@ -78,7 +78,8 @@ static int __ui_cre_tsk(struct pt_regs *regs)
                 * recycled before we could map it; however, the risk
                 * is mitigated by consistency checks performed in
                 * xnshadow_map(). */
-               return xnshadow_map(&task->threadbase, u_completion, u_mode);
+               return xnshadow_map(&task->threadbase,
+                                   u_completion, u_mode_offset);
        }
 
       fail:
diff --git a/ksrc/skins/vrtx/syscall.c b/ksrc/skins/vrtx/syscall.c
index dba6390..c5db2ad 100644
--- a/ksrc/skins/vrtx/syscall.c
+++ b/ksrc/skins/vrtx/syscall.c
@@ -47,7 +47,7 @@ static int __muxid;
  * a1: int tid;
  * a2: int prio;
  * a3: int mode;
- * a4: unsigned long *shadow_mode;
+ * a4: unsigned long *shadow_mode_offset;
  * }
  */
 
diff --git a/ksrc/skins/vxworks/syscall.c b/ksrc/skins/vxworks/syscall.c
index 3543ad1..26a48d2 100644
--- a/ksrc/skins/vxworks/syscall.c
+++ b/ksrc/skins/vxworks/syscall.c
@@ -66,7 +66,7 @@ static WIND_TCB *__wind_task_current(struct task_struct *p)
  * a2: int prio;
  * a3: int flags;
  * a4: pthread_self();
- * a5: unsigned long *mode;
+ * a5: unsigned long *mode_offset;
  * }
  */
 
diff --git a/src/skins/common/current.c b/src/skins/common/current.c
index 9903d7b..8684489 100644
--- a/src/skins/common/current.c
+++ b/src/skins/common/current.c
@@ -9,83 +9,38 @@
 #include <asm/xenomai/syscall.h>
 #include <asm-generic/bits/current.h>
 
-pthread_key_t xeno_current_mode_key;
+extern unsigned long xeno_sem_heap[2];
 
 #ifdef HAVE___THREAD
 __thread __attribute__ ((tls_model ("initial-exec")))
 xnhandle_t xeno_current = XN_NO_HANDLE;
 __thread __attribute__ ((tls_model ("initial-exec")))
-unsigned long xeno_current_mode;
-
-static inline int create_current_key(void) { return 0; }
+unsigned long *xeno_current_mode;
 
 static inline void __xeno_set_current(xnhandle_t current)
 {
        xeno_current = current;
 }
 
-static inline unsigned long *create_current_mode(void)
+void xeno_init_current_keys(void)
 {
-       return &xeno_current_mode;
 }
 
-static inline void free_current_mode(unsigned long *mode) { }
-
-#define XENO_MODE_LEAK_WARNING \
-       "Xenomai: WARNING, this version of Xenomai kernel is anterior to" \
-       " 2.5.2.\nIt can cause memory corruption on thread termination.\n" \
-       "Upgrade is recommended.\n"
-
+void xeno_set_current_mode(unsigned long offset)
+{
+       xeno_current_mode = (unsigned long *)(xeno_sem_heap[0] + offset);
+}
 #else /* !HAVE___THREAD */
 
+pthread_key_t xeno_current_mode_key;
 pthread_key_t xeno_current_key;
 
-static inline int create_current_key(void)
-{
-       return pthread_key_create(&xeno_current_key, NULL);
-}
-
 static inline void __xeno_set_current(xnhandle_t current)
 {
        current = (current != XN_NO_HANDLE ? current : (xnhandle_t)(0));
        pthread_setspecific(xeno_current_key, (void *)current);
 }
 
-static inline unsigned long *create_current_mode(void)
-{
-       return malloc(sizeof(unsigned long));
-}
-
-static inline void free_current_mode(unsigned long *mode)
-{
-       free(mode);
-}
-
-#define XENO_MODE_LEAK_WARNING \
-       "Xenomai: WARNING, this version of Xenomai kernel is anterior to" \
-       " 2.5.2.\nIn order to avoid getting memory corruption on thread " \
-       "termination, we leak\nup to 8 bytes per thread. Upgrade is " \
-       "recommended.\n"
-
-#endif /* !HAVE___THREAD */
-
-void xeno_current_warn_old(void)
-{
-       fprintf(stderr, XENO_MODE_LEAK_WARNING);
-}
-
-static void cleanup_current_mode(void *key)
-{
-       unsigned long *mode = key;
-
-       *mode = -1;
-
-       if (xnvdso_test_feature(XNVDSO_FEAT_DROP_U_MODE)) {
-               XENOMAI_SYSCALL0(__xn_sys_drop_u_mode);
-               free_current_mode(mode);
-       }
-}
-
 static void xeno_current_fork_handler(void)
 {
        if (xeno_get_current() != XN_NO_HANDLE)
@@ -94,13 +49,13 @@ static void xeno_current_fork_handler(void)
 
 static void init_current_keys(void)
 {
-       int err = create_current_key();
+       int err = pthread_key_create(&xeno_current_key, NULL);
        if (err)
                goto error_exit;
 
        pthread_atfork(NULL, NULL, &xeno_current_fork_handler);
 
-       err = pthread_key_create(&xeno_current_mode_key, cleanup_current_mode);
+       err = pthread_key_create(&xeno_current_mode_key, NULL);
        if (err) {
          error_exit:
                fprintf(stderr, "Xenomai: error creating TSD key: %s\n",
@@ -115,6 +70,13 @@ void xeno_init_current_keys(void)
        pthread_once(&xeno_init_current_keys_once, init_current_keys);
 }
 
+void xeno_set_current_mode(unsigned long offset)
+{
+       pthread_setspecific(xeno_current_mode_key,
+                           (void *)(xeno_sem_heap[0] + offset));
+}
+#endif /* !HAVE___THREAD */
+
 xnhandle_t xeno_slow_get_current(void)
 {
        xnhandle_t current;
@@ -138,23 +100,3 @@ void xeno_set_current(void)
        }
        __xeno_set_current(current);
 }
-
-unsigned long *xeno_init_current_mode(void)
-{
-       unsigned long *mode = create_current_mode();
-
-       pthread_setspecific(xeno_current_mode_key, mode);
-       return mode;
-}
-
-unsigned long xeno_slow_get_current_mode(void)
-{
-       xnthread_info_t info;
-       int err;
-
-       err = XENOMAI_SYSCALL1(__xn_sys_current_info, &info);
-       if (err < 0)
-               return XNRELAX;
-
-       return info.state & (XNRELAX|XNOTHER);
-}
diff --git a/src/skins/common/sem_heap.c b/src/skins/common/sem_heap.c
index 2355dd8..2c9514e 100644
--- a/src/skins/common/sem_heap.c
+++ b/src/skins/common/sem_heap.c
@@ -106,8 +106,6 @@ static void xeno_init_vdso(void)
        }
 
        nkvdso = (struct xnvdso *)(xeno_sem_heap[SHARED] + sysinfo.vdso);
-       if (!xnvdso_test_feature(XNVDSO_FEAT_DROP_U_MODE))
-               xeno_current_warn_old();
 }
 
 /* Will be called once at library loading time, and when re-binding
diff --git a/src/skins/native/task.c b/src/skins/native/task.c
index 70ba6f7..5e7be9f 100644
--- a/src/skins/native/task.c
+++ b/src/skins/native/task.c
@@ -57,6 +57,7 @@ static void *rt_task_trampoline(void *cookie)
 {
        struct rt_task_iargs *iargs = (struct rt_task_iargs *)cookie;
        void (*entry) (void *cookie);
+       unsigned long mode_offset;
        struct rt_arg_bulk bulk;
        RT_TASK *task, *self;
        long err;
@@ -81,7 +82,7 @@ static void *rt_task_trampoline(void *cookie)
        bulk.a5 = (u_long)pthread_self();
        /* Signal allocation failures by setting bulk.a6 to 0, they will be
           propagated to the thread waiting in xn_sys_completion. */
-       bulk.a6 = !self ? 0UL : (u_long)xeno_init_current_mode();
+       bulk.a6 = !self ? 0UL : (u_long)&mode_offset;
 
        err = XENOMAI_SKINCALL2(__native_muxid,
                                __native_task_create, &bulk,
@@ -96,6 +97,7 @@ static void *rt_task_trampoline(void *cookie)
        *self = *task;
 
        xeno_set_current();
+       xeno_set_current_mode(mode_offset);
 
        /* Wait on the barrier for the task to be started. The barrier
           could be released in order to process Linux signals while the
@@ -179,6 +181,7 @@ int rt_task_start(RT_TASK *task, void (*entry) (void 
*cookie), void *cookie)
 
 int rt_task_shadow(RT_TASK *task, const char *name, int prio, int mode)
 {
+       unsigned long mode_offset;
        struct rt_arg_bulk bulk;
        RT_TASK task_desc;
        RT_TASK *self;
@@ -212,12 +215,7 @@ int rt_task_shadow(RT_TASK *task, const char *name, int 
prio, int mode)
        bulk.a3 = (u_long)prio;
        bulk.a4 = (u_long)mode;
        bulk.a5 = (u_long)pthread_self();
-       bulk.a6 = (u_long)xeno_init_current_mode();
-
-       if (!bulk.a6) {
-               err = -ENOMEM;
-               goto fail;
-       }
+       bulk.a6 = (u_long)&mode_offset;
 
        err = XENOMAI_SKINCALL2(__native_muxid, __native_task_create, &bulk,
                                NULL);
@@ -227,6 +225,7 @@ int rt_task_shadow(RT_TASK *task, const char *name, int 
prio, int mode)
        *self = *task;
 
        xeno_set_current();
+       xeno_set_current_mode(mode_offset);
 
        return 0;
 
diff --git a/src/skins/posix/thread.c b/src/skins/posix/thread.c
index 81272c9..b0e6695 100644
--- a/src/skins/posix/thread.c
+++ b/src/skins/posix/thread.c
@@ -39,30 +39,16 @@ int __wrap_pthread_setschedparam(pthread_t thread,
                                 int policy, const struct sched_param *param)
 {
        pthread_t myself = pthread_self();
-       unsigned long *mode_buf = NULL;
+       unsigned long mode_offset;
        int err, promoted;
 
-       if (thread == myself) {
+       if (thread == myself)
                xeno_fault_stack();
 
-#ifdef HAVE___THREAD
-               mode_buf = xeno_init_current_mode();
-#else /* !HAVE___THREAD */
-               mode_buf = pthread_getspecific(xeno_current_mode_key);
-               if (!mode_buf) {
-                       mode_buf = malloc(sizeof(*mode_buf));
-
-                       if (!mode_buf)
-                               return ENOMEM;
-
-                       pthread_setspecific(xeno_current_mode_key, mode_buf);
-               }
-#endif /* !HAVE___THREAD */
-       }
-
        err = -XENOMAI_SKINCALL5(__pse51_muxid,
                                 __pse51_thread_setschedparam,
-                                thread, policy, param, mode_buf, &promoted);
+                                thread, policy, param,
+                                &mode_offset, &promoted);
 
        if (err == EPERM)
                return __real_pthread_setschedparam(thread, policy, param);
@@ -70,6 +56,7 @@ int __wrap_pthread_setschedparam(pthread_t thread,
        if (!err && promoted) {
                xeno_sigshadow_install_once();
                xeno_set_current();
+               xeno_set_current_mode(mode_offset);
                if (policy != SCHED_OTHER)
                        XENOMAI_SYSCALL1(__xn_sys_migrate, XENOMAI_XENO_DOMAIN);
        }
@@ -82,28 +69,16 @@ int pthread_setschedparam_ex(pthread_t thread,
 {
        pthread_t myself = pthread_self();
        struct sched_param short_param;
-       unsigned long *mode_buf = NULL;
+       unsigned long mode_offset;
        int err, promoted;
 
-       if (thread == myself) {
-#ifdef HAVE___THREAD
-               mode_buf = xeno_init_current_mode();
-#else /* !HAVE___THREAD */
-               mode_buf = pthread_getspecific(xeno_current_mode_key);
-               if (!mode_buf) {
-                       mode_buf = malloc(sizeof(*mode_buf));
-
-                       if (!mode_buf)
-                               return ENOMEM;
-
-                       pthread_setspecific(xeno_current_mode_key, mode_buf);
-               }
-#endif /* !HAVE___THREAD */
-       }
+       if (thread == myself)
+               xeno_fault_stack();
 
        err = -XENOMAI_SKINCALL5(__pse51_muxid,
                                 __pse51_thread_setschedparam_ex,
-                                thread, policy, param, mode_buf, &promoted);
+                                thread, policy, param,
+                                &mode_offset, &promoted);
 
        if (err == EPERM) {
                short_param.sched_priority = param->sched_priority;
@@ -113,6 +88,7 @@ int pthread_setschedparam_ex(pthread_t thread,
        if (!err && promoted) {
                xeno_sigshadow_install_once();
                xeno_set_current();
+               xeno_set_current_mode(mode_offset);
                if (policy != SCHED_OTHER)
                        XENOMAI_SYSCALL1(__xn_sys_migrate, XENOMAI_XENO_DOMAIN);
        }
@@ -187,10 +163,10 @@ static void *__pthread_trampoline(void *arg)
           registers (again, see later comment). */
        volatile pthread_t tid = pthread_self();
        void *(*start) (void *), *cookie;
+       unsigned long mode_offset;
        struct sched_param param;
        void *status = NULL;
        int parent_prio, policy;
-       unsigned long *mode_buf;
        long err;
 
        xeno_sigshadow_install_once();
@@ -198,18 +174,11 @@ static void *__pthread_trampoline(void *arg)
        param.sched_priority = iargs->prio;
        policy = iargs->policy;
        parent_prio = iargs->parent_prio;
-       mode_buf = xeno_init_current_mode();
-
-       if (!mode_buf) {
-               status = (void *)ENOMEM;
-               iargs->ret = ENOMEM;
-               goto out;
-       }
 
        /* Do _not_ inline the call to pthread_self() in the syscall
           macro: this trashes the syscall regs on some archs. */
        err = XENOMAI_SKINCALL4(__pse51_muxid, __pse51_thread_create, tid,
-                               iargs->policy, iargs->prio, mode_buf);
+                               iargs->policy, iargs->prio, &mode_offset);
        iargs->ret = -err;
 
        /* We must save anything we'll need to use from *iargs on our own
@@ -220,8 +189,10 @@ static void *__pthread_trampoline(void *arg)
        start = iargs->start;
        cookie = iargs->arg;
 
-       if (!err)
+       if (!err) {
                xeno_set_current();
+               xeno_set_current_mode(mode_offset);
+       }
 
        __real_sem_post(&iargs->sync);
 
@@ -238,7 +209,6 @@ static void *__pthread_trampoline(void *arg)
        } else
                status = (void *)-err;
 
-out:
        return status;
 }
 
diff --git a/src/skins/psos+/task.c b/src/skins/psos+/task.c
index 932444e..40d0f04 100644
--- a/src/skins/psos+/task.c
+++ b/src/skins/psos+/task.c
@@ -63,6 +63,7 @@ static void *psos_task_trampoline(void *cookie)
        struct psos_task_iargs *iargs = (struct psos_task_iargs *)cookie;
        void (*entry)(u_long, u_long, u_long, u_long);
        struct psos_arg_bulk bulk;
+       unsigned long mode_offset;
        u_long handle, targs[4];
        long err;
 
@@ -72,7 +73,7 @@ static void *psos_task_trampoline(void *cookie)
        bulk.a1 = (u_long)iargs->name;
        bulk.a2 = (u_long)iargs->prio;
        bulk.a3 = (u_long)iargs->flags;
-       bulk.a4 = (u_long)xeno_init_current_mode();
+       bulk.a4 = (u_long)&mode_offset;
        bulk.a5 = (u_long)pthread_self();
 
        if (!bulk.a4) {
@@ -87,6 +88,7 @@ static void *psos_task_trampoline(void *cookie)
                goto fail;
 
        xeno_set_current();
+       xeno_set_current_mode(mode_offset);
 
        /* Wait on the barrier for the task to be started. The barrier
           could be released in order to process Linux signals while the
@@ -173,6 +175,7 @@ u_long t_shadow(const char *name, /* Xenomai extension. */
                u_long *tid_r)
 {
        struct psos_arg_bulk bulk;
+       unsigned long mode_offset;
        int ret;
 
        xeno_fault_stack();
@@ -183,12 +186,14 @@ u_long t_shadow(const char *name, /* Xenomai extension. */
        bulk.a1 = (u_long)name;
        bulk.a2 = (u_long)prio;
        bulk.a3 = (u_long)flags;
-       bulk.a4 = (u_long)xeno_init_current_mode();
+       bulk.a4 = (u_long)&mode_offset;
        bulk.a5 = (u_long)pthread_self();
 
        ret = XENOMAI_SKINCALL3(__psos_muxid, __psos_t_create, &bulk, tid_r, 
NULL);
-       if (!ret)
+       if (!ret) {
                xeno_set_current();
+               xeno_set_current_mode(mode_offset);
+       }
 
        return ret;
 }
diff --git a/src/skins/uitron/task.c b/src/skins/uitron/task.c
index 92a7963..5308271 100644
--- a/src/skins/uitron/task.c
+++ b/src/skins/uitron/task.c
@@ -61,7 +61,7 @@ static void *uitron_task_trampoline(void *cookie)
 {
        struct uitron_task_iargs *iargs = (struct uitron_task_iargs *)cookie;
        struct sched_param param;
-       unsigned long *mode;
+       unsigned long mode_offset;
        void (*entry)(INT);
        int policy;
        long err;
@@ -77,20 +77,15 @@ static void *uitron_task_trampoline(void *cookie)
        pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
        xeno_sigshadow_install_once();
 
-       mode = xeno_init_current_mode();
-       if (!mode) {
-               err = -ENOMEM;
-               goto fail;
-       }
-
        err = XENOMAI_SKINCALL4(__uitron_muxid,
                                __uitron_cre_tsk,
                                iargs->tskid, iargs->pk_ctsk,
-                               iargs->completionp, mode);
+                               iargs->completionp, &mode_offset);
        if (err)
                goto fail;
 
        xeno_set_current();
+       xeno_set_current_mode(mode_offset);
 
        /* iargs->pk_ctsk might not be valid anymore, after our parent
           was released from the completion sync, so do not
diff --git a/src/skins/vrtx/task.c b/src/skins/vrtx/task.c
index 1dfac3e..3956b84 100644
--- a/src/skins/vrtx/task.c
+++ b/src/skins/vrtx/task.c
@@ -75,6 +75,7 @@ static void *vrtx_task_trampoline(void *cookie)
        struct vrtx_task_iargs *iargs = cookie;
        void (*entry)(void *arg), *arg;
        struct vrtx_arg_bulk bulk;
+       unsigned long mode_offset;
        long err;
 #ifndef HAVE___THREAD
        TCB *tcb;
@@ -99,7 +100,7 @@ static void *vrtx_task_trampoline(void *cookie)
        bulk.a1 = (u_long)iargs->tid;
        bulk.a2 = (u_long)iargs->prio;
        bulk.a3 = (u_long)iargs->mode;
-       bulk.a4 = (u_long)xeno_init_current_mode();
+       bulk.a4 = (u_long)&mode_offset;
        if (bulk.a4 == 0) {
                err = -ENOMEM;
                goto fail;
@@ -115,6 +116,7 @@ static void *vrtx_task_trampoline(void *cookie)
 
        if (err == 0) {
          xeno_set_current();
+         xeno_set_current_mode(mode_offset);
          entry(arg);
        }
 fail:
diff --git a/src/skins/vxworks/taskLib.c b/src/skins/vxworks/taskLib.c
index b77de0d..f751788 100644
--- a/src/skins/vxworks/taskLib.c
+++ b/src/skins/vxworks/taskLib.c
@@ -87,6 +87,7 @@ static void *wind_task_trampoline(void *cookie)
        struct wind_task_iargs *iargs =
            (struct wind_task_iargs *)cookie, _iargs;
        struct wind_arg_bulk bulk;
+       unsigned long mode_offset;
        WIND_TCB *pTcb;
        long err;
 
@@ -101,7 +102,7 @@ static void *wind_task_trampoline(void *cookie)
        bulk.a2 = (u_long)iargs->prio;
        bulk.a3 = (u_long)iargs->flags;
        bulk.a4 = (u_long)pthread_self();
-       bulk.a5 = (u_long)xeno_init_current_mode();
+       bulk.a5 = (u_long)&mode_offset;
        pTcb = iargs->pTcb;
 
        if (!bulk.a5) {
@@ -116,6 +117,7 @@ static void *wind_task_trampoline(void *cookie)
                goto fail;
 
        xeno_set_current();
+       xeno_set_current_mode(mode_offset);
 
 #ifdef HAVE___THREAD
        __vxworks_self = *pTcb;


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to