Module: xenomai-head Branch: master Commit: e5d539dc5bd3dc1d4a872624b1a2df1d0f35f0dd URL: http://git.xenomai.org/?p=xenomai-head.git;a=commit;h=e5d539dc5bd3dc1d4a872624b1a2df1d0f35f0dd
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..2f04c3e 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 ? *xeno_current_mode : XNRELAX; } #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 ? *mode : XNRELAX; } #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 c9e84a6..61d475e 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(¶m, (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(¶m, (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