Generic fast xnsynch support & more
Subsystems (2)
cover Generic fast xnsynch support & more
Here comes a significantly reworked patch series to improve fast mutex support of Xenomai.
This approach now introduces a generic fast xnsynch core and converts the existing POSIX implementation over. It also comes with a second user, the Native skin. Additionally, it improves xeno_get_current via a TLS variable and addresses the issue that threads in secondary mode acquiring an uncontended mutex need to be migrated first.
At this chance, the TLS optimization is also applied on self-lookups of task handles (Native, VRTX and VxWorks). And I included my SMP-by-default patch for user libs which is highly recommended to reduce the risk of accidental code breakage on SMP with the new mutex code.
Jan
--- include/asm-generic/atomic.h | 24 - xenomai/README.INSTALL | 2 xenomai/configure.in | 45 +- xenomai/include/asm-arm/atomic.h | 3 xenomai/include/asm-blackfin/atomic.h | 2 xenomai/include/asm-generic/Makefile.am | 2 xenomai/include/asm-generic/Makefile.in | 2 xenomai/include/asm-generic/bits/bind.h | 82 +++- xenomai/include/asm-generic/bits/current.h | 36 + xenomai/include/asm-generic/features.h | 24 - xenomai/include/asm-ia64/atomic.h | 2 xenomai/include/asm-powerpc/atomic.h | 2 xenomai/include/asm-x86/atomic.h | 2 xenomai/include/native/mutex.h | 23 - xenomai/include/native/syscall.h | 1 xenomai/include/nucleus/registry.h | 1 xenomai/include/nucleus/shadow.h | 3 xenomai/include/nucleus/synch.h | 70 +++ xenomai/include/nucleus/thread.h | 29 + xenomai/include/nucleus/types.h | 13 xenomai/include/psos+/syscall.h | 8 xenomai/include/rtdm/rtdm_driver.h | 2 xenomai/include/vrtx/syscall.h | 1 xenomai/include/vxworks/syscall.h | 1 xenomai/ksrc/arch/arm/Kconfig | 2 xenomai/ksrc/arch/powerpc/Kconfig | 2 xenomai/ksrc/arch/x86/Kconfig | 2 xenomai/ksrc/drivers/testing/switchtest.c | 2 xenomai/ksrc/nucleus/pipe.c | 2 xenomai/ksrc/nucleus/registry.c | 4 xenomai/ksrc/nucleus/select.c | 2 xenomai/ksrc/nucleus/shadow.c | 38 +- xenomai/ksrc/nucleus/synch.c | 534 ++++++++++++++++++++--------- xenomai/ksrc/nucleus/thread.c | 2 xenomai/ksrc/skins/native/Kconfig | 1 xenomai/ksrc/skins/native/alarm.c | 2 xenomai/ksrc/skins/native/buffer.c | 4 xenomai/ksrc/skins/native/cond.c | 18 xenomai/ksrc/skins/native/event.c | 2 xenomai/ksrc/skins/native/heap.c | 2 xenomai/ksrc/skins/native/intr.c | 2 xenomai/ksrc/skins/native/mutex.c | 327 ++++++++++------- xenomai/ksrc/skins/native/queue.c | 2 xenomai/ksrc/skins/native/sem.c | 2 xenomai/ksrc/skins/native/syscall.c | 132 +++++-- xenomai/ksrc/skins/native/task.c | 28 - xenomai/ksrc/skins/posix/Kconfig | 1 xenomai/ksrc/skins/posix/cb_lock.h | 21 - xenomai/ksrc/skins/posix/cond.c | 34 - xenomai/ksrc/skins/posix/intr.c | 2 xenomai/ksrc/skins/posix/mq.c | 4 xenomai/ksrc/skins/posix/mutex.c | 121 ++++-- xenomai/ksrc/skins/posix/mutex.h | 136 +------ xenomai/ksrc/skins/posix/sem.c | 2 xenomai/ksrc/skins/posix/syscall.c | 61 +-- xenomai/ksrc/skins/posix/thread.c | 14 xenomai/ksrc/skins/psos+/Kconfig | 2 xenomai/ksrc/skins/psos+/event.c | 2 xenomai/ksrc/skins/psos+/queue.c | 2 xenomai/ksrc/skins/psos+/rn.c | 2 xenomai/ksrc/skins/psos+/sem.c | 2 xenomai/ksrc/skins/psos+/syscall.c | 53 +- xenomai/ksrc/skins/psos+/task.c | 20 - xenomai/ksrc/skins/rtai/Kconfig | 1 xenomai/ksrc/skins/rtai/sem.c | 12 xenomai/ksrc/skins/rtai/task.c | 10 xenomai/ksrc/skins/rtdm/drvlib.c | 27 - xenomai/ksrc/skins/uitron/Kconfig | 1 xenomai/ksrc/skins/uitron/flag.c | 2 xenomai/ksrc/skins/uitron/mbx.c | 3 xenomai/ksrc/skins/uitron/sem.c | 3 xenomai/ksrc/skins/uitron/syscall.c | 8 xenomai/ksrc/skins/uitron/task.c | 11 xenomai/ksrc/skins/vrtx/Kconfig | 2 xenomai/ksrc/skins/vrtx/event.c | 2 xenomai/ksrc/skins/vrtx/mb.c | 2 xenomai/ksrc/skins/vrtx/mx.c | 7 xenomai/ksrc/skins/vrtx/queue.c | 2 xenomai/ksrc/skins/vrtx/sem.c | 2 xenomai/ksrc/skins/vrtx/syscall.c | 4 xenomai/ksrc/skins/vrtx/task.c | 17 xenomai/ksrc/skins/vxworks/Kconfig | 2 xenomai/ksrc/skins/vxworks/module.c | 2 xenomai/ksrc/skins/vxworks/msgQLib.c | 2 xenomai/ksrc/skins/vxworks/semLib.c | 8 xenomai/ksrc/skins/vxworks/syscall.c | 37 +- xenomai/ksrc/skins/vxworks/taskLib.c | 12 xenomai/src/skins/native/cond.c | 30 + xenomai/src/skins/native/init.c | 8 xenomai/src/skins/native/mutex.c | 105 +++++ xenomai/src/skins/native/task.c | 44 ++ xenomai/src/skins/posix/mutex.c | 192 +++++----- xenomai/src/skins/posix/thread.c | 33 + xenomai/src/skins/psos+/task.c | 34 + xenomai/src/skins/uitron/task.c | 29 + xenomai/src/skins/vrtx/init.c | 19 - xenomai/src/skins/vrtx/task.c | 37 +- xenomai/src/skins/vxworks/init.c | 8 xenomai/src/skins/vxworks/taskLib.c | 29 + 99 files changed, 1809 insertions(+), 909 deletions(-)
--
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux
PATCH 1/12 Generic thread registration
Lay groundwork for registering every thread at least anonymously with the Xenomai registry when required (e.g. handle-based fast xnsynch support). Wrap the operations appropriately, also saving a few #ifdefs.
--- include/nucleus/registry.h | 1 include/nucleus/thread.h | 25 +++++++++++++++++ ksrc/nucleus/thread.c | 2 + ksrc/skins/native/syscall.c | 61 ++++++++++++++++++++++++++----------------- ksrc/skins/native/task.c | 13 --------- ksrc/skins/psos+/syscall.c | 19 ++++++++----- ksrc/skins/psos+/task.c | 20 +++----------- ksrc/skins/vxworks/syscall.c | 31 ++++++++++++--------- ksrc/skins/vxworks/taskLib.c | 10 ------- 9 files changed, 102 insertions(+), 80 deletions(-)
ksrc/skins/native/syscall.c +38 -23
@@ -52,7 +52,8 @@ int __native_muxid;static int __rt_bind_helper (struct task_struct *p,struct pt_regs *regs,xnhandle_t *handlep, -unsigned magic,void **objaddrp) +unsigned magic,void **objaddrp, +unsigned long objoffs) {char name[XNOBJECT_NAME_LEN ];RTIME timeout;
@@ -82,7 +83,7 @@ static int __rt_bind_helper(struct task_/* Also validate the type of the bound object. */ -if (xeno_test_magic (objaddr, magic)) { +if (xeno_test_magic (objaddr + objoffs, magic)) {if (objaddrp) *objaddrp = objaddr; }else
@@ -93,6 +94,11 @@ static int __rt_bind_helper(struct task_return err; } +static RT_TASK *__rt_task_lookup (xnhandle_t threadh) +{ +return thread2rtask (xnthread_lookup (threadh)); +} +static RT_TASK *__rt_task_current (struct task_struct *p) {xnthread_t *thread =xnshadow_thread (p);
@@ -223,7 +229,9 @@ static int __rt_task_bind(struct pt_regsRT_TASK_PLACEHOLDER ph;int err; - err =__rt_bind_helper (p, regs, &ph.opaque,XENO_TASK_MAGIC ,NULL ); + err = +__rt_bind_helper (p, regs, &ph.opaque,XENO_TASK_MAGIC ,NULL , + -offsetof(RT_TASK , thread_base));if (err)return err;
@@ -253,7 +261,7 @@ static int __rt_task_start(struct pt_reg sizeof(ph)))return -EFAULT ; - task = (RT_TASK *)xnregistry_fetch (ph.opaque); + task =__rt_task_lookup (ph.opaque);if (!task)return -ESRCH ;
@@ -279,7 +287,7 @@ static int __rt_task_suspend(struct pt_r sizeof(ph)))return -EFAULT ; - task = (RT_TASK *)xnregistry_fetch (ph.opaque); + task =__rt_task_lookup (ph.opaque); }else task =__rt_task_current (p);
@@ -302,7 +310,7 @@ static int __rt_task_resume(struct pt_re sizeof(ph)))return -EFAULT ; - task = (RT_TASK *)xnregistry_fetch (ph.opaque); + task =__rt_task_lookup (ph.opaque);if (!task)return -ESRCH ;
@@ -326,7 +334,7 @@ static int __rt_task_delete(struct pt_re sizeof(ph)))return -EFAULT ; - task = (RT_TASK *)xnregistry_fetch (ph.opaque); + task =__rt_task_lookup (ph.opaque); }else task =__rt_task_current (p);
@@ -364,7 +372,7 @@ static int __rt_task_set_periodic(struct sizeof(ph)))return -EFAULT ; - task = (RT_TASK *)xnregistry_fetch (ph.opaque); + task =__rt_task_lookup (ph.opaque); }else task =__rt_task_current (p);
@@ -418,7 +426,7 @@ static int __rt_task_set_priority(struct sizeof(ph)))return -EFAULT ; - task = (RT_TASK *)xnregistry_fetch (ph.opaque); + task =__rt_task_lookup (ph.opaque); }else task =__rt_task_current (p);
@@ -473,7 +481,7 @@ static int __rt_task_unblock(struct pt_r sizeof(ph)))return -EFAULT ; - task = (RT_TASK *)xnregistry_fetch (ph.opaque); + task =__rt_task_lookup (ph.opaque);if (!task)return -ESRCH ;
@@ -500,7 +508,7 @@ static int __rt_task_inquire(struct pt_r sizeof(ph)))return -EFAULT ; - task = (RT_TASK *)xnregistry_fetch (ph.opaque); + task =__rt_task_lookup (ph.opaque); }else task =__rt_task_current (p);
@@ -541,7 +549,7 @@ static int __rt_task_notify(struct pt_re sizeof(ph)))return -EFAULT ; - task = (RT_TASK *)xnregistry_fetch (ph.opaque); + task =__rt_task_lookup (ph.opaque); }else task =__rt_task_current (p);
@@ -627,7 +635,7 @@ static int __rt_task_slice(struct pt_reg sizeof(ph)))return -EFAULT ; - task = (RT_TASK *)xnregistry_fetch (ph.opaque); + task =__rt_task_lookup (ph.opaque); }else task =__rt_task_current (current);
@@ -667,7 +675,7 @@ static int __rt_task_send(struct pt_regs sizeof(ph)))return -EFAULT ; - task = (RT_TASK *)xnregistry_fetch (ph.opaque); + task =__rt_task_lookup (ph.opaque); }else task =__rt_task_current (current);
@@ -1104,7 +1112,9 @@ static int __rt_sem_bind(struct pt_regsRT_SEM_PLACEHOLDER ph;int err; - err =__rt_bind_helper (current, regs, &ph.opaque,XENO_SEM_MAGIC ,NULL ); + err = +__rt_bind_helper (current, regs, &ph.opaque,XENO_SEM_MAGIC , +NULL ,0 );if (err)return err;
@@ -1324,7 +1334,8 @@ static int __rt_event_bind(struct pt_regint err; err = -__rt_bind_helper (current, regs, &ph.opaque,XENO_EVENT_MAGIC ,NULL ); +__rt_bind_helper (current, regs, &ph.opaque,XENO_EVENT_MAGIC , +NULL ,0 );if (err)return err;
@@ -1567,7 +1578,8 @@ static int __rt_mutex_bind(struct pt_regint err; err = -__rt_bind_helper (current, regs, &ph.opaque,XENO_MUTEX_MAGIC ,NULL ); +__rt_bind_helper (current, regs, &ph.opaque,XENO_MUTEX_MAGIC , +NULL ,0 );if (err)return err;
@@ -1758,7 +1770,8 @@ static int __rt_cond_bind(struct pt_regsint err; err = -__rt_bind_helper (current, regs, &ph.opaque,XENO_COND_MAGIC ,NULL ); +__rt_bind_helper (current, regs, &ph.opaque,XENO_COND_MAGIC , +NULL ,0 );if (err)return err;
@@ -2008,7 +2021,7 @@ static int __rt_queue_bind(struct pt_reg err =__rt_bind_helper (p, regs, &ph.opaque,XENO_QUEUE_MAGIC , - (void **)&q); + (void **)&q,0 );if (err) goto unlock_and_exit;
@@ -2507,7 +2520,7 @@ static int __rt_heap_bind(struct pt_regs err =__rt_bind_helper (p, regs, &ph.opaque,XENO_HEAP_MAGIC , - (void **)&heap); + (void **)&heap,0 );if (err) goto unlock_and_exit;
@@ -3018,7 +3031,7 @@ static int __rt_intr_bind(struct pt_regsRT_INTR_PLACEHOLDER ph;int err; - err =__rt_bind_helper (p, regs, &ph.opaque,XENO_INTR_MAGIC ,NULL ); + err =__rt_bind_helper (p, regs, &ph.opaque,XENO_INTR_MAGIC ,NULL ,0 );if (err)return err;
@@ -3275,7 +3288,7 @@ static int __rt_pipe_bind(struct pt_regsRT_PIPE_PLACEHOLDER ph;int err; - err =__rt_bind_helper (p, regs, &ph.opaque,XENO_PIPE_MAGIC ,NULL ); + err =__rt_bind_helper (p, regs, &ph.opaque,XENO_PIPE_MAGIC ,NULL ,0 );if (err)return err;
@@ -3551,7 +3564,9 @@ static int __rt_buffer_bind(struct pt_reRT_BUFFER_PLACEHOLDER ph;int ret; - ret =__rt_bind_helper (current, regs, &ph.opaque,XENO_BUFFER_MAGIC ,NULL ); + ret = +__rt_bind_helper (current, regs, &ph.opaque,XENO_BUFFER_MAGIC , +NULL ,0 );if (ret)return ret;
ksrc/skins/native/task.c +1 -12
@@ -46,7 +46,6 @@#include <nucleus/pod.h> #include <nucleus/heap.h> -#include <nucleus/registry.h> #include <native/task.h> #include <native/timer.h>
@@ -80,11 +79,6 @@ static void __task_delete_hook(xnthread_xnsynch_destroy (&task->msendq);#endif /* CONFIG_XENO_OPT_NATIVE_MPS */ -#ifdef CONFIG_XENO_OPT_REGISTRY -if (xnthread_handle (&task->thread_base) !=XN_NO_HANDLE ) -xnregistry_remove (xnthread_handle (&task->thread_base)); -#endif /* CONFIG_XENO_OPT_REGISTRY */ -xnsynch_destroy (&task->safesynch);removeq (&__xeno_task_q, &task->link);
@@ -285,20 +279,15 @@ int rt_task_create(RT_TASK *task,appendq (&__xeno_task_q, &task->link);xnlock_put_irqrestore (&nklock, s); -#ifdef CONFIG_XENO_OPT_REGISTRY /* <!> Since xnregister_enter() may reschedule, only register complete objects, so that the registry cannot return handles to half-baked objects... */ if (name) { - err =xnregistry_enter (task->rname, - task, - &xnthread_handle (&task->thread_base), -NULL ); + err =xnthread_register (&task->thread_base, task->rname);if (err)xnpod_delete_thread (&task->thread_base); } -#endif /* CONFIG_XENO_OPT_REGISTRY */ return err; }
ksrc/skins/psos+/syscall.c +12 -7
@@ -44,6 +44,11 @@int __psos_muxid; +static inline psostask_t *__psos_task_lookup (xnhandle_t taskh) +{ +return thread2psostask (xnthread_lookup (taskh)); +} +static psostask_t *__psos_task_current (struct task_struct *p) {xnthread_t *thread =xnshadow_thread (p);
@@ -131,7 +136,7 @@ static int __t_start(struct pt_regs *regpsostask_t *task; handle =__xn_reg_arg1 (regs); - task = (psostask_t *)xnregistry_fetch (handle); + task =__psos_task_lookup (handle);if (!task)return ERR_OBJID ;
@@ -162,7 +167,7 @@ static int __t_delete(struct pt_regs *re handle =__xn_reg_arg1 (regs);if (handle) - task = (psostask_t *)xnregistry_fetch (handle); + task =__psos_task_lookup (handle);else task =__psos_task_current (current);
@@ -182,7 +187,7 @@ static int __t_suspend(struct pt_regs *rpsostask_t *task;if (handle) - task = (psostask_t *)xnregistry_fetch (handle); + task =__psos_task_lookup (handle);else task =__psos_task_current (current);
@@ -202,7 +207,7 @@ static int __t_resume(struct pt_regs *repsostask_t *task;if (handle) - task = (psostask_t *)xnregistry_fetch (handle); + task =__psos_task_lookup (handle);else task =__psos_task_current (current);
@@ -284,7 +289,7 @@ static int __t_setpri(struct pt_regs *repsostask_t *task;if (handle) - task = (psostask_t *)xnregistry_fetch (handle); + task =__psos_task_lookup (handle);else task =__psos_task_current (current);
@@ -314,7 +319,7 @@ static int __ev_send(struct pt_regs *regu_long events;if (handle) - task = (psostask_t *)xnregistry_fetch (handle); + task =__psos_task_lookup (handle);else task =__psos_task_current (current);
@@ -1317,7 +1322,7 @@ static int __as_send(struct pt_regs *regpsostask_t *task;if (handle) - task = (psostask_t *)xnregistry_fetch (handle); + task =__psos_task_lookup (handle);else task =__psos_task_current (current);
ksrc/skins/psos+/task.c +5 -15
@@ -17,7 +17,6 @@* 02111-1307, USA. */ -#include <nucleus/registry.h> #include <psos+/task.h> #include <psos+/tm.h>
@@ -45,11 +44,6 @@ static void psostask_delete_hook(xnthreaif (xnthread_get_magic (thread) !=PSOS_SKIN_MAGIC )return ; -#ifdef CONFIG_XENO_OPT_REGISTRY -if (xnthread_handle (thread) !=XN_NO_HANDLE ) -xnregistry_remove (xnthread_handle (thread)); -#endif /* CONFIG_XENO_OPT_REGISTRY */ - task =thread2psostask (thread);removeq (&psostaskq, &task->link);
@@ -95,6 +89,7 @@ u_long t_create(const char *name, {xnflags_t bflags =0 ;psostask_t *task; +u_long err;spl_t s;int n;
@@ -159,16 +154,11 @@ u_long t_create(const char *name, *tid_r = (u_long )task;xnlock_put_irqrestore (&nklock, s); -#ifdef CONFIG_XENO_OPT_REGISTRY - { -u_long err =xnregistry_enter (task->name, - task, &xnthread_handle (&task->threadbase),NULL ); -if (err) { -t_delete ((u_long )task); -return err; - } + err =xnthread_register (&task->threadbase, task->name); +if (err) { +t_delete ((u_long )task); +return err; } -#endif /* CONFIG_XENO_OPT_REGISTRY */ xnarch_create_display (&task->threadbase, task->name, psostask);
ksrc/skins/vxworks/syscall.c +18 -13
@@ -42,6 +42,11 @@int __wind_muxid; +static inline WIND_TCB *__wind_lookup_task (xnhandle_t threadh) +{ +return thread2wind_task (xnthread_lookup (threadh)); +} +static WIND_TCB *__wind_task_current (struct task_struct *p) {xnthread_t *thread =xnshadow_thread (p);
@@ -146,7 +151,7 @@ out:static int __wind_task_activate (struct pt_regs *regs) { -WIND_TCB *pTcb = (WIND_TCB *)xnregistry_fetch (__xn_reg_arg1 (regs)); +WIND_TCB *pTcb =__wind_lookup_task (__xn_reg_arg1 (regs));if (!pTcb)return S_objLib_OBJ_ID_ERROR;
@@ -167,7 +172,7 @@ static int __wind_task_deleteforce(strucWIND_TCB *pTcb;if (handle) - pTcb = (WIND_TCB *)xnregistry_fetch (handle); + pTcb =__wind_lookup_task (handle);else pTcb =__wind_task_current (current);
@@ -190,7 +195,7 @@ static int __wind_task_delete(struct pt_WIND_TCB *pTcb;if (handle) - pTcb = (WIND_TCB *)xnregistry_fetch (handle); + pTcb =__wind_lookup_task (handle);else pTcb =__wind_task_current (current);
@@ -213,7 +218,7 @@ static int __wind_task_suspend(struct ptWIND_TCB *pTcb;if (handle) - pTcb = (WIND_TCB *)xnregistry_fetch (handle); + pTcb =__wind_lookup_task (handle);else pTcb =__wind_task_current (current);
@@ -232,7 +237,7 @@ static int __wind_task_suspend(struct ptstatic int __wind_task_resume (struct pt_regs *regs) { -WIND_TCB *pTcb = (WIND_TCB *)xnregistry_fetch (__xn_reg_arg1 (regs)); +WIND_TCB *pTcb =__wind_lookup_task (__xn_reg_arg1 (regs));if (!pTcb)return S_objLib_OBJ_ID_ERROR;
@@ -275,7 +280,7 @@ static int __wind_task_priorityset(strucWIND_TCB *pTcb;if (handle) - pTcb = (WIND_TCB *)xnregistry_fetch (handle); + pTcb =__wind_lookup_task (handle);else pTcb =__wind_task_current (current);
@@ -299,7 +304,7 @@ static int __wind_task_priorityget(strucint prio;if (handle) - pTcb = (WIND_TCB *)xnregistry_fetch (handle); + pTcb =__wind_lookup_task (handle);else pTcb =__wind_task_current (current);
@@ -374,7 +379,7 @@ static int __wind_task_verifyid(struct pxnhandle_t handle =__xn_reg_arg1 (regs);WIND_TCB *pTcb; - pTcb = (WIND_TCB *)xnregistry_fetch (handle); + pTcb =__wind_lookup_task (handle);if (!pTcb)return S_objLib_OBJ_ID_ERROR;
@@ -574,7 +579,7 @@ static int __wind_taskinfo_name(struct pconst char *name;WIND_TCB *pTcb; - pTcb = (WIND_TCB *)xnregistry_fetch (handle); + pTcb =__wind_lookup_task (handle);if (!pTcb)return S_objLib_OBJ_ID_ERROR;
@@ -618,7 +623,7 @@ static int __wind_taskinfo_status(structxnlock_get_irqsave (&nklock, s); - pTcb = (WIND_TCB *)xnregistry_fetch (handle); + pTcb =__wind_lookup_task (handle);if (!pTcb || pTcb->magic !=WIND_TASK_MAGIC ) {xnlock_put_irqrestore (&nklock, s);
@@ -643,7 +648,7 @@ static int __wind_taskinfo_get(struct ptWIND_TCB *pTcb;int err; - pTcb = (WIND_TCB *)xnregistry_fetch (handle); + pTcb =__wind_lookup_task (handle);if (!pTcb)return S_objLib_OBJ_ID_ERROR;
@@ -673,7 +678,7 @@ static int __wind_errno_taskset(struct preturn 0 ; } - pTcb = (WIND_TCB *)xnregistry_fetch (handle); + pTcb =__wind_lookup_task (handle);if (!pTcb)return S_objLib_OBJ_ID_ERROR;
@@ -696,7 +701,7 @@ static int __wind_errno_taskget(struct pif (!handle) errcode =wind_errnoget ();else { - pTcb = (WIND_TCB *)xnregistry_fetch (handle); + pTcb =__wind_lookup_task (handle);if (!pTcb)return S_objLib_OBJ_ID_ERROR;
ksrc/skins/vxworks/taskLib.c +1 -9
@@ -170,14 +170,11 @@ STATUS taskInit(WIND_TCB *pTcb,appendq (&wind_tasks_q, &pTcb->link);xnlock_put_irqrestore (&nklock, s); -#ifdef CONFIG_XENO_OPT_REGISTRY -if (xnregistry_enter (pTcb->name, - pTcb, &xnthread_handle (&pTcb->threadbase),NULL )) { +if (xnthread_register (&pTcb->threadbase, pTcb->name)) {wind_errnoset (S_objLib_OBJ_ID_ERROR);taskDeleteForce ((TASK_ID ) pTcb);return ERROR ; } -#endif /* CONFIG_XENO_OPT_REGISTRY */ return OK ; }
@@ -618,11 +615,6 @@ static void wind_task_delete_hook(xnthreif (xnthread_get_magic (thread) !=VXWORKS_SKIN_MAGIC )return ; -#ifdef CONFIG_XENO_OPT_REGISTRY -if (xnthread_handle (thread) !=XN_NO_HANDLE ) -xnregistry_remove (xnthread_handle (thread)); -#endif /* CONFIG_XENO_OPT_REGISTRY */ - task =thread2wind_task (thread);xnsynch_destroy (&task->safesync);
include/nucleus/registry.h +0 -1
@@ -35,7 +35,6 @@#if defined(__KERNEL__) || defined(__XENO_SIM__)#include <nucleus/synch.h> -#include <nucleus/thread.h> struct xnpnode ;
include/nucleus/thread.h +25 -0
@@ -130,6 +130,7 @@#include <nucleus/stat.h> #include <nucleus/timer.h> +#include <nucleus/registry.h> #ifdef __XENO_SIM__/* Pseudo-status (must not conflict with other bits) */
@@ -392,6 +393,30 @@ static inline xnticks_t xnthread_get_perreturn period; } +#ifdef CONFIG_XENO_OPT_REGISTRY +static inline int xnthread_register (xnthread_t *thread,const char *name) +{ +return xnregistry_enter (name, thread, &xnthread_handle (thread),NULL ); +} + +static inline xnthread_t *xnthread_lookup (xnhandle_t threadh) +{ +xnthread_t *thread =xnregistry_fetch (threadh); + +return (thread &&xnthread_handle (thread) == threadh) ? thread :NULL ; +} +#else /* !CONFIG_XENO_OPT_REGISTRY */ +static inline int xnthread_register (xnthread_t *thread,const char *name) +{ +return 0 ; +} + +static inline xnthread_t *xnthread_lookup (xnhandle_t threadh) +{ +return NULL ; +} +#endif /* !CONFIG_XENO_OPT_REGISTRY */ + #ifdef __cplusplus }#endif
ksrc/nucleus/thread.c +2 -0
@@ -136,6 +136,8 @@ void xnthread_cleanup_tcb(xnthread_t *th#endif #ifdef CONFIG_XENO_OPT_REGISTRY +if (thread->registry.handle !=XN_NO_HANDLE ) +xnregistry_remove (thread->registry.handle); thread->registry.handle =XN_NO_HANDLE ;#endif /* CONFIG_XENO_OPT_REGISTRY */ }
Re: [Xenomai-core] [PATCH 01/12] Generic thread registration
Jan Kiszka wrote:
Why the funky last parameter added to __rt_bind_helper ?
Signature · 1 line
Gilles.
Re: [Xenomai-core] [PATCH 01/12] Generic thread registration
Quoted 3 lines · Gilles Chanteperdrix
Jan Kiszka wrote:
Why the funky last parameter added to
__rt_bind_helper?
As __rt_bind_helper can now be called with an xnthread object address, thus we take its offset inside RT_TASK into account. It is not a nice interface, I know, but I didn't find a better one.
Jan
PATCH 2/12 Handle-based xeno_get_current service
In reply to Jan KiszkaTo avoid sharing kernel object pointers with user space, a handle-based approach is installed by this patch. It also reserves a few bits of the handle value for special use (like the claimed bit of fast xnsynch). Furthermore, the patch ensures that threads are registered at least anonymously to allow them being used with fast xnsynch objects.
--- include/asm-generic/bits/bind.h | 9 ++++- include/asm-generic/bits/current.h | 5 +-- include/nucleus/types.h | 13 +++++++ ksrc/nucleus/shadow.c | 16 +++++++-- ksrc/skins/native/Kconfig | 1 ksrc/skins/native/task.c | 8 +--- ksrc/skins/posix/Kconfig | 1 ksrc/skins/posix/cb_lock.h | 15 ++++++--- ksrc/skins/posix/cond.c | 12 ++++--- ksrc/skins/posix/mutex.c | 21 +++++++----- ksrc/skins/posix/mutex.h | 61 +++++++++++++++++++++++-------------- ksrc/skins/posix/syscall.c | 11 +++--- ksrc/skins/posix/thread.c | 12 +++++++ ksrc/skins/psos+/Kconfig | 2 - ksrc/skins/rtai/Kconfig | 1 ksrc/skins/rtai/task.c | 10 ++++++ ksrc/skins/rtdm/drvlib.c | 8 ++++ ksrc/skins/uitron/Kconfig | 1 ksrc/skins/uitron/task.c | 11 ++++++ ksrc/skins/vrtx/Kconfig | 2 - ksrc/skins/vrtx/task.c | 17 +++++++++- ksrc/skins/vxworks/Kconfig | 2 - src/skins/posix/mutex.c | 41 ++++++++++++------------ 23 files changed, 199 insertions(+), 81 deletions(-)
include/asm-generic/bits/current.h +3 -2
@@ -2,14 +2,15 @@#define _XENO_ASM_GENERIC_CURRENT_H#include <pthread.h> +#include <nucleus/types.h> extern pthread_key_t xeno_current_key;extern void xeno_set_current (void ); -static inline void *xeno_get_current (void ) +static inline xnhandle_t xeno_get_current (void ) { -return pthread_getspecific (xeno_current_key); +return (xnhandle_t )pthread_getspecific (xeno_current_key); }#endif /* _XENO_ASM_GENERIC_CURRENT_H */
include/nucleus/types.h +13 -0
@@ -61,6 +61,19 @@ typedef unsigned long xnhandle_t;#define XN_NO_HANDLE ((xnhandle_t)0) +#define XN_HANDLE_SPARE0 ((xnhandle_t)0x10000000) +#define XN_HANDLE_SPARE1 ((xnhandle_t)0x20000000) +#define XN_HANDLE_SPARE2 ((xnhandle_t)0x40000000) +#define XN_HANDLE_SPARE3 ((xnhandle_t)0x80000000) +#define XN_HANDLE_SPARE_MASK ((xnhandle_t)0xf0000000) + +#define xnhandle_mask_spare (handle) ((handle) & ~XN_HANDLE_SPARE_MASK) +#define xnhandle_test_spare (handle, bits) (!!((handle) & (bits))) +#define xnhandle_set_spare (handle, bits) \ + do { (handle) |= (bits); } while (0) +#define xnhandle_clear_spare (handle, bits) \ + do { (handle) &= ~(bits); } while (0) +struct xnintr ;typedef int (*xnisr_t )(struct xnintr *intr);
ksrc/nucleus/shadow.c +13 -3
@@ -1908,13 +1908,21 @@ static int xnshadow_sys_sem_heap(structreturn __xn_safe_copy_to_user (us_hinfo, &hinfo,sizeof (*us_hinfo)); } +#ifdef CONFIG_XENO_OPT_REGISTRY static int xnshadow_sys_current (struct pt_regs *regs) { -xnthread_t *__user *us_current, *cur =xnshadow_thread (current); - us_current = (xnthread_t *__user *)__xn_reg_arg1 (regs); +xnthread_t *cur =xnshadow_thread (current); +xnhandle_t __user *us_handle; -return __xn_safe_copy_to_user (us_current, &cur,sizeof (*us_current)); +if (!cur) +return -EPERM ; + + us_handle = (xnhandle_t __user *)__xn_reg_arg1 (regs); + +return __xn_safe_copy_to_user (us_handle, &xnthread_handle (cur), +sizeof (*us_handle)); } +#endif /* CONFIG_XENO_OPT_REGISTRY */ static xnsysent_t __systab[] = { [__xn_sys_migrate] = {&xnshadow_sys_migrate, __xn_exec_current},
@@ -1925,7 +1933,9 @@ static xnsysent_t __systab[] = { [__xn_sys_barrier] = {&xnshadow_sys_barrier, __xn_exec_lostage}, [__xn_sys_trace] = {&xnshadow_sys_trace, __xn_exec_any}, [__xn_sys_sem_heap] = {&xnshadow_sys_sem_heap, __xn_exec_any}, +#ifdef CONFIG_XENO_OPT_REGISTRY [__xn_sys_current] = {&xnshadow_sys_current, __xn_exec_any}, +#endif /* CONFIG_XENO_OPT_REGISTRY */ };static void *xnshadow_sys_event (int event,void *data)
ksrc/skins/posix/cb_lock.h +11 -4
@@ -3,15 +3,22 @@#include <asm/xenomai/atomic.h> #include <nucleus/compiler.h> +#include <nucleus/types.h> #ifndef __KERNEL__typedef void xnthread_t ;#endif /* __KERNEL__ */ -#define test_claimed (owner) ((long) (owner) & 1) -#define clear_claimed (owner) ((xnthread_t *) ((long) (owner) & ~1)) -#define set_claimed (owner, bit) \ - ((xnthread_t *) ((long) clear_claimed(owner) | !!(bit))) +#define __CLAIMED_BIT XN_HANDLE_SPARE3 + +#define test_claimed (owner) xnhandle_test_spare(owner, __CLAIMED_BIT) +#define clear_claimed (owner) xnhandle_mask_spare(owner) +#define set_claimed (owner, bit) ({ \ + xnhandle_t __tmp = xnhandle_mask_spare(owner); \ + if (bit) \ + xnhandle_set_spare(__tmp, __CLAIMED_BIT); \ + __tmp; \ +})#ifdef CONFIG_XENO_FASTSEM
ksrc/skins/posix/cond.c +7 -5
@@ -230,18 +230,20 @@ static inline int mutex_save_count(xnthr mutex = shadow->mutex; -if (clear_claimed (xnarch_atomic_intptr_get (mutex->owner)) != cur) +if (clear_claimed (xnarch_atomic_get (mutex->owner)) != +xnthread_handle (cur))return EPERM ; *count_ptr = shadow->lockcnt; -if (likely (xnarch_atomic_intptr_cmpxchg (mutex->owner, cur,NULL ) == cur)) +if (likely (xnarch_atomic_cmpxchg (mutex->owner, cur,XN_NO_HANDLE ) == +xnthread_handle (cur)))return 0 ; owner =xnsynch_wakeup_one_sleeper (&mutex->synchbase); -xnarch_atomic_intptr_set - (mutex->owner, -set_claimed (owner,xnsynch_nsleepers (&mutex->synchbase))); +xnarch_atomic_set (mutex->owner, +set_claimed (xnthread_handle (owner), +xnsynch_nsleepers (&mutex->synchbase)));/* Do not reschedule here, releasing the mutex and suspension must be done atomically in pthread_cond_*wait. */
ksrc/skins/posix/mutex.c +13 -8
@@ -82,7 +82,7 @@ int pse51_mutex_check_init(struct __shadint pse51_mutex_init_internal (struct __shadow_mutex *shadow,pse51_mutex_t *mutex, -xnarch_atomic_intptr_t *ownerp, +xnarch_atomic_t *ownerp,const pthread_mutexattr_t *attr) {xnflags_t synch_flags =XNSYNCH_PRIO |XNSYNCH_NOPIP ;
@@ -118,7 +118,7 @@ int pse51_mutex_init_internal(struct __s mutex->owner = ownerp; mutex->owningq = kq; mutex->sleepers =0 ; -xnarch_atomic_intptr_set (ownerp,NULL ); +xnarch_atomic_set (ownerp,XN_NO_HANDLE );xnlock_get_irqsave (&nklock, s);appendq (&kq->mutexq, &mutex->link);
@@ -159,7 +159,7 @@ int pthread_mutex_init(pthread_mutex_t * &((union __xeno_mutex *)mx)->shadow_mutex;DECLARE_CB_LOCK_FLAGS (s);pse51_mutex_t *mutex; -xnarch_atomic_intptr_t *ownerp; +xnarch_atomic_t *ownerp;int err;if (!attr)
@@ -185,9 +185,9 @@ int pthread_mutex_init(pthread_mutex_t *if (!mutex)return ENOMEM ; - ownerp = (xnarch_atomic_intptr_t *) + ownerp = (xnarch_atomic_t *)xnheap_alloc (&xnsys_ppd_get (attr->pshared)->sem_heap, -sizeof (xnarch_atomic_intptr_t)); +sizeof (xnarch_atomic_t));if (!ownerp) {xnfree (mutex);return EAGAIN ;
@@ -266,7 +266,7 @@ int pthread_mutex_destroy(pthread_mutex_return EPERM ; } -if (xnarch_atomic_intptr_get (mutex->owner)) { +if (xnarch_atomic_get (mutex->owner) !=XN_NO_HANDLE ) {cb_write_unlock (&shadow->lock, s);return EBUSY ; }
@@ -290,6 +290,10 @@ int pse51_mutex_timedlock_break(struct _spl_t s;int err; +/* We need a valid thread handle for the fast lock. */ +if (xnthread_handle (cur) ==XN_NO_HANDLE ) +return -EPERM ; + err =pse51_mutex_timedlock_internal (cur, shadow,1 , timed, abs_to);if (err != -EBUSY ) goto unlock_and_return;
@@ -392,7 +396,7 @@ int pthread_mutex_trylock(pthread_mutex_return -PTR_ERR (owner); err =EBUSY ; -if (clear_claimed (owner) == cur) { +if (owner == cur) {pse51_mutex_t *mutex = shadow->mutex;if (mutex->attr.type ==PTHREAD_MUTEX_RECURSIVE ) {
@@ -573,7 +577,8 @@ int pthread_mutex_unlock(pthread_mutex_t mutex = shadow->mutex; -if (clear_claimed (xnarch_atomic_intptr_get (mutex->owner)) != cur) { +if (clear_claimed (xnarch_atomic_get (mutex->owner)) != +xnthread_handle (cur)) { err =EPERM ; goto out; }
ksrc/skins/posix/mutex.h +39 -22
146 lines not on this page · raw message
ksrc/skins/posix/syscall.c +6 -5
@@ -1060,7 +1060,8 @@ static int __pthread_mutex_unlock(struct mutex = shadow->mutex; -if (clear_claimed (xnarch_atomic_intptr_get (mutex->owner)) != cur) { +if (clear_claimed (xnarch_atomic_get (mutex->owner)) != +xnthread_handle (cur)) { err = -EPERM ; goto out; }
@@ -1119,7 +1120,7 @@ static int __pthread_mutex_init(struct ppthread_mutexattr_t locattr, *attr, *uattrp;union __xeno_mutex mx, *umx;pse51_mutex_t *mutex; -xnarch_atomic_intptr_t *ownerp; +xnarch_atomic_t *ownerp;int err; umx = (union __xeno_mutex *)__xn_reg_arg1 (regs);
@@ -1144,9 +1145,9 @@ static int __pthread_mutex_init(struct pif (!mutex)return -ENOMEM ; - ownerp = (xnarch_atomic_intptr_t *) + ownerp = (xnarch_atomic_t *)xnheap_alloc (&xnsys_ppd_get (attr->pshared)->sem_heap, -sizeof (xnarch_atomic_intptr_t)); +sizeof (xnarch_atomic_t));if (!ownerp) {xnfree (mutex);return -EAGAIN ;
@@ -1185,7 +1186,7 @@ static int __pthread_mutex_destroy(strucif (pse51_kqueues (mutex->attr.pshared) != mutex->owningq)return -EPERM ; -if (xnarch_atomic_intptr_get (mutex->owner)) +if (xnarch_atomic_get (mutex->owner) !=XN_NO_HANDLE )return -EBUSY ;pse51_mark_deleted (shadow);
src/skins/posix/mutex.c +21 -20
119 lines not on this page · raw message
ksrc/skins/posix/thread.c +12 -0
@@ -234,6 +234,18 @@ int pthread_create(pthread_t *tid, thread->hkey.mm =NULL ;#endif /* CONFIG_XENO_OPT_PERVASIVE */ +#ifdef CONFIG_XENO_FASTSEM +/* We need an anonymous registry entry to obtain a handle for fast +mutex locking. */ + { +int err =xnthread_register (&thread->threadbase,"" ); +if (err) { +thread_destroy (thread); +return err; + } + } +#endif /* CONFIG_XENO_FASTSEM */ + *tid = thread;/* Must be done before the thread is started. */ if (start)/* Do not start shadow threads (i.e. start == NULL). */
ksrc/skins/posix/Kconfig +1 -0
@@ -1,5 +1,6 @@ menuconfig XENO_SKIN_POSIX depends on XENO_OPT_NUCLEUS + select XENO_OPT_REGISTRY if XENO_FASTSEM tristate "POSIX API" default y help
include/asm-generic/bits/bind.h +8 -1
@@ -22,7 +22,14 @@ __attribute__ ((weak))void xeno_set_current (void ) {void *kthread_cb; -XENOMAI_SYSCALL1 (__xn_sys_current, &kthread_cb); +int err; + + err =XENOMAI_SYSCALL1 (__xn_sys_current, &kthread_cb); +if (err) { +fprintf (stderr,"Xenomai: error obtaining handle for current " +"thread: %s\n" ,strerror (err)); +exit (1 ); + }pthread_setspecific (xeno_current_key, kthread_cb); }
ksrc/skins/native/Kconfig +1 -0
@@ -1,5 +1,6 @@ menuconfig XENO_SKIN_NATIVE depends on XENO_OPT_NUCLEUS + select XENO_OPT_REGISTRY if XENO_FASTSEM tristate "Native API" default y help
ksrc/skins/native/task.c +3 -5
@@ -283,11 +283,9 @@ int rt_task_create(RT_TASK *task,complete objects, so that the registry cannot return handles to half-baked objects... */ -if (name) { - err =xnthread_register (&task->thread_base, task->rname); -if (err) -xnpod_delete_thread (&task->thread_base); - } + err =xnthread_register (&task->thread_base, name ? task->rname :"" ); +if (err) +xnpod_delete_thread (&task->thread_base);return err; }
ksrc/skins/psos+/Kconfig +1 -1
@@ -2,7 +2,7 @@ menuconfig XENO_SKIN_PSOS depends on XENO_OPT_NUCLEUS select XENO_OPT_TIMING_PERIODIC tristate "pSOS+ emulator" - select XENO_OPT_REGISTRY if XENO_OPT_PERVASIVE + select XENO_OPT_REGISTRY if XENO_OPT_PERVASIVE || XENO_FASTSEM help This API skin emulates WindRiver's pSOS+ operating system.
ksrc/skins/uitron/Kconfig +1 -0
@@ -2,6 +2,7 @@ menuconfig XENO_SKIN_UITRON depends on XENO_OPT_NUCLEUS select XENO_OPT_TIMING_PERIODIC select XENO_OPT_MAP + select XENO_OPT_REGISTRY if XENO_FASTSEM tristate "uITRON API" help
ksrc/skins/uitron/task.c +10 -1
@@ -16,7 +16,6 @@* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <nucleus/registry.h> #include <nucleus/pod.h> #include <nucleus/heap.h> #include <uitron/task.h>
@@ -151,6 +150,16 @@ ER cre_tsk(ID tskid, T_CTSK *pk_ctsk)xnlock_put_irqrestore (&nklock, s); task->magic = uITRON_TASK_MAGIC; +#ifdef CONFIG_XENO_FASTSEM +/* We need an anonymous registry entry to obtain a handle for fast +mutex locking. */ +if (xnthread_register (&task->threadbase,"" )) { +xnmap_remove (ui_task_idmap, tskid); +xnpod_abort_thread (&task->threadbase); +return E_NOMEM ; + } +#endif /* CONFIG_XENO_FASTSEM */ +return E_OK ; }
ksrc/skins/rtai/Kconfig +1 -0
@@ -1,5 +1,6 @@ menuconfig XENO_SKIN_RTAI depends on XENO_OPT_NUCLEUS + select XENO_OPT_REGISTRY if XENO_FASTSEM tristate "RTAI emulator" help
ksrc/skins/rtai/task.c +10 -0
@@ -152,6 +152,16 @@ int rt_task_init(RT_TASK *task, task->magic =RTAI_TASK_MAGIC ;appendq (&__rtai_task_q, &task->link); +#ifdef CONFIG_XENO_FASTSEM +/* We need an anonymous registry entry to obtain a handle for fast +mutex locking. */ + err =xnthread_register (&task->thread_base,"" ); +if (err) { +xnpod_abort_thread (&task->thread_base); + goto unlock_and_exit; + } +#endif /* CONFIG_XENO_FASTSEM */ +/* Add a switch hook only if a signal function has been declared at least once for some created task. */
ksrc/skins/vrtx/Kconfig +1 -1
@@ -3,7 +3,7 @@ menuconfig XENO_SKIN_VRTX select XENO_OPT_TIMING_PERIODIC select XENO_OPT_MAP tristate "VRTX emulator" - select XENO_OPT_REGISTRY if XENO_OPT_PERVASIVE + select XENO_OPT_REGISTRY if XENO_OPT_PERVASIVE || CONFIG_XENO_FASTSEM help This API skin emulates Mentor Graphics's VRTX operating
ksrc/skins/vrtx/task.c +15 -2
@@ -188,12 +188,25 @@ int sc_tecreate_inner(vrtxtask_t *task,if (mode &0x10 ) bmode |=XNRRB ; - *errp =RET_OK ; -xnlock_get_irqsave (&nklock, s);appendq (&vrtx_task_q, &task->link);xnlock_put_irqrestore (&nklock, s); +#ifdef CONFIG_XENO_FASTSEM +/* We need an anonymous registry entry to obtain a handle for fast +mutex locking. */ + { +int err =xnthread_register (&task->threadbase,"" ); +if (err) { +xnpod_abort_thread (&task->threadbase); + *errp =ER_MEM ; +return -1 ; + } + } +#endif /* CONFIG_XENO_FASTSEM */ + + *errp =RET_OK ; +xnpod_start_thread (&task->threadbase, bmode,0 ,XNPOD_ALL_CPUS , &vrtxtask_trampoline, task);
ksrc/skins/vxworks/Kconfig +1 -1
@@ -2,7 +2,7 @@ menuconfig XENO_SKIN_VXWORKS depends on XENO_OPT_NUCLEUS select XENO_OPT_TIMING_PERIODIC tristate "VxWorks emulator" - select XENO_OPT_REGISTRY if XENO_OPT_PERVASIVE + select XENO_OPT_REGISTRY if XENO_OPT_PERVASIVE || XENO_FASTSEM help This API skin emulates WindRiver's VxWorks operating system.
ksrc/skins/rtdm/drvlib.c +8 -0
@@ -145,6 +145,14 @@ int rtdm_task_init(rtdm_task_t *task, coif (err)return err; +#ifdef CONFIG_XENO_FASTSEM +/* We need an anonymous registry entry to obtain a handle for fast +mutex locking. */ + err =xnthread_register (task,"" ); +if (err) + goto cleanup_out; +#endif /* CONFIG_XENO_FASTSEM */ +if (period >0 ) { err =xnpod_set_thread_periodic (task,XN_INFINITE , xntbase_ns2ticks_ceil
Re: [Xenomai-core] [PATCH 02/12] Handle-based xeno_get_current service
Jan Kiszka wrote:
ok for me.
Signature · 1 line
Gilles.
PATCH 3/12 Remove xnarch_atomic_intptr
In reply to Jan KiszkaNo more users, no more use cases in sight, let's get rid of it.
--- include/asm-arm/atomic.h | 3 --- include/asm-blackfin/atomic.h | 2 -- include/asm-generic/Makefile.am | 2 +- include/asm-generic/Makefile.in | 2 +- include/asm-generic/atomic.h | 24 ------------------------ include/asm-ia64/atomic.h | 2 -- include/asm-powerpc/atomic.h | 2 -- include/asm-x86/atomic.h | 2 -- 8 files changed, 2 insertions(+), 37 deletions(-)
include/asm-arm/atomic.h +0 -3
@@ -412,9 +412,6 @@ static __inline__ void xnarch_atomic_cletypedef unsigned long atomic_flags_t ; -/* Add support for xnarch_atomic_intptr_t */ -#include <asm-generic/xenomai/atomic.h> -#endif /* !_XENO_ASM_ARM_ATOMIC_H */ // vim: ts=4 et sw=4 sts=4
include/asm-blackfin/atomic.h +0 -2
@@ -42,8 +42,6 @@typedef atomic_t atomic_counter_t ;typedef atomic_t xnarch_atomic_t ; -#include <asm-generic/xenomai/atomic.h> -#else /* !__KERNEL__ */ #include <asm/xenomai/syscall.h>
include/asm-generic/Makefile.am +1 -1
@@ -1,5 +1,5 @@ includesubdir = $(includedir)/asm-generic -includesub_HEADERS = arith.h atomic.h features.h hal.h syscall.h system.h wrappers.h +includesub_HEADERS = arith.h features.h hal.h syscall.h system.h wrappers.h SUBDIRS = bits
include/asm-generic/Makefile.in +1 -1
@@ -226,7 +226,7 @@ target_vendor = @target_vendor@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ includesubdir = $(includedir)/asm-generic -includesub_HEADERS = arith.h atomic.h features.h hal.h syscall.h system.h wrappers.h +includesub_HEADERS = arith.h features.h hal.h syscall.h system.h wrappers.h SUBDIRS = bits all: all-recursive
include/asm-generic/atomic.h deleted +0 -24
@@ -1,24 +0,0 @@ -#ifndef _XENO_ASM_GENERIC_ATOMIC_H -#define _XENO_ASM_GENERIC_ATOMIC_H - -typedef xnarch_atomic_t xnarch_atomic_intptr_t ; - -static inline void *xnarch_atomic_intptr_get (xnarch_atomic_intptr_t *l) -{ -xnarch_atomic_t *v = (xnarch_atomic_t *)l; - -return (void *)xnarch_atomic_get (v); -} - -static inline void xnarch_atomic_intptr_set (xnarch_atomic_intptr_t *l,void *i) -{ -xnarch_atomic_t *v = (xnarch_atomic_t *)l; - -xnarch_atomic_set (v, (long )i); -} - -#define xnarch_atomic_intptr_cmpxchg (l, old, newval) \ - (void *)(xnarch_atomic_cmpxchg((xnarch_atomic_t *)(l), \ - (long)(old), (long)(newval))) - -#endif /* _XENO_ASM_GENERIC_ATOMIC_H */
include/asm-ia64/atomic.h +0 -2
@@ -71,8 +71,6 @@ static inline void atomic_clear_mask(uns#define xnarch_atomic_cmpxchg (pcounter,old,new) \ cmpxchg((&(pcounter)->counter),(old),(new)) -#include <asm-generic/xenomai/atomic.h> -#else /* !__KERNEL__ */ #include <asm/xenomai/features.h>
include/asm-powerpc/atomic.h +0 -2
@@ -262,6 +262,4 @@ xnarch_atomic_cmpxchg(xnarch_atomic_t *ptypedef unsigned long atomic_flags_t ; -#include <asm-generic/xenomai/atomic.h> -#endif /* !_XENO_ASM_POWERPC_ATOMIC_H */
include/asm-x86/atomic.h +0 -2
@@ -136,6 +136,4 @@ xnarch_atomic_cmpxchg(xnarch_atomic_t *v#endif /* __KERNEL__ */ -#include <asm-generic/xenomai/atomic.h> -#endif /* !_XENO_ASM_X86_ATOMIC_64_H */
Re: [Xenomai-core] [PATCH 03/12] Remove xnarch_atomic_intptr
Jan Kiszka wrote:
Ok.
Signature · 1 line
Gilles.
PATCH 4/12 Spread xeno_set_current under all skins
In reply to Jan KiszkaSpread xeno_set_current under all user space supporting skins.
--- src/skins/native/task.c | 13 +++++++++++-- src/skins/psos+/task.c | 18 ++++++++++++++---- src/skins/uitron/task.c | 18 +++++++++++++----- src/skins/vrtx/task.c | 3 +++ src/skins/vxworks/taskLib.c | 3 +++ 5 files changed, 44 insertions(+), 11 deletions(-)
src/skins/native/task.c +11 -2
@@ -26,6 +26,7 @@#include <limits.h> #include <native/syscall.h> #include <native/task.h> +#include <asm-generic/bits/current.h> #include "wrappers.h" extern pthread_key_t __native_tskey;
@@ -88,6 +89,8 @@ static void *rt_task_trampoline(void *coif (err) goto fail; +xeno_set_current (); +/* Wait on the barrier for the task to be started. The barrier could be released in order to process Linux signals while the Xenomai shadow is still dormant; in such a case, resume wait. */
@@ -169,6 +172,7 @@ int rt_task_shadow(RT_TASK *task, conststruct sched_param param;struct rt_arg_bulk bulk;RT_TASK task_desc; +int err;if (task ==NULL ) task = &task_desc;/* Discarded. */
@@ -191,8 +195,13 @@ int rt_task_shadow(RT_TASK *task, const bulk.a4 = (u_long )mode; bulk.a5 = (u_long )pthread_self (); -return XENOMAI_SKINCALL2 (__native_muxid, __native_task_create, &bulk, -NULL ); + err =XENOMAI_SKINCALL2 (__native_muxid, __native_task_create, &bulk, +NULL ); + +if (!err) +xeno_set_current (); + +return err; }int rt_task_bind (RT_TASK *task,const char *name,RTIME timeout)
src/skins/psos+/task.c +14 -4
@@ -26,6 +26,7 @@#include <memory.h> #include <string.h> #include <psos+/psos.h> +#include <asm-generic/bits/current.h> extern int __psos_muxid;
@@ -89,6 +90,8 @@ static void *psos_task_trampoline(void *if (err) goto fail; +xeno_set_current (); +/* Wait on the barrier for the task to be started. The barrier could be released in order to process Linux signals while the Xenomai shadow is still dormant; in such a case, resume wait. */
@@ -173,14 +176,21 @@ u_long t_shadow(const char *name, /* Xenu_long flags, u_long *tid_r) { + int err; +pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS ,NULL ); old_sigharden_handler =signal (SIGHARDEN , &psos_task_sigharden); -return XENOMAI_SKINCALL5 (__psos_muxid, - __psos_t_create, - name, prio, flags, - tid_r,NULL ); + err =XENOMAI_SKINCALL5 (__psos_muxid, + __psos_t_create, + name, prio, flags, + tid_r,NULL ); + +if (!err) +xeno_set_current (); + +return err; } u_long t_start(u_long tid,
src/skins/uitron/task.c +13 -5
@@ -25,6 +25,7 @@#include <limits.h> #include <asm/xenomai/system.h> #include <uitron/uitron.h> +#include <asm-generic/bits/current.h> extern int __uitron_muxid;
@@ -89,6 +90,8 @@ static void *uitron_task_trampoline(voidif (err) goto fail; +xeno_set_current (); +/* iargs->pk_ctsk might not be valid anymore, after our parent was released from the completion sync, so do not dereference this pointer. */
@@ -150,7 +153,7 @@ ER cre_tsk(ID tskid, T_CTSK *pk_ctsk)ER shd_tsk (ID tskid,T_CTSK *pk_ctsk)/* Xenomai extension. */ {struct sched_param param; -int policy; +int policy, err;/* Make sure the POSIX library caches the right priority. */ policy =uitron_task_set_posix_priority (pk_ctsk->itskpri, ¶m);
@@ -160,10 +163,15 @@ ER shd_tsk(ID tskid, T_CTSK *pk_ctsk) /* old_sigharden_handler =signal (SIGHARDEN , &uitron_task_sigharden); -return XENOMAI_SKINCALL3 (__uitron_muxid, - __uitron_cre_tsk, - tskid, pk_ctsk, -NULL ); + err =XENOMAI_SKINCALL3 (__uitron_muxid, + __uitron_cre_tsk, + tskid, pk_ctsk, +NULL ); + +if (!err) +xeno_set_current (); + +return err; }ER del_tsk (ID tskid)
src/skins/vrtx/task.c +3 -0
@@ -27,6 +27,7 @@#include <errno.h> #include <limits.h> #include <vrtx/vrtx.h> +#include <asm-generic/bits/current.h> extern pthread_key_t __vrtx_tskey;
@@ -116,6 +117,8 @@ static void *vrtx_task_trampoline(void *if (err) goto fail; +xeno_set_current (); +/* Wait on the barrier for the task to be started. The barrier could be released in order to process Linux signals while the Xenomai shadow is still dormant; in such a case, resume wait. */
src/skins/vxworks/taskLib.c +3 -0
@@ -27,6 +27,7 @@#include <errno.h> #include <limits.h> #include <vxworks/vxworks.h> +#include <asm-generic/bits/current.h> #include "wrappers.h" extern pthread_key_t __vxworks_tskey;
@@ -117,6 +118,8 @@ static void *wind_task_trampoline(void *if (err) goto fail; +xeno_set_current (); +/* Wait on the barrier for the task to be started. The barrier could be released in order to process Linux signals while the Xenomai shadow is still dormant; in such a case, resume wait. */
Re: [Xenomai-core] [PATCH 04/12] Spread xeno_set_current under all skins
Jan Kiszka wrote:
Ok.
Signature · 1 line
Gilles.
PATCH 5/12 Factor out xnsynch_acquire/release
In reply to Jan KiszkaThis patch addresses the increasing divergence of owner-tracking vs. owner-less xnsynch objects.
Services dealing with the former will include the new, lockless xnsynch prologue for optimizing its fastpath. At the the same time, this additional code should not disturb too much in those cases where we do not track ownership (condition variables, events, semaphores etc.). Moreover, I noticed that some of the existing code assumes XNSYNCH_NOPIP means no ownership, which is surely not true. The already visible effect is that lock stealing is needlessly restricted to XNSYNCH_PIP.
Going through the API, I dug out three diverging services and replaced them with two new ones:
Owner-less xnsynch objects:
- xnsynch_sleep_on
- xnsynch_wakeup_one_sleeper
- xnsynch_wakeup_this_sleeper
Owner-tracking xnsynch objects:
- xnsynch_acquire
- xnsynch_release
The latter type of objects are marked with the new flag XNSYNCH_OWNER, used only for debugging and code documentation purposes in the current implementation.
--- include/nucleus/synch.h | 16 + include/rtdm/rtdm_driver.h | 2 ksrc/nucleus/synch.c | 418 +++++++++++++++++++++++++++++--------------- ksrc/skins/native/cond.c | 2 ksrc/skins/native/mutex.c | 7 ksrc/skins/native/task.c | 5 ksrc/skins/posix/cond.c | 2 ksrc/skins/posix/mutex.c | 10 - ksrc/skins/posix/mutex.h | 6 ksrc/skins/rtai/sem.c | 10 - ksrc/skins/rtdm/drvlib.c | 15 - ksrc/skins/vrtx/mx.c | 6 ksrc/skins/vxworks/semLib.c | 6 13 files changed, 326 insertions(+), 179 deletions(-)
include/nucleus/synch.h +11 -5
@@ -30,10 +30,11 @@#define XNSYNCH_NOPIP 0x0#define XNSYNCH_PIP 0x2#define XNSYNCH_DREORD 0x4 +#define XNSYNCH_OWNER 0x8#if defined(__KERNEL__) || defined(__XENO_SIM__) -#define XNSYNCH_CLAIMED 0x8/* Claimed by other thread(s) w/ PIP */ +#define XNSYNCH_CLAIMED 0x10/* Claimed by other thread(s) w/ PIP */ /* Spare flags usable by upper interfaces */ #define XNSYNCH_SPARE0 0x01000000
@@ -105,13 +106,18 @@ void xnsynch_sleep_on(xnsynch_t *synch,struct xnthread *xnsynch_wakeup_one_sleeper (xnsynch_t *synch); -struct xnthread *xnsynch_peek_pendq (xnsynch_t *synch); -xnpholder_t *xnsynch_wakeup_this_sleeper (xnsynch_t *synch,xnpholder_t *holder); -int xnsynch_flush (xnsynch_t *synch, -xnflags_t reason); +void xnsynch_acquire (xnsynch_t *synch, +xnticks_t timeout, +xntmode_t timeout_mode); + +struct xnthread *xnsynch_release (xnsynch_t *synch); + +struct xnthread *xnsynch_peek_pendq (xnsynch_t *synch); + +int xnsynch_flush (xnsynch_t *synch,xnflags_t reason);void xnsynch_release_all_ownerships (struct xnthread *thread);
ksrc/nucleus/synch.c +278 -140
527 lines not on this page · raw message
include/rtdm/rtdm_driver.h +1 -1
@@ -1134,7 +1134,7 @@ static inline void rtdm_mutex_unlock(rtdtrace_mark (xn_rtdm_mutex_unlock,"mutex %p" , mutex); -if (unlikely (xnsynch_wakeup_one_sleeper (&mutex->synch_base) !=NULL )) +if (unlikely (xnsynch_release (&mutex->synch_base) !=NULL ))xnpod_schedule (); }
ksrc/skins/native/cond.c +1 -1
@@ -421,7 +421,7 @@ int rt_cond_wait_inner(RT_COND *cond, RT mutex->lockcnt =0 ; -if (xnsynch_wakeup_one_sleeper (&mutex->synch_base)) { +if (xnsynch_release (&mutex->synch_base)) { mutex->lockcnt =1 ;/* Scheduling deferred */ }
ksrc/skins/native/mutex.c +4 -3
@@ -170,7 +170,8 @@ int rt_mutex_create(RT_MUTEX *mutex, conif (xnpod_asynch_p ())return -EPERM ; -xnsynch_init (&mutex->synch_base,XNSYNCH_PRIO |XNSYNCH_PIP ); +xnsynch_init (&mutex->synch_base, +XNSYNCH_PRIO |XNSYNCH_PIP |XNSYNCH_OWNER ); mutex->handle =0 ;/* i.e. (still) unregistered mutex. */ mutex->magic =XENO_MUTEX_MAGIC ; mutex->lockcnt =0 ;
@@ -309,7 +310,7 @@ int rt_mutex_acquire_inner(RT_MUTEX *mut goto unlock_and_exit; } -xnsynch_sleep_on (&mutex->synch_base, timeout, timeout_mode); +xnsynch_acquire (&mutex->synch_base, timeout, timeout_mode);if (xnthread_test_info (thread,XNRMID )) err = -EIDRM ;/* Mutex deleted while pending. */
@@ -523,7 +524,7 @@ int rt_mutex_release(RT_MUTEX *mutex)if (--mutex->lockcnt >0 ) goto unlock_and_exit; -if (xnsynch_wakeup_one_sleeper (&mutex->synch_base)) { +if (xnsynch_release (&mutex->synch_base)) { mutex->lockcnt =1 ;xnpod_schedule (); }
ksrc/skins/native/task.c +3 -2
@@ -269,7 +269,8 @@ int rt_task_create(RT_TASK *task,#ifdef CONFIG_XENO_OPT_NATIVE_MPS xnsynch_init (&task->mrecv,XNSYNCH_FIFO ); -xnsynch_init (&task->msendq,XNSYNCH_PRIO |XNSYNCH_PIP ); +xnsynch_init (&task->msendq, +XNSYNCH_PRIO |XNSYNCH_PIP |XNSYNCH_OWNER );xnsynch_set_owner (&task->msendq, &task->thread_base); task->flowgen =0 ;#endif /* CONFIG_XENO_OPT_NATIVE_MPS */
@@ -1773,7 +1774,7 @@ ssize_t rt_task_send(RT_TASK *task,client in the case required by the priority inheritance protocol (i.e. prio(client) > prio(server)). */ -xnsynch_sleep_on (&task->msendq, timeout,XN_RELATIVE ); +xnsynch_acquire (&task->msendq, timeout,XN_RELATIVE );/* At this point, the server task might have exited right * after having replied to us, so do not make optimistic
ksrc/skins/posix/cond.c +1 -1
@@ -240,7 +240,7 @@ static inline int mutex_save_count(xnthr xnthread_handle(cur)))return 0 ; - owner =xnsynch_wakeup_one_sleeper (&mutex->synchbase); + owner =xnsynch_release (&mutex->synchbase);xnarch_atomic_set (mutex->owner,set_claimed (xnthread_handle (owner),xnsynch_nsleepers (&mutex->synchbase)));
ksrc/skins/posix/mutex.c +5 -5
@@ -85,7 +85,7 @@ int pse51_mutex_init_internal(struct __sxnarch_atomic_t *ownerp, const pthread_mutexattr_t *attr) { - xnflags_t synch_flags = XNSYNCH_PRIO | XNSYNCH_NOPIP; + xnflags_t synch_flags = XNSYNCH_PRIO | XNSYNCH_OWNER;struct xnsys_ppd *sys_ppd;pse51_kqueues_t *kq;spl_t s;
@@ -307,11 +307,11 @@ int pse51_mutex_timedlock_break(struct _for (;;) { ++mutex->sleepers;if (timed) -xnsynch_sleep_on (&mutex->synchbase, - abs_to,XN_REALTIME ); +xnsynch_acquire (&mutex->synchbase, + abs_to,XN_REALTIME );else -xnsynch_sleep_on (&mutex->synchbase, -XN_INFINITE ,XN_RELATIVE ); +xnsynch_acquire (&mutex->synchbase, +XN_INFINITE ,XN_RELATIVE ); --mutex->sleepers;if (xnthread_test_info (cur,XNBREAK )) {
ksrc/skins/posix/mutex.h +3 -3
@@ -170,9 +170,9 @@ static inline int pse51_mutex_timedlock_xnsynch_set_owner (&mutex->synchbase, owner); ++mutex->sleepers;if (timed) -xnsynch_sleep_on (&mutex->synchbase, abs_to,XN_REALTIME ); +xnsynch_acquire (&mutex->synchbase, abs_to,XN_REALTIME );else -xnsynch_sleep_on (&mutex->synchbase,XN_INFINITE ,XN_RELATIVE ); +xnsynch_acquire (&mutex->synchbase,XN_INFINITE ,XN_RELATIVE ); --mutex->sleepers;if (xnthread_test_info (cur,XNBREAK )) {
@@ -216,7 +216,7 @@ static inline void pse51_mutex_unlock_inreturn ;xnlock_get_irqsave (&nklock, s); - owner =xnsynch_wakeup_one_sleeper (&mutex->synchbase); + owner =xnsynch_release (&mutex->synchbase); ownerh =set_claimed (xnthread_handle (owner), mutex->sleepers);xnarch_atomic_set (mutex->owner, ownerh);if (owner)
ksrc/skins/rtai/sem.c +5 -5
@@ -28,7 +28,7 @@ void rt_typed_sem_init(SEM * sem, int vaint mode =XNSYNCH_PRIO ;if ((type &RES_SEM ) ==RES_SEM ) { - mode |=XNSYNCH_PIP ; + mode |=XNSYNCH_PIP |XNSYNCH_OWNER ; value =0 ;/* We will use this as a lock count. */ }else {if ((type &BIN_SEM ) && value >1 )
@@ -98,7 +98,7 @@ int rt_sem_signal(SEM * sem) goto unlock_and_exit; sem->owner = -thread2rtask (xnsynch_wakeup_one_sleeper (&sem->synch_base)); +thread2rtask (xnsynch_release (&sem->synch_base));if (sem->owner !=NULL )xnpod_schedule ();
@@ -141,12 +141,12 @@ int rt_sem_wait(SEM * sem) err = ++sem->count; goto unlock_and_exit; } +xnsynch_acquire (&sem->synch_base,XN_INFINITE ,XN_RELATIVE ); }else if (sem->count >0 ) { err = sem->count--; goto unlock_and_exit; - } - -xnsynch_sleep_on (&sem->synch_base,XN_INFINITE ,XN_RELATIVE ); + }else +xnsynch_sleep_on (&sem->synch_base,XN_INFINITE ,XN_RELATIVE );if (xnthread_test_info (&task->thread_base,XNRMID )) err =SEM_ERR ;/* Semaphore deleted while pending. */
ksrc/skins/rtdm/drvlib.c +8 -7
@@ -1390,7 +1390,8 @@ void rtdm_mutex_init(rtdm_mutex_t *mutex/* Make atomic for re-initialisation support */ xnlock_get_irqsave (&nklock, s); -xnsynch_init (&mutex->synch_base,XNSYNCH_PRIO |XNSYNCH_PIP ); +xnsynch_init (&mutex->synch_base, +XNSYNCH_PRIO |XNSYNCH_PIP |XNSYNCH_OWNER );xnlock_put_irqrestore (&nklock, s); }
@@ -1534,14 +1535,14 @@ int rtdm_mutex_timedlock(rtdm_mutex_t *m restart:if (timeout_seq && (timeout >0 )) {/* timeout sequence */ -xnsynch_sleep_on (&mutex->synch_base, *timeout_seq, -XN_ABSOLUTE ); +xnsynch_acquire (&mutex->synch_base, *timeout_seq, +XN_ABSOLUTE ); }else {/* infinite or relative timeout */ -xnsynch_sleep_on (&mutex->synch_base, -xntbase_ns2ticks_ceil - (xnthread_time_base (curr_thread), - timeout),XN_RELATIVE ); +xnsynch_acquire (&mutex->synch_base, +xntbase_ns2ticks_ceil + (xnthread_time_base (curr_thread), + timeout),XN_RELATIVE ); } if (unlikely(xnthread_test_info(curr_thread,
ksrc/skins/vrtx/mx.c +3 -3
@@ -161,7 +161,7 @@ int sc_mcreate(unsigned int opt, int *erinith (&mx->link); mx->mid = mid; mx->owner =NULL ; -xnsynch_init (&mx->synchbase, bflags |XNSYNCH_DREORD ); +xnsynch_init (&mx->synchbase, bflags |XNSYNCH_DREORD |XNSYNCH_OWNER );xnlock_get_irqsave (&nklock, s);appendq (&vrtx_mx_q, &mx->link);
@@ -192,7 +192,7 @@ void sc_mpost(int mid, int *errp) }/* Undefined behaviour if the poster does not own the mutex. */ - mx->owner =xnsynch_wakeup_one_sleeper (&mx->synchbase); + mx->owner =xnsynch_release (&mx->synchbase); *errp =RET_OK ;
@@ -267,7 +267,7 @@ void sc_mpend(int mid, unsigned long timif (timeout) task->vrtxtcb.TCBSTAT |=TBSDELAY ; -xnsynch_sleep_on (&mx->synchbase, timeout,XN_RELATIVE ); +xnsynch_acquire (&mx->synchbase, timeout,XN_RELATIVE );if (xnthread_test_info (&task->threadbase,XNBREAK )) *errp = -EINTR ;
ksrc/skins/vxworks/semLib.c +3 -3
@@ -138,7 +138,7 @@ SEM_ID semCCreate(int flags, int count)SEM_ID semMCreate (int flags) { -int bflags =0 ; +int bflags =XNSYNCH_OWNER ;error_check (flags & ~WIND_SEMM_OPTION_MASK , S_semLib_INVALID_QUEUE_TYPE, return 0);
@@ -346,7 +346,7 @@ static STATUS semm_take(wind_sem_t *sem,error_check (to ==XN_NONBLOCK , S_objLib_OBJ_UNAVAILABLE, return ERROR); -xnsynch_sleep_on (&sem->synchbase, to,XN_RELATIVE ); +xnsynch_acquire (&sem->synchbase, to,XN_RELATIVE );error_check (xnthread_test_info (cur,XNBREAK ), -EINTR, return ERROR);
@@ -385,7 +385,7 @@ static STATUS semm_give(wind_sem_t *sem)if (--sem->count >0 )return OK ; -if (xnsynch_wakeup_one_sleeper (&sem->synchbase)) { +if (xnsynch_release (&sem->synchbase)) { sem->count =1 ; resched =1 ; }
Re: [Xenomai-core] [PATCH 05/12] Factor out xnsynch_acquire/release
Jan Kiszka wrote:
Ok.
Signature · 1 line
Gilles.
PATCH 6/12 Lockless fast path for xnsynch_acquire/release
In reply to Jan KiszkaThis patch adds optional lockless fast paths to xnsynch_acquire and xnsynch_release. Those paths are considered if CONFIG_XENO_FASTSYNC is defined and the owner-tracking xnsynch object is given a non-NULL reference to an atomic fastlock variable on initialization. This allows for a smooth migration of existing mutex implementations in Xenomai skins to a fast xnsynch scheme.
--- configure.in | 16 ++-- include/asm-generic/bits/bind.h | 16 ++-- include/asm-generic/features.h | 24 +++--- include/nucleus/synch.h | 54 ++++++++++++++- ksrc/arch/arm/Kconfig | 2 ksrc/arch/powerpc/Kconfig | 2 ksrc/arch/x86/Kconfig | 2 ksrc/drivers/testing/switchtest.c | 2 ksrc/nucleus/pipe.c | 2 ksrc/nucleus/registry.c | 4 - ksrc/nucleus/select.c | 2 ksrc/nucleus/synch.c | 132 ++++++++++++++++++++++++++++++++------ ksrc/skins/native/Kconfig | 2 ksrc/skins/native/alarm.c | 2 ksrc/skins/native/buffer.c | 4 - ksrc/skins/native/cond.c | 2 ksrc/skins/native/event.c | 2 ksrc/skins/native/heap.c | 2 ksrc/skins/native/intr.c | 2 ksrc/skins/native/mutex.c | 2 ksrc/skins/native/queue.c | 2 ksrc/skins/native/sem.c | 2 ksrc/skins/native/task.c | 6 - ksrc/skins/posix/Kconfig | 2 ksrc/skins/posix/cb_lock.h | 6 - ksrc/skins/posix/cond.c | 18 ++--- ksrc/skins/posix/intr.c | 2 ksrc/skins/posix/mq.c | 4 - ksrc/skins/posix/mutex.c | 12 +-- ksrc/skins/posix/mutex.h | 4 - ksrc/skins/posix/sem.c | 2 ksrc/skins/posix/syscall.c | 20 ++--- ksrc/skins/posix/thread.c | 6 - ksrc/skins/psos+/Kconfig | 2 ksrc/skins/psos+/event.c | 2 ksrc/skins/psos+/queue.c | 2 ksrc/skins/psos+/rn.c | 2 ksrc/skins/psos+/sem.c | 2 ksrc/skins/rtai/Kconfig | 2 ksrc/skins/rtai/sem.c | 2 ksrc/skins/rtai/task.c | 4 - ksrc/skins/rtdm/drvlib.c | 10 +- ksrc/skins/uitron/Kconfig | 2 ksrc/skins/uitron/flag.c | 2 ksrc/skins/uitron/mbx.c | 3 ksrc/skins/uitron/sem.c | 3 ksrc/skins/uitron/task.c | 4 - ksrc/skins/vrtx/Kconfig | 2 ksrc/skins/vrtx/event.c | 2 ksrc/skins/vrtx/mb.c | 2 ksrc/skins/vrtx/mx.c | 3 ksrc/skins/vrtx/queue.c | 2 ksrc/skins/vrtx/sem.c | 2 ksrc/skins/vxworks/Kconfig | 2 ksrc/skins/vxworks/module.c | 2 ksrc/skins/vxworks/msgQLib.c | 2 ksrc/skins/vxworks/semLib.c | 2 ksrc/skins/vxworks/syscall.c | 2 ksrc/skins/vxworks/taskLib.c | 2 src/skins/posix/mutex.c | 42 ++++++------ 60 files changed, 309 insertions(+), 162 deletions(-)
configure.in +8 -8
@@ -59,27 +59,27 @@ AM_PROG_LEX AC_MSG_CHECKING([for target architecture]) -CONFIG_XENO_FASTSEM= +CONFIG_XENO_FASTSYNCH= case "$host" in i*86*-*) XENO_TARGET_ARCH=x86 XENO_LINUX_ARCH=i386 XENO_LINUX_INSTALL_TARGET=install - CONFIG_XENO_FASTSEM=y + CONFIG_XENO_FASTSYNCH=y ;; powerpc-*|ppc-*) XENO_TARGET_ARCH=powerpc XENO_LINUX_ARCH=ppc XENO_LINUX_INSTALL_TARGET=install_image XENO_LINUX_IMAGE=arch/ppc/boot/images/zImage.elf - CONFIG_XENO_FASTSEM=y + CONFIG_XENO_FASTSYNCH=y ;; powerpc64-*|ppc64-*) XENO_TARGET_ARCH=powerpc XENO_LINUX_ARCH=ppc64 XENO_LINUX_INSTALL_TARGET=install_image XENO_LINUX_IMAGE=arch/ppc64/boot/images/zImage - CONFIG_XENO_FASTSEM=y + CONFIG_XENO_FASTSYNCH=y ;; ia64-*) XENO_TARGET_ARCH=ia64
@@ -96,14 +96,14 @@ case "$host" in XENO_LINUX_ARCH=arm XENO_LINUX_INSTALL_TARGET=install_image XENO_LINUX_IMAGE=arch/arm/boot/zImage - # We set CONFIG_XENO_FASTSEM later, when we know what architecture we + # We set CONFIG_XENO_FASTSYNCH later, when we know what architecture we # are running ;; x86_64-*|amd64-*) XENO_TARGET_ARCH=x86 XENO_LINUX_ARCH=x86_64 XENO_LINUX_INSTALL_TARGET=install - CONFIG_XENO_FASTSEM=y + CONFIG_XENO_FASTSYNCH=y ;; *) echo "" echo "*******************************************"
@@ -288,7 +288,7 @@ user-space]), AC_MSG_RESULT(${CONFIG_XENO_ARM_EABI:-no}) if test $CONFIG_XENO_ARM_ARCH -ge 6 || test x$CONFIG_SMP != xy; then - CONFIG_XENO_FASTSEM=y + CONFIG_XENO_FASTSYNCH=y fi fi
@@ -570,7 +570,7 @@ dnl test x$CONFIG_XENO_X86_SEP = xy && AC_DEFINE(CONFIG_XENO_X86_SEP,1,[config]) test x$CONFIG_SMP = xy && AC_DEFINE(CONFIG_SMP,1,[config]) -test x$CONFIG_XENO_FASTSEM = xy && AC_DEFINE(CONFIG_XENO_FASTSEM,1,[config]) +test x$CONFIG_XENO_FASTSYNCH = xy && AC_DEFINE(CONFIG_XENO_FASTSYNCH,1,[config]) test x$CONFIG_X86_TSC = xy && AC_DEFINE(CONFIG_X86_TSC,1,[config]) test -n "$CONFIG_XENO_ARM_ARCH" && AC_DEFINE_UNQUOTED(CONFIG_XENO_ARM_ARCH,$CONFIG_XENO_ARM_ARCH,[config])
include/asm-generic/bits/bind.h +8 -8
@@ -43,14 +43,14 @@ static void init_current_key(void) } } -#ifdef CONFIG_XENO_FASTSEM +#ifdef CONFIG_XENO_FASTSYNCH __attribute__ ((weak))unsigned long xeno_sem_heap[2 ] = {0 ,0 }; -#endif /* CONFIG_XENO_FASTSEM */ +#endif /* CONFIG_XENO_FASTSYNCH */ void xeno_handle_mlock_alert (int sig); -#ifdef CONFIG_XENO_FASTSEM +#ifdef CONFIG_XENO_FASTSYNCH static void *map_sem_heap(unsigned shared) { struct heap_info {
@@ -104,7 +104,7 @@ static void unmap_sem_heap(unsigned long munmap((void *) heap_addr, hinfo.size); } -#endif /* CONFIG_XENO_FASTSEM */ +#endif /* CONFIG_XENO_FASTSYNCH */ void __attribute__((weak))xeno_sigill_handler (int sig) {
@@ -177,7 +177,7 @@ xeno_bind_skin(unsigned skin_magic, conspthread_once (&xeno_init_current_key_once, &init_current_key); -#ifdef CONFIG_XENO_FASTSEM +#ifdef CONFIG_XENO_FASTSYNCH /* In case we forked, we need to map the new local semaphore heap */ if (xeno_sem_heap[0 ])unmap_sem_heap (xeno_sem_heap[0 ],0 );
@@ -196,7 +196,7 @@ xeno_bind_skin(unsigned skin_magic, cons exit(EXIT_FAILURE); } } -#endif /* CONFIG_XENO_FASTSEM */ +#endif /* CONFIG_XENO_FASTSYNCH */ return muxid; }
@@ -253,7 +253,7 @@ xeno_bind_skin_opt(unsigned skin_magic,pthread_once (&xeno_init_current_key_once, &init_current_key); -#ifdef CONFIG_XENO_FASTSEM +#ifdef CONFIG_XENO_FASTSYNCH /* In case we forked, we need to map the new local semaphore heap */ if (xeno_sem_heap[0 ])unmap_sem_heap (xeno_sem_heap[0 ],0 );
@@ -272,7 +272,7 @@ xeno_bind_skin_opt(unsigned skin_magic, exit(EXIT_FAILURE); } } -#endif /* CONFIG_XENO_FASTSEM */ +#endif /* CONFIG_XENO_FASTSYNCH */ return muxid; }
include/asm-generic/features.h +12 -12
@@ -25,9 +25,9 @@#include <xeno_config.h> #endif /* __KERNEL__ */ -#define __xn_feat_smp 0x80000000 -#define __xn_feat_fastsem 0x40000000 -#define __xn_feat_nofastsem 0x20000000 +#define __xn_feat_smp 0x80000000 +#define __xn_feat_fastsynch 0x40000000 +#define __xn_feat_nofastsynch 0x20000000#ifdef CONFIG_SMP #define __xn_feat_smp_mask __xn_feat_smp
@@ -35,25 +35,25 @@#define __xn_feat_smp_mask 0#endif -#ifdef CONFIG_XENO_FASTSEM -#define __xn_feat_fastsem_mask __xn_feat_fastsem +#ifdef CONFIG_XENO_FASTSYNCH +#define __xn_feat_fastsynch_mask __xn_feat_fastsynch#else -#define __xn_feat_fastsem_mask __xn_feat_nofastsem +#define __xn_feat_fastsynch_mask __xn_feat_nofastsynch#endif -#define __xn_feat_generic_mask (__xn_feat_smp_mask | __xn_feat_fastsem_mask) +#define __xn_feat_generic_mask (__xn_feat_smp_mask | __xn_feat_fastsynch_mask) -#define __xn_feat_generic_man_mask (__xn_feat_fastsem | __xn_feat_nofastsem) +#define __xn_feat_generic_man_mask (__xn_feat_fastsynch | __xn_feat_nofastsynch)static inline const char *get_generic_feature_label (unsigned feature) {switch (feature) {case __xn_feat_smp:return "smp" ; -case __xn_feat_fastsem: -return "fastsem" ; -case __xn_feat_nofastsem: -return "nofastsem" ; +case __xn_feat_fastsynch: +return "fastsynch" ; +case __xn_feat_nofastsynch: +return "nofastsynch" ;default :return 0 ; }
include/nucleus/synch.h +52 -2
80 lines not on this page · raw message
ksrc/arch/arm/Kconfig +1 -1
@@ -2,7 +2,7 @@ config XENO_GENERIC_STACKPOOL bool default y -config XENO_FASTSEM +config XENO_FASTSYNCH bool default y if (CPU_32v3 || CPU_32v4T || CPU_32v5) && !SMP || CPU_32v6 || CPU_32v7
ksrc/arch/powerpc/Kconfig +1 -1
@@ -2,7 +2,7 @@ config XENO_GENERIC_STACKPOOL bool default y -config XENO_FASTSEM +config XENO_FASTSYNCH bool default y
ksrc/arch/x86/Kconfig +1 -1
@@ -2,7 +2,7 @@ config XENO_GENERIC_STACKPOOL bool default y -config XENO_FASTSEM +config XENO_FASTSYNCH bool default y
ksrc/skins/native/Kconfig +1 -1
@@ -1,6 +1,6 @@ menuconfig XENO_SKIN_NATIVE depends on XENO_OPT_NUCLEUS - select XENO_OPT_REGISTRY if XENO_FASTSEM + select XENO_OPT_REGISTRY if XENO_FASTSYNCH tristate "Native API" default y help
ksrc/skins/posix/Kconfig +1 -1
@@ -1,6 +1,6 @@ menuconfig XENO_SKIN_POSIX depends on XENO_OPT_NUCLEUS - select XENO_OPT_REGISTRY if XENO_FASTSEM + select XENO_OPT_REGISTRY if XENO_FASTSYNCH tristate "POSIX API" default y help
ksrc/skins/posix/cb_lock.h +3 -3
@@ -20,7 +20,7 @@ typedef void xnthread_t; __tmp; \ }) -#ifdef CONFIG_XENO_FASTSEM +#ifdef CONFIG_XENO_FASTSYNCH static __inline__int __cb_try_read_lock (xnarch_atomic_t *lock) {
@@ -68,7 +68,7 @@ static __inline__ void __cb_write_unlock#define cb_try_write_lock (lock, flags) __cb_try_write_lock(lock)#define cb_force_write_lock (lock, flags) __cb_force_write_lock(lock)#define cb_write_unlock (lock, flags) __cb_write_unlock(lock) -#else /* !CONFIG_XENO_FASTSEM */ +#else /* !CONFIG_XENO_FASTSYNCH */ #ifdef __KERNEL__#define DECLARE_CB_LOCK_FLAGS (name) spl_t name#define cb_try_read_lock (lock, flags) \
@@ -87,6 +87,6 @@ static __inline__ void __cb_write_unlock#define cb_force_write_lock (lock, flags) do { } while (0)#define cb_write_unlock (lock, flags) do { } while (0)#endif /* !__KERNEL__ */ -#endif /* !CONFIG_XENO_FASTSEM */ +#endif /* !CONFIG_XENO_FASTSYNCH */ #endif /* CB_LOCK_H */
ksrc/skins/posix/cond.c +9 -9
@@ -142,7 +142,7 @@ int pthread_cond_init(pthread_cond_t * c shadow->magic =PSE51_COND_MAGIC ; shadow->cond = cond; -xnsynch_init (&cond->synchbase, synch_flags); +xnsynch_init (&cond->synchbase, synch_flags,NULL );inith (&cond->link); cond->attr = *attr; cond->mutex =NULL ;
@@ -424,10 +424,10 @@ int pthread_cond_wait(pthread_cond_t * cunsigned count;int err; -#ifdef CONFIG_XENO_FASTSEM +#ifdef CONFIG_XENO_FASTSYNCH if (unlikely (cb_try_read_lock (&mutex->lock, s)))return EINVAL ; -#endif /* CONFIG_XENO_FASTSEM */ +#endif /* CONFIG_XENO_FASTSYNCH */ err =pse51_cond_timedwait_prologue (cur, cond, mutex, &count,0 ,XN_INFINITE );
@@ -437,9 +437,9 @@ int pthread_cond_wait(pthread_cond_t * c mutex, count)) ; -#ifdef CONFIG_XENO_FASTSEM +#ifdef CONFIG_XENO_FASTSYNCH cb_read_unlock (&mutex->lock, s); -#endif /* CONFIG_XENO_FASTSEM */ +#endif /* CONFIG_XENO_FASTSYNCH */ return err !=EINTR ? err :0 ; }
@@ -492,10 +492,10 @@ int pthread_cond_timedwait(pthread_cond_unsigned count;int err; -#ifdef CONFIG_XENO_FASTSEM +#ifdef CONFIG_XENO_FASTSYNCH if (unlikely (cb_try_read_lock (&mutex->lock, s)))return EINVAL ; -#endif /* CONFIG_XENO_FASTSEM */ +#endif /* CONFIG_XENO_FASTSYNCH */ err =pse51_cond_timedwait_prologue (cur, cond, mutex, &count,1 ,ts2ticks_ceil (abstime) +1 );
@@ -505,9 +505,9 @@ int pthread_cond_timedwait(pthread_cond_ mutex, count)) ; -#ifdef CONFIG_XENO_FASTSEM +#ifdef CONFIG_XENO_FASTSYNCH cb_read_unlock (&mutex->lock, s); -#endif /* CONFIG_XENO_FASTSEM */ +#endif /* CONFIG_XENO_FASTSYNCH */ return err !=EINTR ? err :0 ; }
ksrc/skins/posix/mutex.c +6 -6
@@ -103,16 +103,16 @@ int pse51_mutex_init_internal(struct __s shadow->mutex = mutex; shadow->lockcnt =0 ; -#ifdef CONFIG_XENO_FASTSEM +#ifdef CONFIG_XENO_FASTSYNCH xnarch_atomic_set (&shadow->lock,-1 ); shadow->attr = *attr; shadow->owner_offset =xnheap_mapped_offset (&sys_ppd->sem_heap, ownerp); -#endif /* CONFIG_XENO_FASTSEM */ +#endif /* CONFIG_XENO_FASTSYNCH */ if (attr->protocol ==PTHREAD_PRIO_INHERIT ) synch_flags |=XNSYNCH_PIP ; -xnsynch_init (&mutex->synchbase, synch_flags); +xnsynch_init (&mutex->synchbase, synch_flags,NULL );inith (&mutex->link); mutex->attr = *attr; mutex->owner = ownerp;
@@ -169,16 +169,16 @@ int pthread_mutex_init(pthread_mutex_t * goto checked; err =pse51_mutex_check_init (shadow, attr); -#ifndef CONFIG_XENO_FASTSEM +#ifndef CONFIG_XENO_FASTSYNCH cb_read_unlock (&shadow->lock, s);if (err)return -err; -#else /* CONFIG_XENO_FASTSEM */ +#else /* CONFIG_XENO_FASTSYNCH */ if (err) {cb_read_unlock (&shadow->lock, s);return -err; } -#endif /* CONFIG_XENO_FASTSEM */ +#endif /* CONFIG_XENO_FASTSYNCH */ checked: mutex = (pse51_mutex_t *)xnmalloc (sizeof (*mutex));
ksrc/skins/posix/mutex.h +2 -2
@@ -30,14 +30,14 @@ union __xeno_mutex {unsigned magic;unsigned lockcnt;struct pse51_mutex *mutex; -#ifdef CONFIG_XENO_FASTSEM +#ifdef CONFIG_XENO_FASTSYNCH xnarch_atomic_t lock;union {unsigned owner_offset;xnarch_atomic_t *owner; };struct pse51_mutexattr attr; -#endif /* CONFIG_XENO_FASTSEM */ +#endif /* CONFIG_XENO_FASTSYNCH */ } shadow_mutex; };
ksrc/skins/posix/syscall.c +10 -10
@@ -886,7 +886,7 @@ static int __pthread_mutexattr_setpsharereturn __xn_safe_copy_to_user ((void __user *)uattrp, &attr,sizeof (*uattrp)); } -#ifndef CONFIG_XENO_FASTSEM +#ifndef CONFIG_XENO_FASTSYNCH static int __pthread_mutex_init (struct pt_regs *regs) {pthread_mutexattr_t locattr, *attr, *uattrp;
@@ -1088,7 +1088,7 @@ static int __pthread_mutex_unlock(struct return err; } -#else /* !CONFIG_XENO_FASTSEM */ +#else /* !CONFIG_XENO_FASTSYNCH */ static int __pthread_mutex_check_init (struct pt_regs *regs) {pthread_mutexattr_t locattr, *attr, *uattrp;
@@ -1279,7 +1279,7 @@ static int __pthread_mutex_unlock(struct return 0; } -#endif /* !CONFIG_XENO_FASTSEM */ +#endif /* !CONFIG_XENO_FASTSYNCH */ static int __pthread_condattr_init (struct pt_regs *regs) {
@@ -1469,11 +1469,11 @@ static int __pthread_cond_wait_prologue(if (__xn_safe_copy_from_user (&mx.shadow_mutex, (void __user *)&umx->shadow_mutex, -#ifdef CONFIG_XENO_FASTSEM +#ifdef CONFIG_XENO_FASTSYNCH offsetof(struct __shadow_mutex, lock) -#else /* !CONFIG_XENO_FASTSEM */ +#else /* !CONFIG_XENO_FASTSYNCH */sizeof (mx.shadow_mutex) -#endif /* !CONFIG_XENO_FASTSEM */ +#endif /* !CONFIG_XENO_FASTSYNCH */ ))return -EFAULT ;
@@ -1537,11 +1537,11 @@ static int __pthread_cond_wait_epilogue(if (__xn_safe_copy_from_user (&mx.shadow_mutex, (void __user *)&umx->shadow_mutex, -#ifdef CONFIG_XENO_FASTSEM +#ifdef CONFIG_XENO_FASTSYNCH offsetof(struct __shadow_mutex, lock) -#else /* !CONFIG_XENO_FASTSEM */ +#else /* !CONFIG_XENO_FASTSYNCH */sizeof (mx.shadow_mutex) -#endif /* !CONFIG_XENO_FASTSEM */ +#endif /* !CONFIG_XENO_FASTSYNCH */ ))return -EFAULT ;
@@ -2695,7 +2695,7 @@ static xnsysent_t __systab[] = { [__pse51_mutex_lock] = {&__pthread_mutex_lock, __xn_exec_primary}, [__pse51_mutex_timedlock] = {&__pthread_mutex_timedlock, __xn_exec_primary}, -#ifndef CONFIG_XENO_FASTSEM +#ifndef CONFIG_XENO_FASTSYNCH [__pse51_mutex_trylock] = {&__pthread_mutex_trylock, __xn_exec_primary}, #else [__pse51_check_init] = {&__pthread_mutex_check_init, __xn_exec_any},
ksrc/skins/posix/thread.c +3 -3
@@ -209,7 +209,7 @@ int pthread_create(pthread_t *tid, thread->magic =PSE51_THREAD_MAGIC ; thread->entry = start; thread->arg = arg; -xnsynch_init (&thread->join_synch,XNSYNCH_PRIO ); +xnsynch_init (&thread->join_synch,XNSYNCH_PRIO ,NULL ); thread->nrt_joiners =0 ;pse51_cancel_init_thread (thread);
@@ -234,7 +234,7 @@ int pthread_create(pthread_t *tid, thread->hkey.mm =NULL ;#endif /* CONFIG_XENO_OPT_PERVASIVE */ -#ifdef CONFIG_XENO_FASTSEM +#ifdef CONFIG_XENO_FASTSYNCH /* We need an anonymous registry entry to obtain a handle for fast mutex locking. */ {
@@ -244,7 +244,7 @@ int pthread_create(pthread_t *tid, return err; } } -#endif /* CONFIG_XENO_FASTSEM */ +#endif /* CONFIG_XENO_FASTSYNCH */ *tid = thread;/* Must be done before the thread is started. */
ksrc/skins/psos+/Kconfig +1 -1
@@ -2,7 +2,7 @@ menuconfig XENO_SKIN_PSOS depends on XENO_OPT_NUCLEUS select XENO_OPT_TIMING_PERIODIC tristate "pSOS+ emulator" - select XENO_OPT_REGISTRY if XENO_OPT_PERVASIVE || XENO_FASTSEM + select XENO_OPT_REGISTRY if XENO_OPT_PERVASIVE || XENO_FASTSYNCH help This API skin emulates WindRiver's pSOS+ operating system.
ksrc/skins/rtai/Kconfig +1 -1
@@ -1,6 +1,6 @@ menuconfig XENO_SKIN_RTAI depends on XENO_OPT_NUCLEUS - select XENO_OPT_REGISTRY if XENO_FASTSEM + select XENO_OPT_REGISTRY if XENO_FASTSYNCH tristate "RTAI emulator" help
ksrc/skins/rtai/task.c +2 -2
@@ -152,7 +152,7 @@ int rt_task_init(RT_TASK *task, task->magic =RTAI_TASK_MAGIC ;appendq (&__rtai_task_q, &task->link); -#ifdef CONFIG_XENO_FASTSEM +#ifdef CONFIG_XENO_FASTSYNCH /* We need an anonymous registry entry to obtain a handle for fast mutex locking. */ err =xnthread_register (&task->thread_base,"" );
@@ -160,7 +160,7 @@ int rt_task_init(RT_TASK *task,xnpod_abort_thread (&task->thread_base); goto unlock_and_exit; } -#endif /* CONFIG_XENO_FASTSEM */ +#endif /* CONFIG_XENO_FASTSYNCH */ /* Add a switch hook only if a signal function has been declared at least once for some created task. */
ksrc/skins/uitron/Kconfig +1 -1
@@ -2,7 +2,7 @@ menuconfig XENO_SKIN_UITRON depends on XENO_OPT_NUCLEUS select XENO_OPT_TIMING_PERIODIC select XENO_OPT_MAP - select XENO_OPT_REGISTRY if XENO_FASTSEM + select XENO_OPT_REGISTRY if XENO_FASTSYNCH tristate "uITRON API" help
ksrc/skins/uitron/task.c +2 -2
@@ -150,7 +150,7 @@ ER cre_tsk(ID tskid, T_CTSK *pk_ctsk)xnlock_put_irqrestore (&nklock, s); task->magic = uITRON_TASK_MAGIC; -#ifdef CONFIG_XENO_FASTSEM +#ifdef CONFIG_XENO_FASTSYNCH /* We need an anonymous registry entry to obtain a handle for fast mutex locking. */ if (xnthread_register (&task->threadbase,"" )) {
@@ -158,7 +158,7 @@ ER cre_tsk(ID tskid, T_CTSK *pk_ctsk)xnpod_abort_thread (&task->threadbase); return E_NOMEM; } -#endif /* CONFIG_XENO_FASTSEM */ +#endif /* CONFIG_XENO_FASTSYNCH */ return E_OK ; }
ksrc/skins/vrtx/Kconfig +1 -1
@@ -3,7 +3,7 @@ menuconfig XENO_SKIN_VRTX select XENO_OPT_TIMING_PERIODIC select XENO_OPT_MAP tristate "VRTX emulator" - select XENO_OPT_REGISTRY if XENO_OPT_PERVASIVE || CONFIG_XENO_FASTSEM + select XENO_OPT_REGISTRY if XENO_OPT_PERVASIVE || CONFIG_XENO_FASTSYNCH help This API skin emulates Mentor Graphics's VRTX operating
ksrc/skins/vxworks/Kconfig +1 -1
@@ -2,7 +2,7 @@ menuconfig XENO_SKIN_VXWORKS depends on XENO_OPT_NUCLEUS select XENO_OPT_TIMING_PERIODIC tristate "VxWorks emulator" - select XENO_OPT_REGISTRY if XENO_OPT_PERVASIVE || XENO_FASTSEM + select XENO_OPT_REGISTRY if XENO_OPT_PERVASIVE || XENO_FASTSYNCH help This API skin emulates WindRiver's VxWorks operating system.
src/skins/posix/mutex.c +21 -21
151 lines not on this page · raw message
ksrc/nucleus/pipe.c +1 -1
@@ -235,7 +235,7 @@ int xnpipe_connect(int minor,__setbits (state->status,XNPIPE_KERN_CONN ); -xnsynch_init (&state->synchbase,XNSYNCH_FIFO ); +xnsynch_init (&state->synchbase,XNSYNCH_FIFO ,NULL ); state->output_handler = output_handler; state->input_handler = input_handler; state->alloc_handler = alloc_handler;
ksrc/nucleus/registry.c +2 -2
@@ -186,7 +186,7 @@ int xnregistry_init(void)for (n =0 ; n < registry_hash_entries; n++) registry_hash_table[n] =NULL ; -xnsynch_init (®istry_hash_synch,XNSYNCH_FIFO ); +xnsynch_init (®istry_hash_synch,XNSYNCH_FIFO ,NULL );return 0 ; }
@@ -615,7 +615,7 @@ int xnregistry_enter(const char *key, object =link2xnobj (holder); -xnsynch_init (&object->safesynch,XNSYNCH_FIFO ); +xnsynch_init (&object->safesynch,XNSYNCH_FIFO ,NULL ); object->objaddr = objaddr; object->cstamp = ++registry_obj_stamp; object->safelock =0 ;
ksrc/nucleus/select.c +1 -1
@@ -274,7 +274,7 @@ int xnselector_init(struct xnselector *s {unsigned i; -xnsynch_init (&selector->synchbase,XNSYNCH_FIFO |XNSYNCH_NOPIP ); +xnsynch_init (&selector->synchbase,XNSYNCH_FIFO ,NULL );for (i =0 ; i <XNSELECT_MAX_TYPES ; i++) {__FD_ZERO (&selector->fds[i].expected);__FD_ZERO (&selector->fds[i].pending);
ksrc/nucleus/synch.c +113 -19
209 lines not on this page · raw message
ksrc/drivers/testing/switchtest.c +1 -1
@@ -219,7 +219,7 @@ static int rtswitch_register_task(rtswit ctx->next_index++; t->base = *arg;sema_init (&t->nrt_synch,0 ); -xnsynch_init (&t->rt_synch,XNSYNCH_FIFO ); +xnsynch_init (&t->rt_synch,XNSYNCH_FIFO ,NULL );up (&ctx->lock);
ksrc/skins/native/alarm.c +1 -1
@@ -207,7 +207,7 @@ int rt_alarm_create(RT_ALARM *alarm,xnlock_put_irqrestore (&nklock, s);#ifdef CONFIG_XENO_OPT_PERVASIVE -xnsynch_init (&alarm->synch_base,XNSYNCH_PRIO ); +xnsynch_init (&alarm->synch_base,XNSYNCH_PRIO ,NULL ); alarm->cpid =0 ;#endif /* CONFIG_XENO_OPT_PERVASIVE */
ksrc/skins/native/buffer.c +2 -2
@@ -192,8 +192,8 @@ int rt_buffer_create(RT_BUFFER *bf, consif (bf->bufmem ==NULL )return -ENOMEM ; -xnsynch_init (&bf->isynch_base, mode &B_PRIO ); -xnsynch_init (&bf->osynch_base, mode &B_PRIO ); +xnsynch_init (&bf->isynch_base, mode &B_PRIO ,NULL ); +xnsynch_init (&bf->osynch_base, mode &B_PRIO ,NULL ); bf->handle =0 ;/* i.e. (still) unregistered buffer. */ xnobject_copy_name (bf->name, name);
ksrc/skins/native/cond.c +1 -1
@@ -160,7 +160,7 @@ int rt_cond_create(RT_COND *cond, constif (xnpod_asynch_p ())return -EPERM ; -xnsynch_init (&cond->synch_base,XNSYNCH_PRIO ); +xnsynch_init (&cond->synch_base,XNSYNCH_PRIO ,NULL ); cond->handle =0 ;/* i.e. (still) unregistered cond. */ cond->magic =XENO_COND_MAGIC ;xnobject_copy_name (cond->name, name);
ksrc/skins/native/event.c +1 -1
@@ -183,7 +183,7 @@ int rt_event_create(RT_EVENT *event,if (xnpod_asynch_p ())return -EPERM ; -xnsynch_init (&event->synch_base, mode &EV_PRIO ); +xnsynch_init (&event->synch_base, mode &EV_PRIO ,NULL ); event->value = ivalue; event->handle =0 ;/* i.e. (still) unregistered event. */ event->magic =XENO_EVENT_MAGIC ;
ksrc/skins/native/heap.c +1 -1
@@ -292,7 +292,7 @@ int rt_heap_create(RT_HEAP *heap, const } } -xnsynch_init (&heap->synch_base, mode & (H_PRIO |H_FIFO )); +xnsynch_init (&heap->synch_base, mode & (H_PRIO |H_FIFO ),NULL ); heap->handle =0 ;/* i.e. (still) unregistered heap. */ heap->magic =XENO_HEAP_MAGIC ; heap->mode = mode;
ksrc/skins/native/intr.c +1 -1
@@ -266,7 +266,7 @@ int rt_intr_create(RT_INTR *intr,xnintr_init (&intr->intr_base, intr->name, irq, isr, iack, mode);#ifdef CONFIG_XENO_OPT_PERVASIVE -xnsynch_init (&intr->synch_base,XNSYNCH_PRIO ); +xnsynch_init (&intr->synch_base,XNSYNCH_PRIO ,NULL ); intr->pending =0 ; intr->cpid =0 ; intr->mode =0 ;
ksrc/skins/native/mutex.c +1 -1
@@ -171,7 +171,7 @@ int rt_mutex_create(RT_MUTEX *mutex, conreturn -EPERM ;xnsynch_init (&mutex->synch_base, -XNSYNCH_PRIO |XNSYNCH_PIP |XNSYNCH_OWNER ); +XNSYNCH_PRIO |XNSYNCH_PIP |XNSYNCH_OWNER ,NULL ); mutex->handle =0 ;/* i.e. (still) unregistered mutex. */ mutex->magic =XENO_MUTEX_MAGIC ; mutex->lockcnt =0 ;
ksrc/skins/native/queue.c +1 -1
@@ -255,7 +255,7 @@ int rt_queue_create(RT_QUEUE *q, } } -xnsynch_init (&q->synch_base, mode & (Q_PRIO |Q_FIFO )); +xnsynch_init (&q->synch_base, mode & (Q_PRIO |Q_FIFO ),NULL );initq (&q->pendq); q->handle =0 ;/* i.e. (still) unregistered queue. */ q->magic =XENO_QUEUE_MAGIC ;
ksrc/skins/native/sem.c +1 -1
@@ -181,7 +181,7 @@ int rt_sem_create(RT_SEM *sem, const chaif ((mode &S_PULSE ) && icount >0 )return -EINVAL ; -xnsynch_init (&sem->synch_base, mode &S_PRIO ); +xnsynch_init (&sem->synch_base, mode &S_PRIO ,NULL ); sem->count = icount; sem->mode = mode; sem->handle =0 ;/* i.e. (still) unregistered semaphore. */
ksrc/skins/native/task.c +3 -3
@@ -255,7 +255,7 @@ int rt_task_create(RT_TASK *task, task->overrun =-1 ; task->cstamp = ++__xeno_task_stamp; task->safelock =0 ; -xnsynch_init (&task->safesynch,XNSYNCH_FIFO ); +xnsynch_init (&task->safesynch,XNSYNCH_FIFO ,NULL );xnarch_cpus_clear (task->affinity);
@@ -268,9 +268,9 @@ int rt_task_create(RT_TASK *task, task->affinity =XNPOD_ALL_CPUS ;#ifdef CONFIG_XENO_OPT_NATIVE_MPS -xnsynch_init (&task->mrecv,XNSYNCH_FIFO ); +xnsynch_init (&task->mrecv,XNSYNCH_FIFO ,NULL );xnsynch_init (&task->msendq, -XNSYNCH_PRIO |XNSYNCH_PIP |XNSYNCH_OWNER ); +XNSYNCH_PRIO |XNSYNCH_PIP |XNSYNCH_OWNER ,NULL );xnsynch_set_owner (&task->msendq, &task->thread_base); task->flowgen =0 ;#endif /* CONFIG_XENO_OPT_NATIVE_MPS */
ksrc/skins/posix/intr.c +1 -1
@@ -116,7 +116,7 @@ int pthread_intr_attach_np(pthread_intr_xnintr_init (&intr->intr_base,NULL , irq, isr, iack,0 );#ifdef CONFIG_XENO_OPT_PERVASIVE -xnsynch_init (&intr->synch_base,XNSYNCH_PRIO ); +xnsynch_init (&intr->synch_base,XNSYNCH_PRIO ,NULL ); intr->pending =0 ;#endif /* CONFIG_XENO_OPT_PERVASIVE */ intr->magic =PSE51_INTR_MAGIC ;
ksrc/skins/posix/mq.c +2 -2
@@ -129,8 +129,8 @@ static int pse51_mq_init(pse51_mq_t * mq mq->memsize = memsize;initpq (&mq->queued); -xnsynch_init (&mq->receivers,XNSYNCH_PRIO |XNSYNCH_NOPIP ); -xnsynch_init (&mq->senders,XNSYNCH_PRIO |XNSYNCH_NOPIP ); +xnsynch_init (&mq->receivers,XNSYNCH_PRIO |XNSYNCH_NOPIP ,NULL ); +xnsynch_init (&mq->senders,XNSYNCH_PRIO |XNSYNCH_NOPIP ,NULL ); mq->mem = mem;/* Fill the pool. */
ksrc/skins/posix/sem.c +1 -1
@@ -99,7 +99,7 @@ static int pse51_sem_init_inner(pse51_seinith (&sem->link);appendq (&pse51_kqueues (pshared)->semq, &sem->link); -xnsynch_init (&sem->synchbase,XNSYNCH_PRIO ); +xnsynch_init (&sem->synchbase,XNSYNCH_PRIO ,NULL ); sem->value = value; sem->pshared = pshared; sem->is_named =0 ;
ksrc/skins/psos+/event.c +1 -1
@@ -21,7 +21,7 @@void taskev_init (psosevent_t *evgroup) { -xnsynch_init (&evgroup->synchbase,XNSYNCH_FIFO ); +xnsynch_init (&evgroup->synchbase,XNSYNCH_FIFO ,NULL ); evgroup->events =0 ; }
ksrc/skins/psos+/queue.c +1 -1
@@ -259,7 +259,7 @@ static u_long q_create_internal(const ch } } -xnsynch_init (&queue->synchbase, bflags); +xnsynch_init (&queue->synchbase, bflags,NULL ); queue->magic =PSOS_QUEUE_MAGIC ;xnobject_copy_name (queue->name, name);
ksrc/skins/psos+/rn.c +1 -1
@@ -214,7 +214,7 @@ u_long rn_create(const char *name, rn->usize = usize;xnobject_copy_name (rn->name, name); -xnsynch_init (&rn->synchbase, bflags); +xnsynch_init (&rn->synchbase, bflags,NULL ); rn->magic =PSOS_RN_MAGIC ;inith (&rn->rlink);
ksrc/skins/psos+/sem.c +1 -1
@@ -114,7 +114,7 @@ u_long sm_create(const char *name, u_lonif (flags &SM_PRIOR ) bflags |=XNSYNCH_PRIO ; -xnsynch_init (&sem->synchbase, bflags); +xnsynch_init (&sem->synchbase, bflags,NULL );inith (&sem->link); sem->count = icount;
ksrc/skins/rtai/sem.c +1 -1
@@ -38,7 +38,7 @@ void rt_typed_sem_init(SEM * sem, int va mode =XNSYNCH_FIFO ; } -xnsynch_init (&sem->synch_base, mode); +xnsynch_init (&sem->synch_base, mode,NULL ); sem->count = value; sem->type = type &0x3 ; sem->owner =NULL ;
ksrc/skins/rtdm/drvlib.c +5 -5
@@ -145,13 +145,13 @@ int rtdm_task_init(rtdm_task_t *task, coif (err)return err; -#ifdef CONFIG_XENO_FASTSEM +#ifdef CONFIG_XENO_FASTSYNCH /* We need an anonymous registry entry to obtain a handle for fast mutex locking. */ err =xnthread_register (task,"" );if (err) goto cleanup_out; -#endif /* CONFIG_XENO_FASTSEM */ +#endif /* CONFIG_XENO_FASTSYNCH */ if (period >0 ) { err = xnpod_set_thread_periodic(task, XN_INFINITE,
@@ -761,7 +761,7 @@ void rtdm_event_init(rtdm_event_t *event/* Make atomic for re-initialisation support */ xnlock_get_irqsave (&nklock, s); -xnsynch_init (&event->synch_base,XNSYNCH_PRIO ); +xnsynch_init (&event->synch_base,XNSYNCH_PRIO ,NULL );if (pending)xnsynch_set_flags (&event->synch_base,RTDM_EVENT_PENDING );xnselect_init (&event->select_block);
@@ -1109,7 +1109,7 @@ void rtdm_sem_init(rtdm_sem_t *sem, unsixnlock_get_irqsave (&nklock, s); sem->value = value; -xnsynch_init (&sem->synch_base,XNSYNCH_PRIO ); +xnsynch_init (&sem->synch_base,XNSYNCH_PRIO ,NULL );xnselect_init (&sem->select_block);xnlock_put_irqrestore (&nklock, s);
@@ -1391,7 +1391,7 @@ void rtdm_mutex_init(rtdm_mutex_t *mutexxnlock_get_irqsave (&nklock, s);xnsynch_init (&mutex->synch_base, -XNSYNCH_PRIO |XNSYNCH_PIP |XNSYNCH_OWNER ); +XNSYNCH_PRIO |XNSYNCH_PIP |XNSYNCH_OWNER ,NULL );xnlock_put_irqrestore (&nklock, s); }
ksrc/skins/uitron/flag.c +1 -1
@@ -122,7 +122,7 @@ ER cre_flg(ID flgid, T_CFLG *pk_cflg)return E_OBJ ; } -xnsynch_init (&flag->synchbase,XNSYNCH_FIFO ); +xnsynch_init (&flag->synchbase,XNSYNCH_FIFO ,NULL ); flag->id = flgid; flag->exinf = pk_cflg->exinf; flag->flgatr = pk_cflg->flgatr;
ksrc/skins/uitron/mbx.c +2 -1
@@ -138,7 +138,8 @@ ER cre_mbx(ID mbxid, T_CMBX *pk_cmbx) }xnsynch_init (&mbx->synchbase, - (pk_cmbx->mbxatr &TA_TPRI ) ?XNSYNCH_PRIO :XNSYNCH_FIFO ); + (pk_cmbx->mbxatr &TA_TPRI ) ?XNSYNCH_PRIO :XNSYNCH_FIFO , +NULL ); mbx->id = mbxid; mbx->exinf = pk_cmbx->exinf;
ksrc/skins/uitron/sem.c +2 -1
@@ -127,7 +127,8 @@ ER cre_sem(ID semid, T_CSEM *pk_csem) }xnsynch_init (&sem->synchbase, - (pk_csem->sematr &TA_TPRI ) ?XNSYNCH_PRIO :XNSYNCH_FIFO ); + (pk_csem->sematr &TA_TPRI ) ?XNSYNCH_PRIO :XNSYNCH_FIFO , +NULL ); sem->id = semid; sem->exinf = pk_csem->exinf;
ksrc/skins/vrtx/event.c +1 -1
@@ -151,7 +151,7 @@ int sc_fcreate(int *errp) goto nocb; } -xnsynch_init (&evgroup->synchbase,XNSYNCH_PRIO |XNSYNCH_DREORD ); +xnsynch_init (&evgroup->synchbase,XNSYNCH_PRIO |XNSYNCH_DREORD ,NULL );inith (&evgroup->link); evgroup->evid = evid; evgroup->magic =VRTX_EVENT_MAGIC ;
ksrc/skins/vrtx/mb.c +1 -1
@@ -210,7 +210,7 @@ vrtxmb_t *mb_map(char **mboxp) mb->mboxp = mboxp; mb->msg =NULL ; mb->hnext =NULL ; -xnsynch_init (&mb->synchbase,XNSYNCH_PRIO |XNSYNCH_DREORD ); +xnsynch_init (&mb->synchbase,XNSYNCH_PRIO |XNSYNCH_DREORD ,NULL );appendq (&vrtx_mbox_q, &mb->link);mb_hash (mboxp, mb);
ksrc/skins/vrtx/mx.c +2 -1
@@ -161,7 +161,8 @@ int sc_mcreate(unsigned int opt, int *erinith (&mx->link); mx->mid = mid; mx->owner =NULL ; -xnsynch_init (&mx->synchbase, bflags |XNSYNCH_DREORD |XNSYNCH_OWNER ); +xnsynch_init (&mx->synchbase, bflags |XNSYNCH_DREORD |XNSYNCH_OWNER , +NULL );xnlock_get_irqsave (&nklock, s);appendq (&vrtx_mx_q, &mx->link);
ksrc/skins/vrtx/queue.c +1 -1
@@ -165,7 +165,7 @@ int sc_qecreate(int qid, int qsize, int bflags =XNSYNCH_PRIO ;inith (&queue->link); -xnsynch_init (&queue->synchbase, bflags |XNSYNCH_DREORD ); +xnsynch_init (&queue->synchbase, bflags |XNSYNCH_DREORD ,NULL ); queue->magic =VRTX_QUEUE_MAGIC ; queue->qid = qid; queue->qsize = qsize;
ksrc/skins/vrtx/sem.c +1 -1
@@ -155,7 +155,7 @@ int sc_screate(unsigned initval, int optelse bflags =XNSYNCH_FIFO ; -xnsynch_init (&sem->synchbase, bflags |XNSYNCH_DREORD ); +xnsynch_init (&sem->synchbase, bflags |XNSYNCH_DREORD ,NULL );inith (&sem->link); sem->semid = semid; sem->magic =VRTX_SEM_MAGIC ;
ksrc/skins/vxworks/module.c +1 -1
@@ -59,7 +59,7 @@ int SKIN_INIT(vxworks)/* The following fields are unused in the global holder; still, we initialize them not to leave such data in an invalid state. */ -xnsynch_init (&__wind_global_rholder.wdsynch,XNSYNCH_FIFO ); +xnsynch_init (&__wind_global_rholder.wdsynch,XNSYNCH_FIFO ,NULL );initq (&__wind_global_rholder.wdpending); __wind_global_rholder.wdcount =0 ;
ksrc/skins/vxworks/msgQLib.c +1 -1
@@ -174,7 +174,7 @@ MSG_Q_ID msgQCreate(int nb_msgs, int lenif (flags &MSG_Q_PRIORITY ) bflags |=XNSYNCH_PRIO ; -xnsynch_init (&queue->synchbase, bflags); +xnsynch_init (&queue->synchbase, bflags,NULL ); msg_size =sizeof (wind_msg_t) + length;
ksrc/skins/vxworks/semLib.c +1 -1
@@ -423,7 +423,7 @@ static SEM_ID sem_create_internal(int fl check_alloc(wind_sem_t, sem, return 0); -xnsynch_init (&sem->synchbase, (xnflags_t )flags); +xnsynch_init (&sem->synchbase, (xnflags_t )flags,NULL ); sem->magic =WIND_SEM_MAGIC ; sem->count = count; sem->vtbl = vtbl;
ksrc/skins/vxworks/syscall.c +1 -1
@@ -1171,7 +1171,7 @@ static void *__wind_shadow_eventcb(int einitq (&rh->wdq);/* A single server thread pends on this. */ -xnsynch_init (&rh->wdsynch,XNSYNCH_FIFO ); +xnsynch_init (&rh->wdsynch,XNSYNCH_FIFO ,NULL );initq (&rh->wdpending); rh->wdcount =0 ;initq (&rh->msgQq);
ksrc/skins/vxworks/taskLib.c +1 -1
@@ -146,7 +146,7 @@ STATUS taskInit(WIND_TCB *pTcb,xnthread_time_slice (&pTcb->threadbase) = rrperiod; pTcb->safecnt =0 ; -xnsynch_init (&pTcb->safesync,0 ); +xnsynch_init (&pTcb->safesync,0 ,NULL );/* TODO: fill in attributes of wind_task_t: pTcb->status
Re: [Xenomai-core] [PATCH 06/12] Lockless fast path for xnsynch_acquire/release
Jan Kiszka wrote:
Ok. Though I do not see the point of the FASTSEM/FASTSYNCH rename. FASTSEM is short, and we are not much interested in getting anything else than semaphores faster.
Signature · 1 line
Gilles.
Re: [Xenomai-core] [PATCH 06/12] Lockless fast path for xnsynch_acquire/release
Quoted 5 lines · Gilles Chanteperdrix
Jan Kiszka wrote:
Ok. Though I do not see the point of the FASTSEM/FASTSYNCH rename. FASTSEM is short, and we are not much interested in getting anything else than semaphores faster.
We aren't optimizing semaphores (at least not yet), we are optimizing mutexes only. And if we ever optimize also semaphores, FASTSYNCH will luckily still fit. :)
Jan
Re: [Xenomai-core] [PATCH 06/12] Lockless fast path for xnsynch_acquire/release
Quoted 10 lines · Jan Kiszka
Quoted 5 lines · Gilles Chanteperdrix
Jan Kiszka wrote:
Ok. Though I do not see the point of the FASTSEM/FASTSYNCH rename. FASTSEM is short, and we are not much interested in getting anything else than semaphores faster.
We aren't optimizing semaphores (at least not yet), we are optimizing mutexes only. And if we ever optimize also semaphores, FASTSYNCH will luckily still fit. :)
The name was chosen because we plan to optimize semaphores as well, and because mutexes are simply a special kind of semaphores, so, by saying FASTSEM, we cover semaphores as well as mutexes.
Signature · 1 line
Gilles.
Re: [Xenomai-core] [PATCH 06/12] Lockless fast path for xnsynch_acquire/release
Quoted 7 lines · Gilles Chanteperdrix
Quoted 6 lines · Jan Kiszka
Quoted 5 lines · Gilles Chanteperdrix
Jan Kiszka wrote:
Ok. Though I do not see the point of the FASTSEM/FASTSYNCH rename. FASTSEM is short, and we are not much interested in getting anything else than semaphores faster.
Quoted 7 lines
Quoted 3 lines
We aren't optimizing semaphores (at least not yet), we are optimizing mutexes only. And if we ever optimize also semaphores, FASTSYNCH will luckily still fit. :)
The name was chosen because we plan to optimize semaphores as well, and because mutexes are simply a special kind of semaphores, so, by saying FASTSEM, we cover semaphores as well as mutexes.
That depends on how you define both - most semaphore definitions do not include the ownership concept, thus are not a superclass of (owner-tracking) mutexes we consider here.
Jan
Re: [Xenomai-core] [PATCH 06/12] Lockless fast path for xnsynch_acquire/release
Quoted 15 lines · Jan Kiszka
Quoted 7 lines · Gilles Chanteperdrix
Quoted 6 lines · Jan Kiszka
Quoted 5 lines · Gilles Chanteperdrix
Jan Kiszka wrote:
Ok. Though I do not see the point of the FASTSEM/FASTSYNCH rename. FASTSEM is short, and we are not much interested in getting anything else than semaphores faster.
Quoted 6 lines
Quoted 3 lines
We aren't optimizing semaphores (at least not yet), we are optimizing mutexes only. And if we ever optimize also semaphores, FASTSYNCH will luckily still fit. :)
The name was chosen because we plan to optimize semaphores as well, and because mutexes are simply a special kind of semaphores, so, by saying FASTSEM, we cover semaphores as well as mutexes.
Quoted 5 lines
That depends on how you define both - most semaphore definitions do not include the ownership concept, thus are not a superclass of (owner-tracking) mutexes we consider here.
From my point of view, a mutex is a semaphore. If we imagine it in
simple OOP terms, the mutex class inherit from the semaphore class. Yes, it has an owner member which the semaphore has not, but it still is a semaphore.
Signature · 1 line
Gilles.
PATCH 7/12 Convert POSIX skin to fast xnsynch
In reply to Jan KiszkaMigrates the existing fast mutex implementation of the POSIX skin to fast xnsynch services, also fixing the build for arch that do not support fast mutexes.
Lock stealing via pthread_trylock is not considered by this patch, keeping this services lockless and syscall-less until we identify the need for using the steal mechanism also for this case.
--- ksrc/skins/posix/cond.c | 18 ++--- ksrc/skins/posix/mutex.c | 92 ++++++++++++++++++++-------- ksrc/skins/posix/mutex.h | 143 +++++++-------------------------------------- ksrc/skins/posix/syscall.c | 22 ++---- src/skins/posix/mutex.c | 55 ++++++++--------- 5 files changed, 132 insertions(+), 198 deletions(-)
ksrc/skins/posix/cond.c +7 -11
@@ -223,27 +223,23 @@ static inline int mutex_save_count(xnthr unsigned *count_ptr) {pse51_mutex_t *mutex; -xnthread_t *owner; if (!pse51_obj_active(shadow, PSE51_MUTEX_MAGIC, struct __shadow_mutex))return EINVAL ; mutex = shadow->mutex; -if (clear_claimed (xnarch_atomic_get (mutex->owner)) != -xnthread_handle (cur)) +#ifdef CONFIG_XENO_FASTSYNCH +if (xnsynch_fast_owner_check (mutex->synchbase.fastlock, +xnthread_handle (cur)) !=0 ) +#else /* !CONFIG_XENO_FASTSYNCH */ + if (xnsynch_owner(&mutex->synchbase) != cur) +#endif /* !CONFIG_XENO_FASTSYNCH */ return EPERM ; *count_ptr = shadow->lockcnt; -if (likely (xnarch_atomic_cmpxchg (mutex->owner, cur,XN_NO_HANDLE ) == -xnthread_handle (cur))) -return 0 ; - - owner =xnsynch_release (&mutex->synchbase); -xnarch_atomic_set (mutex->owner, -set_claimed (xnthread_handle (owner), -xnsynch_nsleepers (&mutex->synchbase))); +xnsynch_release (&mutex->synchbase);/* Do not reschedule here, releasing the mutex and suspension must be done atomically in pthread_cond_*wait. */
ksrc/skins/posix/mutex.c +64 -28
203 lines not on this page · raw message
ksrc/skins/posix/mutex.h +24 -119
186 lines not on this page · raw message
ksrc/skins/posix/syscall.c +9 -13
@@ -1060,13 +1060,10 @@ static int __pthread_mutex_unlock(struct mutex = shadow->mutex; -if (clear_claimed (xnarch_atomic_get (mutex->owner)) != -xnthread_handle (cur)) { - err = -EPERM ; + err = (xnsynch_owner (&mutex->synchbase) == cur) ?0 : -EPERM ; +if (err) goto out; - } - err =0 ;if (shadow->lockcnt >1 ) {/* Mutex is recursive */ --shadow->lockcnt;
@@ -1080,8 +1077,9 @@ static int __pthread_mutex_unlock(structreturn 0 ; } - -pse51_mutex_unlock_internal (cur, mutex); + +if (xnsynch_release (&mutex->synchbase)) +xnpod_schedule (); out:cb_read_unlock (&shadow->lock, s);
@@ -1186,13 +1184,11 @@ static int __pthread_mutex_destroy(strucif (pse51_kqueues (mutex->attr.pshared) != mutex->owningq)return -EPERM ; -if (xnarch_atomic_get (mutex->owner) !=XN_NO_HANDLE ) +if (xnsynch_fast_owner_check (mutex->synchbase.fastlock, +XN_NO_HANDLE ) !=0 )return -EBUSY ;pse51_mark_deleted (shadow); -if (!mutex->attr.pshared) -xnheap_free (&xnsys_ppd_get (mutex->attr.pshared)->sem_heap, - mutex->owner);pse51_mutex_destroy_internal (mutex, mutex->owningq); return __xn_safe_copy_to_user((void __user *)&umx->shadow_mutex,
@@ -1262,7 +1258,6 @@ static int __pthread_mutex_timedlock(strstatic int __pthread_mutex_unlock (struct pt_regs *regs) { -xnthread_t *cur =xnpod_current_thread ();union __xeno_mutex mx, *umx;if (xnpod_root_p ())
@@ -1275,7 +1270,8 @@ static int __pthread_mutex_unlock(struct offsetof(struct __shadow_mutex, lock)))return -EFAULT ; -pse51_mutex_unlock_internal (cur, mx.shadow_mutex.mutex); +if (xnsynch_release (&mx.shadow_mutex.mutex->synchbase)) +xnpod_schedule ();return 0 ; }
src/skins/posix/mutex.c +28 -27
153 lines not on this page · raw message
Re: [Xenomai-core] [PATCH 07/12] Convert POSIX skin to fast xnsynch
Jan Kiszka wrote:
This patch contains too many #ifdefs.
Things like
#ifdef CONFIG_XENO_FASTSYNCH
if (xnsynch_fast_owner_check(...))
#else
if (xnsynch_owner(...) == ...)
#endif
could be replaced with only one macro xnsynch_check_owner in synch.h that would be defined with some #ifdefs, and used everywhere without #ifdefs.
Signature · 1 line
Gilles.
Re: [Xenomai-core] [PATCH 07/12] Convert POSIX skin to fast xnsynch
Quoted 12 lines · Gilles Chanteperdrix
Jan Kiszka wrote:
This patch contains too many #ifdefs.
Things like
#ifdef
CONFIG_XENO_FASTSYNCH
if (xnsynch_fast_owner_check(...))
#else
if (xnsynch_owner(...)== ...)
#endif
Quoted 3 lines
could be replaced with only one macro
xnsynch_check_ownerinsynch.hthat would be defined with some #ifdefs, and used everywhere without #ifdefs.
Yes, that looks like a good idea. Will go through the patch again, checking for more cleanup possibilities like that.
Jan
PATCH 8/12 Use fast xnsynch with native skin
In reply to Jan KiszkaImplement a fast path for rt_mutex_acquire/release, making use of fast xnsynch services. Just as for the POSIX skin, lock stealing via trylock is sacrificed for a syscall-less user space implementation.
--- include/native/mutex.h | 23 ++- ksrc/skins/native/cond.c | 16 +- ksrc/skins/native/mutex.c | 314 ++++++++++++++++++++++++++------------------ ksrc/skins/native/syscall.c | 70 +++++++-- src/skins/native/cond.c | 30 ++++ src/skins/native/mutex.c | 102 +++++++++++++- 6 files changed, 398 insertions(+), 157 deletions(-)
include/native/mutex.h +18 -5
@@ -32,7 +32,7 @@ struct rt_task;*/ typedef struct rt_mutex_info { - int lockcnt; /**< Lock nesting level (> 0 means "locked"). */ + int locked; /**< > 0 if mutex is locked. */ int nwaiters; /**< Number of pending tasks. */
@@ -44,7 +44,15 @@ typedef struct rt_mutex_info { }RT_MUTEX_INFO ;typedef struct rt_mutex_placeholder { +xnhandle_t opaque; + +#ifdef CONFIG_XENO_FASTSYNCH +xnarch_atomic_t *fastlock; + +int lockcnt; +#endif /* CONFIG_XENO_FASTSYNCH */ + }RT_MUTEX_PLACEHOLDER ;#if (defined(__KERNEL__) || defined(__XENO_SIM__)) && !defined(DOXYGEN_CPP )
@@ -54,6 +62,8 @@ typedef struct rt_mutex_placeholder {#define XENO_MUTEX_MAGIC 0x55550505 +#define RT_MUTEX_EXPORTED XNSYNCH_SPARE0/* Mutex registered by name */ + typedef struct __rt_mutex { unsigned magic; /* !< Magic code - must be first */
@@ -74,7 +84,7 @@ typedef struct __rt_mutex {#define rlink2mutex (ln) container_of(ln, RT_MUTEX, rlink) -xnqueue_t *rqueue;/* !< Backpointer to resource queue. */ +xnqueue_t *rqueue;/* !< Backpointer to resource queue. */ }RT_MUTEX ;
@@ -93,9 +103,8 @@ static inline void __native_mutex_flush_ xeno_flush_rq(RT_MUTEX, rq, mutex); } -int rt_mutex_acquire_inner (RT_MUTEX *mutex, -xntmode_t timeout_mode, -RTIME timeout); +int rt_mutex_acquire_inner (RT_MUTEX *mutex,RTIME timeout, +xntmode_t timeout_mode);#else /* !CONFIG_XENO_OPT_NATIVE_MUTEX */
@@ -138,6 +147,10 @@ static inline int rt_mutex_unbind (RT_MUextern "C" {#endif +int rt_mutex_create_inner (RT_MUTEX *mutex,const char *name, +xnarch_atomic_t *fastlock); +int rt_mutex_delete_inner (RT_MUTEX *mutex); +/* Public interface. */ int rt_mutex_create(RT_MUTEX *mutex,
ksrc/skins/native/cond.c +9 -7
@@ -407,24 +407,26 @@ int rt_cond_wait_inner(RT_COND *cond, RT thread =xnpod_current_thread (); -if (thread !=xnsynch_owner (&mutex->synch_base)) { +#ifdef CONFIG_XENO_FASTSYNCH +if (xnsynch_fast_owner_check (mutex->synch_base.fastlock, +xnthread_handle (thread)) !=0 ) { +#else /* !CONFIG_XENO_FASTSYNCH */ +if (xnsynch_owner (&mutex->synch_base) != thread) { +#endif /* !CONFIG_XENO_FASTSYNCH */ err = -EPERM ; goto unlock_and_exit; }/* * We can't use rt_mutex_release since that might reschedule -* before enter xnsynch_sleep_on, hence most of the code is -* duplicated here. +* before enter xnsynch_sleep_on. */ lockcnt = mutex->lockcnt;/* Leave even if mutex is nested */ mutex->lockcnt =0 ; -if (xnsynch_release (&mutex->synch_base)) { - mutex->lockcnt =1 ; -/* Scheduling deferred */ - } +xnsynch_release (&mutex->synch_base); +/* Scheduling deferred */ xnsynch_sleep_on (&cond->synch_base, timeout, timeout_mode);
ksrc/skins/native/mutex.c +191 -123
443 lines not on this page · raw message
ksrc/skins/native/syscall.c +56 -14
154 lines not on this page · raw message
src/skins/native/cond.c +30 -0
@@ -41,16 +41,46 @@ int rt_cond_delete(RT_COND *cond)int rt_cond_wait (RT_COND *cond,RT_MUTEX *mutex,RTIME timeout) { +#ifdef CONFIG_XENO_FASTSYNCH +int saved_lockcnt, err; + + saved_lockcnt = mutex->lockcnt; + + err =XENOMAI_SKINCALL4 (__native_muxid, + __native_cond_wait, cond, mutex, +XN_RELATIVE , &timeout); + + mutex->lockcnt = saved_lockcnt; + +return err; + +#else /* !CONFIG_XENO_FASTSYNCH */ return XENOMAI_SKINCALL4 (__native_muxid, __native_cond_wait, cond, mutex,XN_RELATIVE , &timeout); +#endif /* !CONFIG_XENO_FASTSYNCH */ }int rt_cond_wait_until (RT_COND *cond,RT_MUTEX *mutex,RTIME timeout) { +#ifdef CONFIG_XENO_FASTSYNCH +int saved_lockcnt, err; + + saved_lockcnt = mutex->lockcnt; + + err =XENOMAI_SKINCALL4 (__native_muxid, + __native_cond_wait, cond, mutex, +XN_REALTIME , &timeout); + + mutex->lockcnt = saved_lockcnt; + +return err; + +#else /* !CONFIG_XENO_FASTSYNCH */ return XENOMAI_SKINCALL4 (__native_muxid, __native_cond_wait, cond, mutex,XN_REALTIME , &timeout); +#endif /* !CONFIG_XENO_FASTSYNCH */ }int rt_cond_signal (RT_COND *cond)
src/skins/native/mutex.c +94 -8
135 lines not on this page · raw message
Re: [Xenomai-core] [PATCH 08/12] Use fast xnsynch with native skin
Jan Kiszka wrote:
Same remark for the #ifdefs. I also do not understand your modification of rt_cond_wait_inner, this code is very tense; posix and native had the same bug in this area at different times, so this change should probably be made separately.
Signature · 1 line
Gilles.
Re: [Xenomai-core] [PATCH 08/12] Use fast xnsynch with native skin
Quoted 3 lines · Gilles Chanteperdrix
Jan Kiszka wrote:
Same remark for the #ifdefs.
Yes, but most cases (maybe except for owner checking) are unavoidable due to heavy differences. I hope that we may have only FASTXNSYCH archs one day.
Quoted 4 lines
I also do not understand your modification
ofrt_cond_wait_inner, this code is very tense; posix and native had the same bug in this area at different times, so this change should probably be made separately.
Which modification precisely (damn, I need to find out what makes quilt cause this attachment confusion)? Note that lockcnt tracking changed with this patch: the lock owner himself is in charge of maintaining it, not some thread handing the lock over.
That said, I would happily analyse the case that broke before. I will also check if I can break out the lockcnt maintenance change, but I think to recall that it was coupled to the fast path changes.
Jan
Re: [Xenomai-core] [PATCH 08/12] Use fast xnsynch with native skin
Quoted 14 lines · Jan Kiszka
Quoted 3 lines · Gilles Chanteperdrix
Jan Kiszka wrote:
Same remark for the #ifdefs.
Yes, but most cases (maybe except for owner checking) are unavoidable due to heavy differences. I hope that we may have only FASTXNSYCH archs one day.
Quoted 4 lines
I also do not understand your modification
ofrt_cond_wait_inner, this code is very tense; posix and native had the same bug in this area at different times, so this change should probably be made separately.
Quoted 8 lines
Which modification precisely (damn, I need to find out what makes quilt cause this attachment confusion)? Note that lockcnt tracking changed with this patch: the lock owner himself is in charge of maintaining it, not some thread handing the lock over.
That said, I would happily analyse the case that broke before. I will also check if I can break out the lockcnt maintenance change, but I think to recall that it was coupled to the fast path changes.
The point is that in case of rt_cond_wait, the mutex must unlock completely regardless of the current lock count. So, the count is set to 1 before calling the function which unlocks the last level of the recursion count. As far as I can see, you removed the part which sets the counter to 1.
Signature · 1 line
Gilles.
Re: [Xenomai-core] [PATCH 08/12] Use fast xnsynch with native skin
Quoted 22 lines · Gilles Chanteperdrix
Quoted 12 lines · Jan Kiszka
Quoted 3 lines · Gilles Chanteperdrix
Jan Kiszka wrote:
Same remark for the #ifdefs.
Yes, but most cases (maybe except for owner checking) are unavoidable due to heavy differences. I hope that we may have only FASTXNSYCH archs one day.
Quoted 4 lines
I also do not understand your modification
ofrt_cond_wait_inner, this code is very tense; posix and native had the same bug in this area at different times, so this change should probably be made separately.Quoted 8 lines
Which modification precisely (damn, I need to find out what makes quilt cause this attachment confusion)? Note that lockcnt tracking changed with this patch: the lock owner himself is in charge of maintaining it, not some thread handing the lock over.
That said, I would happily analyse the case that broke before. I will also check if I can break out the lockcnt maintenance change, but I think to recall that it was coupled to the fast path changes.
Quoted 6 lines
The point is that in case of
rt_cond_wait, the mutex must unlock completely regardless of the current lock count. So, the count is set to 1 before calling the function which unlocks the last level of the recursion count. As far as I can see, you removed the part which sets the counter to 1.
Don't find that spot. Are we talking about this change or something else?
Quoted 3 lines
ksrc/skins/native/cond.c +0
-0@@ -407,24 +407,26 @@ int rt_cond_wait_inner(RT_COND *cond, RT
...
ksrc/skins/native/cond.c int rt_cond_wait_inner(RT_COND *cond, RT · line 431
Quoted 11 lines
ksrc/skins/native/cond.c +2
-4mutex->lockcnt =0 ; -if (xnsynch_release (&mutex->synch_base)) { - mutex->lockcnt =1 ; -/* Scheduling deferred */ - } +xnsynch_release (&mutex->synch_base); +/* Scheduling deferred */ xnsynch_sleep_on (&cond->synch_base, timeout, timeout_mode);
In case it's the above: That setting of lockcnt is actually on behalf of the new owner (xnsynch_release != NULL => we woke up a new owner). And that has been sanitized in the patch in so far that only the owner manipulates lockcnt, always. If you see a remaining issue in this approach or find a hole in the implementation, please let me know.
Jan
Re: [Xenomai-core] [PATCH 08/12] Use fast xnsynch with native skin
Quoted 44 lines · Jan Kiszka
Quoted 18 lines · Gilles Chanteperdrix
Quoted 17 lines · Jan Kiszka
Quoted 3 lines · Gilles Chanteperdrix
Jan Kiszka wrote:
Same remark for the #ifdefs.
Yes, but most cases (maybe except for owner checking) are unavoidable due to heavy differences. I hope that we may have only FASTXNSYCH archs one day.
Quoted 4 lines
I also do not understand your modification
ofrt_cond_wait_inner, this code is very tense; posix and native had the same bug in this area at different times, so this change should probably be made separately.Which modification precisely (damn, I need to find out what makes quilt cause this attachment confusion)? Note that lockcnt tracking changed with this patch: the lock owner himself is in charge of maintaining it, not some thread handing the lock over.
Quoted 9 lines
Quoted 3 lines
That said, I would happily analyse the case that broke before. I will also check if I can break out the lockcnt maintenance change, but I think to recall that it was coupled to the fast path changes.
The point is that in case of
rt_cond_wait, the mutex must unlock completely regardless of the current lock count. So, the count is set to 1 before calling the function which unlocks the last level of the recursion count. As far as I can see, you removed the part which sets the counter to 1.Don't find that spot. Are we talking about this change or something else?
Quoted 3 lines
ksrc/skins/native/cond.c +0
-0@@ -407,24 +407,26 @@ int rt_cond_wait_inner(RT_COND *cond, RT...
Quoted 9 lines
ksrc/skins/native/cond.c +2
-4mutex->lockcnt =0 ; -if (xnsynch_release (&mutex->synch_base)) { - mutex->lockcnt =1 ; -/* Scheduling deferred */ - } +xnsynch_release (&mutex->synch_base); +/* Scheduling deferred */
Quoted 8 lines
Quoted 2 lines
xnsynch_sleep_on(&cond->synch_base, timeout, timeout_mode);In case it's the above: That setting of lockcnt is actually on behalf of the new owner (
xnsynch_release!= NULL => we woke up a new owner). And that has been sanitized in the patch in so far that only the owner manipulates lockcnt, always. If you see a remaining issue in this approach or find a hole in the implementation, please let me know.
Who sets the lockcnt to 0 if there is no next owner ?
Signature · 1 line
Gilles.
Re: [Xenomai-core] [PATCH 08/12] Use fast xnsynch with native skin
Quoted 52 lines · Gilles Chanteperdrix
Quoted 43 lines · Jan Kiszka
Quoted 18 lines · Gilles Chanteperdrix
Quoted 17 lines · Jan Kiszka
Quoted 3 lines · Gilles Chanteperdrix
Jan Kiszka wrote:
Same remark for the #ifdefs.
Yes, but most cases (maybe except for owner checking) are unavoidable due to heavy differences. I hope that we may have only FASTXNSYCH archs one day.
Quoted 4 lines
I also do not understand your modification
ofrt_cond_wait_inner, this code is very tense; posix and native had the same bug in this area at different times, so this change should probably be made separately.Which modification precisely (damn, I need to find out what makes quilt cause this attachment confusion)? Note that lockcnt tracking changed with this patch: the lock owner himself is in charge of maintaining it, not some thread handing the lock over.
Quoted 9 lines
Quoted 3 lines
That said, I would happily analyse the case that broke before. I will also check if I can break out the lockcnt maintenance change, but I think to recall that it was coupled to the fast path changes.
The point is that in case of
rt_cond_wait, the mutex must unlock completely regardless of the current lock count. So, the count is set to 1 before calling the function which unlocks the last level of the recursion count. As far as I can see, you removed the part which sets the counter to 1.Don't find that spot. Are we talking about this change or something else?
Quoted 3 lines
ksrc/skins/native/cond.c +0
-0@@ -407,24 +407,26 @@ int rt_cond_wait_inner(RT_COND *cond, RT...
Quoted 9 lines
ksrc/skins/native/cond.c +2
-4mutex->lockcnt =0 ; -if (xnsynch_release (&mutex->synch_base)) { - mutex->lockcnt =1 ; -/* Scheduling deferred */ - } +xnsynch_release (&mutex->synch_base); +/* Scheduling deferred */ Quoted 7 lines
Quoted 2 lines
xnsynch_sleep_on(&cond->synch_base, timeout, timeout_mode);In case it's the above: That setting of lockcnt is actually on behalf of the new owner (
xnsynch_release!= NULL => we woke up a new owner). And that has been sanitized in the patch in so far that only the owner manipulates lockcnt, always. If you see a remaining issue in this approach or find a hole in the implementation, please let me know.
Quoted 1 line
Who sets the lockcnt to 0 if there is no next owner ?
Look up, only a few lines...
Jan
Re: [Xenomai-core] [PATCH 08/12] Use fast xnsynch with native skin
In reply to Gilles ChanteperdrixQuoted 52 lines · Gilles Chanteperdrix
Quoted 43 lines · Jan Kiszka
Quoted 18 lines · Gilles Chanteperdrix
Quoted 17 lines · Jan Kiszka
Quoted 3 lines · Gilles Chanteperdrix
Jan Kiszka wrote:
Same remark for the #ifdefs.
Yes, but most cases (maybe except for owner checking) are unavoidable due to heavy differences. I hope that we may have only FASTXNSYCH archs one day.
Quoted 4 lines
I also do not understand your modification
ofrt_cond_wait_inner, this code is very tense; posix and native had the same bug in this area at different times, so this change should probably be made separately.Which modification precisely (damn, I need to find out what makes quilt cause this attachment confusion)? Note that lockcnt tracking changed with this patch: the lock owner himself is in charge of maintaining it, not some thread handing the lock over.
Quoted 9 lines
Quoted 3 lines
That said, I would happily analyse the case that broke before. I will also check if I can break out the lockcnt maintenance change, but I think to recall that it was coupled to the fast path changes.
The point is that in case of
rt_cond_wait, the mutex must unlock completely regardless of the current lock count. So, the count is set to 1 before calling the function which unlocks the last level of the recursion count. As far as I can see, you removed the part which sets the counter to 1.Don't find that spot. Are we talking about this change or something else?
Quoted 3 lines
ksrc/skins/native/cond.c +0
-0@@ -407,24 +407,26 @@ int rt_cond_wait_inner(RT_COND *cond, RT...
Quoted 9 lines
ksrc/skins/native/cond.c +2
-4mutex->lockcnt =0 ; -if (xnsynch_release (&mutex->synch_base)) { - mutex->lockcnt =1 ; -/* Scheduling deferred */ - } +xnsynch_release (&mutex->synch_base); +/* Scheduling deferred */ Quoted 7 lines
Quoted 2 lines
xnsynch_sleep_on(&cond->synch_base, timeout, timeout_mode);In case it's the above: That setting of lockcnt is actually on behalf of the new owner (
xnsynch_release!= NULL => we woke up a new owner). And that has been sanitized in the patch in so far that only the owner manipulates lockcnt, always. If you see a remaining issue in this approach or find a hole in the implementation, please let me know.
Quoted 1 line
Who sets the lockcnt to 0 if there is no next owner ?
Ok. It appears in the code you quoted. However, your modification changes the behaviour of the mutex code:
with the old version, the mutex will appear locked if an owner has been woken up
with the new version, the mutex will appear unlocked between the time when a new owner has been woken up and the time this new owner gets out of xnsynch_acquire, allowing the lock to be stolen by another thread.
Signature · 1 line
Gilles.
Re: [Xenomai-core] [PATCH 08/12] Use fast xnsynch with native skin
Quoted 54 lines · Gilles Chanteperdrix
Quoted 44 lines · Gilles Chanteperdrix
Quoted 43 lines · Jan Kiszka
Quoted 18 lines · Gilles Chanteperdrix
Quoted 17 lines · Jan Kiszka
Quoted 3 lines · Gilles Chanteperdrix
Jan Kiszka wrote:
Same remark for the #ifdefs.
Yes, but most cases (maybe except for owner checking) are unavoidable due to heavy differences. I hope that we may have only FASTXNSYCH archs one day.
Quoted 4 lines
I also do not understand your modification
ofrt_cond_wait_inner, this code is very tense; posix and native had the same bug in this area at different times, so this change should probably be made separately.Which modification precisely (damn, I need to find out what makes quilt cause this attachment confusion)? Note that lockcnt tracking changed with this patch: the lock owner himself is in charge of maintaining it, not some thread handing the lock over.
Quoted 9 lines
Quoted 3 lines
That said, I would happily analyse the case that broke before. I will also check if I can break out the lockcnt maintenance change, but I think to recall that it was coupled to the fast path changes.
The point is that in case of
rt_cond_wait, the mutex must unlock completely regardless of the current lock count. So, the count is set to 1 before calling the function which unlocks the last level of the recursion count. As far as I can see, you removed the part which sets the counter to 1.Don't find that spot. Are we talking about this change or something else?
Quoted 3 lines
ksrc/skins/native/cond.c +0
-0@@ -407,24 +407,26 @@ int rt_cond_wait_inner(RT_COND *cond, RT...
Quoted 9 lines
ksrc/skins/native/cond.c +2
-4mutex->lockcnt =0 ; -if (xnsynch_release (&mutex->synch_base)) { - mutex->lockcnt =1 ; -/* Scheduling deferred */ - } +xnsynch_release (&mutex->synch_base); +/* Scheduling deferred */ Quoted 8 lines
Quoted 7 lines
Quoted 2 lines
xnsynch_sleep_on(&cond->synch_base, timeout, timeout_mode);In case it's the above: That setting of lockcnt is actually on behalf of the new owner (
xnsynch_release!= NULL => we woke up a new owner). And that has been sanitized in the patch in so far that only the owner manipulates lockcnt, always. If you see a remaining issue in this approach or find a hole in the implementation, please let me know.Who sets the lockcnt to 0 if there is no next owner ?
Quoted 8 lines
Ok. It appears in the code you quoted. However, your modification changes the behaviour of the mutex code:
with the old version, the mutex will appear locked if an owner has been woken up
with the new version, the mutex will appear unlocked between the time when a new owner has been woken up and the time this new owner gets out ofxnsynch_acquire, allowing the lock to be stolen by another thread.
But that is what cond_wait is about: releasing the associated lock to whoever gets it - either directly or via lock-stealing. I see no problem here. Moreover, lockcnt is never used (and must not!) as an indication if a lock is free. It is a pure helper for the lock owner to track recursion. And it is also no longer consistent between kernel and user side, another reason to allow only the lock owner to play with it.
Jan
Re: [Xenomai-core] [PATCH 08/12] Use fast xnsynch with native skin
Quoted 6 lines · Jan Kiszka
But that is what
cond_waitis about: releasing the associated lock to whoever gets it - either directly or via lock-stealing. I see no problem here. Moreover, lockcnt is never used (and must not!) as an indication if a lock is free. It is a pure helper for the lock owner to track recursion. And it is also no longer consistent between kernel and user side, another reason to allow only the lock owner to play with it.
Right.
Signature · 1 line
Gilles.
PATCH 9/12 Optionally replace pthread_getspecific with TLS variables
In reply to Jan KiszkaOn architectures that support the __thread storage class and the initial-exec TLS model, several use cases of pthread_get/setspecific can be optimized. On x86, e.g., we are able to implement xeno_get_current() via just two instructions instead of a call into glibc and all the included pthread_key lookup. The minor downside of initial-exec TLS is that libraries using such variables are excluded from dlopen.
This patch adds the required check to configure, also installing a switch (--without-__thread) in order to disable the support if dlopen compatibility should be required. It adds a __thread-variant for xeno_get_current and self-references of the current Native, VRTX and VxWorks tasks.
RTDK's rt_printf services are intentionally not converted as they are heavy-weighted anyway and depend on the pthread_key destructor mechanism.
--- configure.in | 23 +++++++++++++++++++ include/asm-generic/bits/bind.h | 44 ++++++++++++++++++++++++++----------- include/asm-generic/bits/current.h | 13 +++++++++- src/skins/native/init.c | 8 +++++- src/skins/native/task.c | 21 +++++++++++++++++ src/skins/vrtx/init.c | 8 +++++- src/skins/vrtx/task.c | 14 ++++++++++- src/skins/vxworks/init.c | 8 +++++- src/skins/vxworks/taskLib.c | 20 +++++++++++++++- 9 files changed, 137 insertions(+), 22 deletions(-)
configure.in +23 -0
@@ -762,6 +762,29 @@ LIBS="$LIBS -lrt" AC_CHECK_FUNCS([shm_open shm_unlink]) LIBS="$save_LIBS" +AC_ARG_WITH([__thread], + AC_HELP_STRING([--without-__thread], + [do not use TLS features (allows for dlopen'ing Xenomai libs)]), + [use__thread=$withval], + [use__thread=yes]) + +dnl Check whether the compiler supports the __thread keyword. +if test "x$use__thread" != xno; then + AC_CACHE_CHECK([for __thread], libc_cv_gcc___thread, + [cat > conftest.c <<\EOF +__thread int a __attribute__ ((tls_model ("initial-exec"))) = 42; +EOF + if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -c -Werror conftest.c >&AS_MESSAGE_LOG_FD]); then + libc_cv_gcc___thread=yes + else + libc_cv_gcc___thread=no + fi + rm -f conftest*]) + if test "$libc_cv_gcc___thread" = yes; then + AC_DEFINE(HAVE___THREAD,1,[config]) + fi +fi + dnl dnl Build the Makefiles dnl
include/asm-generic/bits/bind.h +32 -12
78 lines not on this page · raw message
include/asm-generic/bits/current.h +11 -2
@@ -4,13 +4,22 @@#include <pthread.h> #include <nucleus/types.h> -extern pthread_key_t xeno_current_key; +#ifdef HAVE___THREAD +extern __thread xnhandle_t xeno_current __attribute__ ((tls_model ("initial-exec"))); -extern void xeno_set_current (void ); +static inline xnhandle_t xeno_get_current (void ) +{ +return xeno_current; +} +#else /* ! HAVE___THREAD */ +extern pthread_key_t xeno_current_key;static inline xnhandle_t xeno_get_current (void ) {return (xnhandle_t )pthread_getspecific (xeno_current_key); } +#endif /* ! HAVE___THREAD */ + +extern void xeno_set_current (void );#endif /* _XENO_ASM_GENERIC_CURRENT_H */
src/skins/native/init.c +6 -2
@@ -27,16 +27,18 @@#include <asm-generic/bits/bind.h> #include <asm-generic/bits/mlock_alert.h> -pthread_key_t __native_tskey; -int __native_muxid =-1 ;void native_timer_init (int ); +#ifndef HAVE___THREAD +pthread_key_t __native_tskey; +static void __flush_tsd (void *tsd) {/* Free the task descriptor allocated by rt_task_self(). */ free (tsd); } +#endif /* !HAVE___THREAD */ static __attribute__ ((constructor))void __init_xeno_interface (void )
@@ -50,10 +52,12 @@ void __init_xeno_interface(void) __native_muxid =__xn_mux_shifted_id (__native_muxid); +#ifndef HAVE___THREAD /* Allocate a TSD key for indexing self task pointers. */ if (pthread_key_create (&__native_tskey, &__flush_tsd) !=0 ) {fprintf (stderr,"Xenomai: failed to allocate new TSD key?!\n" );exit (1 ); } +#endif /* !HAVE___THREAD */ }
src/skins/native/task.c +21 -0
@@ -29,7 +29,14 @@#include <asm-generic/bits/current.h> #include "wrappers.h" +#ifdef HAVE___THREAD +__thread RT_TASK __native_self __attribute__ ((tls_model ("initial-exec"))) = { + .opaque = XN_NO_HANDLE, + .opaque2 = 0 +}; +#else /* !HAVE___THREAD */ extern pthread_key_t __native_tskey; +#endif /* !HAVE___THREAD */ extern int __native_muxid;
@@ -91,6 +98,10 @@ static void *rt_task_trampoline(void *coxeno_set_current (); +#ifdef HAVE___THREAD + __native_self = *iargs->task; +#endif /* HAVE___THREAD */ +/* Wait on the barrier for the task to be started. The barrier could be released in order to process Linux signals while the Xenomai shadow is still dormant; in such a case, resume wait. */
@@ -316,6 +327,15 @@ RT_TASK *rt_task_self(void) {RT_TASK *self; +#ifdef HAVE___THREAD + self = &__native_self; + +if (self->opaque ==XN_NO_HANDLE ) +return NULL ; + +#else /* !HAVE___THREAD */ +RT_TASK *self; + self = (RT_TASK *)pthread_getspecific (__native_tskey);if (self)
@@ -330,6 +350,7 @@ RT_TASK *rt_task_self(void) }pthread_setspecific (__native_tskey, self); +#endif /* !HAVE___THREAD */ return self; }
src/skins/vxworks/init.c +6 -2
@@ -26,15 +26,17 @@#include <asm-generic/bits/bind.h> #include <asm-generic/bits/mlock_alert.h> -pthread_key_t __vxworks_tskey; -int __vxworks_muxid =-1 ; +#ifndef HAVE___THREAD +pthread_key_t __vxworks_tskey; +static void __flush_tsd (void *tsd) {/* Free the task descriptor allocated by taskIdSelf(). */ free (tsd); } +#endif /* !HAVE___THREAD */ static __attribute__ ((constructor))void __init_xeno_interface (void )
@@ -43,10 +45,12 @@ void __init_xeno_interface(void) "vxworks", "xeno_vxworks"); __vxworks_muxid =__xn_mux_shifted_id (__vxworks_muxid); +#ifndef HAVE___THREAD /* Allocate a TSD key for indexing self task pointers. */ if (pthread_key_create (&__vxworks_tskey, &__flush_tsd) !=0 ) {fprintf (stderr,"Xenomai: failed to allocate new TSD key?!\n" );exit (1 ); } +#endif /* !HAVE___THREAD */ }
src/skins/vxworks/taskLib.c +19 -1
@@ -30,7 +30,14 @@#include <asm-generic/bits/current.h> #include "wrappers.h" +#ifdef HAVE___THREAD +__threadWIND_TCB +__vxworks_self __attribute__ ((tls_model ("initial-exec"))) = { + .handle = XN_NO_HANDLE +}; +#else /* !HAVE___THREAD */ extern pthread_key_t __vxworks_tskey; +#endif /* !HAVE___THREAD */ extern int __vxworks_muxid;
@@ -120,6 +127,10 @@ static void *wind_task_trampoline(void *xeno_set_current (); +#ifdef HAVE___THREAD + __vxworks_self = *iargs->pTcb; +#endif /* HAVE___THREAD */ +/* Wait on the barrier for the task to be started. The barrier could be released in order to process Linux signals while the Xenomai shadow is still dormant; in such a case, resume wait. */
@@ -309,9 +320,15 @@ STATUS taskResume(TASK_ID task_id)TASK_ID taskIdSelf (void ) { -WIND_TCB *self = (WIND_TCB *)pthread_getspecific (__vxworks_tskey); +#ifdef HAVE___THREAD +return __vxworks_self.handle; + +#else /* !HAVE___THREAD */ +WIND_TCB *self;int err; + self = (WIND_TCB *)pthread_getspecific (__vxworks_tskey); +if (self)return self->handle;
@@ -332,6 +349,7 @@ TASK_ID taskIdSelf(void)pthread_setspecific (__vxworks_tskey, self);return self->handle; +#endif /* !HAVE___THREAD */ }STATUS taskPrioritySet (TASK_ID task_id,int prio)
src/skins/vrtx/init.c +6 -2
@@ -26,15 +26,17 @@#include <asm-generic/bits/bind.h> #include <asm-generic/bits/mlock_alert.h> -pthread_key_t __vrtx_tskey; -int __vrtx_muxid =-1 ; +#ifndef HAVE___THREAD +pthread_key_t __vrtx_tskey; +static void __flush_tsd (void *tsd) {/* Free the TCB struct. */ free (tsd); } +#endif /* !HAVE___THREAD */ static __attribute__ ((constructor))void __init_xeno_interface (void )
@@ -43,10 +45,12 @@ void __init_xeno_interface(void)xeno_bind_skin (VRTX_SKIN_MAGIC ,"vrtx" ,"xeno_vrtx" ); __vrtx_muxid =__xn_mux_shifted_id (__vrtx_muxid); +#ifndef HAVE___THREAD /* Allocate a TSD key for indexing self task pointers. */ if (pthread_key_create (&__vrtx_tskey, &__flush_tsd) !=0 ) {fprintf (stderr,"Xenomai: failed to allocate new TSD key?!\n" );exit (1 ); } +#endif /* !HAVE___THREAD */ }
src/skins/vrtx/task.c +13 -1
@@ -29,7 +29,11 @@#include <vrtx/vrtx.h> #include <asm-generic/bits/current.h> +#ifdef HAVE___THREAD +__thread TCB __vrtx_tcb __attribute__ ((tls_model ("initial-exec"))); +#else /* !HAVE___THREAD */ extern pthread_key_t __vrtx_tskey; +#endif /* !HAVE___THREAD */ extern int __vrtx_muxid;
@@ -81,7 +85,9 @@ static void *vrtx_task_trampoline(void *struct sched_param param;int policy;long err; +#ifndef HAVE___THREAD TCB *tcb; +#endif /* !HAVE___THREAD */ /* Backup the arg struct, it might vanish after completion. */ memcpy (&_iargs, iargs,sizeof (_iargs));
@@ -96,6 +102,7 @@ static void *vrtx_task_trampoline(void */* vrtx_task_delete requires asynchronous cancellation */ pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS ,NULL ); +#ifndef HAVE___THREAD tcb = (TCB *)malloc (sizeof (*tcb));if (tcb ==NULL ) {fprintf (stderr,"Xenomai: failed to allocate local TCB?!\n" );
@@ -104,6 +111,7 @@ static void *vrtx_task_trampoline(void * }pthread_setspecific (__vrtx_tskey, tcb); +#endif /* !HAVE___THREAD */ old_sigharden_handler =signal (SIGHARDEN , &vrtx_task_sigharden);
@@ -224,7 +232,11 @@ TCB *sc_tinquiry(int pinfo[], int tid, i {TCB *tcb; - tcb = (TCB *)pthread_getspecific (__vrtx_tskey);/* Cannot fail. */ +#ifdef HAVE___THREAD + tcb = &__vrtx_tcb; +#else /* !HAVE___THREAD */ + tcb = (TCB *)pthread_getspecific (__vrtx_tskey);/* Cannot fail. */ +#endif /* !HAVE___THREAD */ *errp =XENOMAI_SKINCALL3 (__vrtx_muxid, __vrtx_tinquiry, pinfo, tcb, tid);
Re: [Xenomai-core] [PATCH 09/12] Optionally replace pthread_getspecific with TLS variables
Jan Kiszka wrote:
The real downside here is a lot of #ifdef clutter. What about the idea of defining an API to abstract the differences between pthread_get/setspecific and __thread and have #ifdef only in one header ?
Signature · 1 line
Gilles.
Re: [Xenomai-core] [PATCH 09/12] Optionally replace pthread_getspecific with TLS variables
Quoted 5 lines · Gilles Chanteperdrix
Jan Kiszka wrote:
The real downside here is a lot of #ifdef clutter. What about the idea of defining an API to abstract the differences between pthread_get/setspecific and
__threadand have #ifdef only in one header ?
Sometimes you only store a value that way, sometimes you also have to provide the object that is stored. Then its initialisation is fairly specific.
Everything can be abstracted, but I'm not that optimistic that the result will be better readable, just look at the patched users. Or what abstractions do you have in mind?
Jan
Re: [Xenomai-core] [PATCH 09/12] Optionally replace pthread_getspecific with TLS variables
Quoted 7 lines · Jan Kiszka
Quoted 5 lines · Gilles Chanteperdrix
Jan Kiszka wrote:
The real downside here is a lot of #ifdef clutter. What about the idea of defining an API to abstract the differences between pthread_get/setspecific and
__threadand have #ifdef only in one header ?
Quoted 7 lines
Sometimes you only store a value that way, sometimes you also have to provide the object that is stored. Then its initialisation is fairly specific.
Everything can be abstracted, but I'm not that optimistic that the result will be better readable, just look at the patched users. Or what abstractions do you have in mind?
I tried, but I failed. The usage differences in the skins are to significant to define a generic per-thread wrapper that fits at least a subset of use cases.
Anyway, I was at least able to eliminate two #ifdefs by converting the xeno_current_key initialization from pthread_once to a constructor function (that is under #ifdef anyway). Updates will follow.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT SE 2 Corporate Competence Center Embedded Linux
PATCH 10/12 Report current shadow thread mode to user space
In reply to Jan KiszkaWith this patch applied, the Xenomai skin libraries are able to obtain the execution mode the current thread without issuing a syscall. The kernel-user interface looks as follows:
- On thread creation (which triggers xnshadow_map), user space passes a pointer to an unsigned long.
- Before going primary and after completing the switch to secondary mode, the nucleus writes 0 or XNRELAX to that unsigned long. The mode updates use __xn_put_user, so they are fail-safe (write errors are ignored, only an initial access_wok check is reported back).
- User space can check its state by calling xeno_get_current_mode(). An optional light-weight version based on __thread is also provided.
--- include/asm-generic/bits/bind.h | 29 +++++++++++++++++++++++++---- include/asm-generic/bits/current.h | 20 ++++++++++++++++++++ include/native/syscall.h | 1 + include/nucleus/shadow.h | 3 ++- include/nucleus/thread.h | 4 ++++ include/psos+/syscall.h | 8 ++++++++ include/vrtx/syscall.h | 1 + include/vxworks/syscall.h | 1 + ksrc/nucleus/shadow.c | 22 ++++++++++++++++++++-- ksrc/skins/native/syscall.c | 3 ++- ksrc/skins/posix/syscall.c | 14 +++++++++----- ksrc/skins/psos+/syscall.c | 34 +++++++++++++++++++++------------- ksrc/skins/uitron/syscall.c | 8 ++++++-- ksrc/skins/vrtx/syscall.c | 4 +++- ksrc/skins/vxworks/syscall.c | 4 +++- src/skins/native/task.c | 10 ++++++++++ src/skins/posix/thread.c | 33 +++++++++++++++++++++++++++++++-- src/skins/psos+/task.c | 16 +++++++++++++--- src/skins/uitron/task.c | 11 +++++++++-- src/skins/vrtx/task.c | 6 ++++++ src/skins/vxworks/taskLib.c | 6 ++++++ 21 files changed, 201 insertions(+), 37 deletions(-)
include/native/syscall.h +1 -0
@@ -134,6 +134,7 @@ struct rt_arg_bulk {u_long a3;u_long a4;u_long a5; +u_long a6; };#ifdef __KERNEL__
include/nucleus/shadow.h +2 -1
@@ -69,7 +69,8 @@ void xnshadow_grab_events(void);void xnshadow_release_events (void );int xnshadow_map (struct xnthread *thread, -xncompletion_t __user *u_completion); +xncompletion_t __user *u_completion, +unsigned long __user *u_mode);void xnshadow_unmap (struct xnthread *thread);
include/nucleus/thread.h +4 -0
@@ -248,6 +248,10 @@ 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. */ +#endif /* CONFIG_XENO_OPT_PERVASIVE */ +XNARCH_DECL_DISPLAY_CONTEXT (); } xnthread_t;
ksrc/nucleus/shadow.c +20 -2
@@ -1079,6 +1079,8 @@ redo:/* Grab the request token. */ return -ERESTARTSYS ; +__xn_put_user (0 , thread->u_mode); +preempt_disable ();/* Assume that we might have been migrated while waiting for
@@ -1250,6 +1252,8 @@ void xnshadow_relax(int notify)/* "current" is now running into the Linux domain on behalf of the root thread. */ +__xn_put_user (XNRELAX , thread->u_mode); +trace_mark (xn_nucleus_shadow_relaxed,"thread %p thread_name %s comm %s" , thread,xnthread_name (thread), current->comm);
@@ -1264,7 +1268,9 @@ void xnshadow_exit(void) }/*! -* \fn int xnshadow_map(xnthread_t *thread, xncompletion_t __user *u_completion) +* \fn int xnshadow_map(xnthread_t *thread, +* xncompletion_t __user *u_completion, +* unsigned long __user *u_mode) * @internal * \brief Create a shadow thread context. *
@@ -1288,6 +1294,11 @@ 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. +* * @return 0 is returned on success. Otherwise: * * - -ERESTARTSYS is returned if the current Linux task has received a
@@ -1313,7 +1324,8 @@ void xnshadow_exit(void)* */ -int xnshadow_map (xnthread_t *thread,xncompletion_t __user *u_completion) +int xnshadow_map (xnthread_t *thread,xncompletion_t __user *u_completion, +unsigned long __user *u_mode) {xnarch_cpumask_t affinity;unsigned muxid, magic;
@@ -1325,6 +1337,9 @@ int xnshadow_map(xnthread_t *thread, xncif (xnthread_test_state (thread,XNMAPPED ))return -EINVAL ; +if (!access_wok (u_mode,sizeof (*u_mode))) +return -EFAULT ; +#ifdef CONFIG_MMU if (!(current->mm->def_flags &VM_LOCKED ))send_sig (SIGXCPU , current,1 );
@@ -1385,6 +1400,9 @@ int xnshadow_map(xnthread_t *thread, xncif (err)return err; + thread->u_mode = u_mode; +__xn_put_user (XNRELAX , u_mode); + err =xnshadow_harden (); xnarch_trace_pid(xnarch_user_pid(xnthread_archtcb(thread)),
ksrc/skins/native/syscall.c +2 -1
@@ -191,7 +191,8 @@ static int __rt_task_create(struct pt_reif (__xn_safe_copy_to_user ((void __user *)bulk.a1, &ph,sizeof (ph))) err = -EFAULT ;else { - err =xnshadow_map (&task->thread_base, u_completion); + err =xnshadow_map (&task->thread_base, u_completion, + (unsigned long __user *)bulk.a6);if (!err) goto out; }
ksrc/skins/posix/syscall.c +9 -5
@@ -180,7 +180,8 @@ static int __pthread_create(struct pt_reif (err)return -err;/* Conventionally, our error codes are negative. */ - err =xnshadow_map (&k_tid->threadbase,NULL ); + err =xnshadow_map (&k_tid->threadbase,NULL , + (unsigned long __user *)__xn_reg_arg2 (regs));if (!err && !__pthread_hash (&hkey, k_tid)) err = -ENOMEM ;
@@ -196,7 +197,8 @@ static int __pthread_create(struct pt_re#define __pthread_detach __pse51_call_not_availablestatic pthread_t __pthread_shadow (struct task_struct *p, -struct pse51_hkey *hkey) +struct pse51_hkey *hkey, +unsigned long __user *u_mode) {pthread_attr_t attr;pthread_t k_tid;
@@ -211,7 +213,7 @@ static pthread_t __pthread_shadow(structif (err)return ERR_PTR (-err); - err =xnshadow_map (&k_tid->threadbase,NULL ); + err =xnshadow_map (&k_tid->threadbase,NULL , u_mode);if (!err && !__pthread_hash (hkey, k_tid)) err = -EAGAIN ;
@@ -227,11 +229,13 @@ static pthread_t __pthread_shadow(structstatic int __pthread_setschedparam (struct pt_regs *regs) {int policy, err, promoted =0 ; +unsigned long __user *u_mode;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);if (__xn_safe_copy_from_user (¶m, (void __user *)__xn_reg_arg3 (regs),sizeof (param)))
@@ -241,10 +245,10 @@ static int __pthread_setschedparam(struc hkey.mm = current->mm; k_tid =__pthread_find (&hkey); -if (!k_tid &&__xn_reg_arg1 (regs) ==__xn_reg_arg4 (regs)) { +if (!k_tid && u_mode) {/* If the syscall applies to "current", and the latter is not a Xenomai thread already, then shadow it. */ - k_tid =__pthread_shadow (current, &hkey); + k_tid =__pthread_shadow (current, &hkey, u_mode);if (IS_ERR (k_tid))return PTR_ERR (k_tid);
ksrc/skins/psos+/syscall.c +21 -13
@@ -60,11 +60,14 @@ static psostask_t *__psos_task_current(s }/* -* int __t_create(const char *name, -* u_long prio, -* u_long flags, +* int __t_create(struct psos_arg_bulk *bulk, * u_long *tid_r, * xncompletion_t *completion) +* bulk = { +* a1: const char *name; +* a2: u_long prio; +* a3: u_long flags; +* a4: unsigned long *mode; */ static int __t_create (struct pt_regs *regs)
@@ -73,10 +76,15 @@ static int __t_create(struct pt_regs *restruct task_struct *p = current;u_long prio, flags, tid, err;char name[XNOBJECT_NAME_LEN ]; +struct psos_arg_bulk bulk;psostask_t *task; +if (__xn_safe_copy_from_user (&bulk, (void __user *)__xn_reg_arg1 (regs), +sizeof (bulk))) +return -EFAULT ; +/* Get task name. */ -if (__xn_safe_strncpy_from_user (name, (const char __user *)__xn_reg_arg1 (regs), +if (__xn_safe_strncpy_from_user (name, (const char __user *)bulk.a1,sizeof (name) -1 ) <0 )return -EFAULT ;
@@ -85,12 +93,12 @@ static int __t_create(struct pt_regs *re p->comm[sizeof (p->comm) -1 ] ='\0' ;/* Task priority. */ - prio =__xn_reg_arg2 (regs); + prio = bulk.a2;/* Task flags. Force FPU support in user-space. This will lead to a no-op if the platform does not support it. */ - flags =__xn_reg_arg3 (regs) |T_SHADOW |T_FPU ; + flags = bulk.a3 |T_SHADOW |T_FPU ;/* Completion descriptor our parent thread is pending on. */ - u_completion = (xncompletion_t __user *)__xn_reg_arg5 (regs); + u_completion = (xncompletion_t __user *)__xn_reg_arg3 (regs); err =t_create (name, prio,0 ,0 , flags, &tid);
@@ -100,14 +108,14 @@ static int __t_create(struct pt_regs *re* about the new thread id, so we can manipulate its * TCB pointer freely. */ tid =xnthread_handle (&task->threadbase); -if (__xn_safe_copy_to_user ((void __user *)__xn_reg_arg4 (regs), &tid, +if (__xn_safe_copy_to_user ((void __user *)__xn_reg_arg2 (regs), &tid,sizeof (tid)))return -EFAULT ; -else { - err =xnshadow_map (&task->threadbase, u_completion);/* May be NULL */ -if (!err) - goto out; - } + + err =xnshadow_map (&task->threadbase, u_completion, + (unsigned long __user *)bulk.a4); +if (!err) + goto out;t_delete ((u_long )task); }
ksrc/skins/vrtx/syscall.c +3 -1
@@ -48,6 +48,7 @@ static int __muxid;* a1: int tid; * a2: int prio; * a3: int mode; +* a4: unsigned long *shadow_mode; * } */
@@ -89,7 +90,8 @@ static int __sc_tecreate(struct pt_regs &tid, sizeof(tid))) err = -EFAULT; else { - err =xnshadow_map (&task->threadbase, u_completion); + err =xnshadow_map (&task->threadbase, u_completion, + (unsigned long __user *)bulk.a4);if (!err) goto done; }
ksrc/skins/vxworks/syscall.c +3 -1
@@ -66,6 +66,7 @@ static WIND_TCB *__wind_task_current(str* a2: int prio; * a3: int flags; * a4: pthread_self(); +* a5: unsigned long *mode; * } */
@@ -124,7 +125,8 @@ static int __wind_task_init(struct pt_re sizeof(ph))) err = -EFAULT; else { - err =xnshadow_map (&task->threadbase, u_completion); + err =xnshadow_map (&task->threadbase, u_completion, + (unsigned long __user *)bulk.a5);if (!err) goto out; }
ksrc/skins/uitron/syscall.c +6 -2
@@ -31,13 +31,15 @@int __ui_muxid;/* -* int __uitron_cre_tsk(ID tskid, T_CTSK *pk_ctsk, xncompletion_t *completion) +* int __uitron_cre_tsk(ID tskid, T_CTSK *pk_ctsk, xncompletion_t *completion, +* unsigned long *mode) */ static int __ui_cre_tsk (struct pt_regs *regs) {xncompletion_t __user *u_completion;struct task_struct *p = current; +unsigned long __user *u_mode;uitask_t *task;T_CTSK pk_ctsk;ID tskid;
@@ -54,6 +56,8 @@ static int __ui_cre_tsk(struct pt_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); + err =cre_tsk (tskid, &pk_ctsk);if (likely (err ==E_OK )) {
@@ -74,7 +78,7 @@ static int __ui_cre_tsk(struct pt_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);/* May be NULL */ +return xnshadow_map (&task->threadbase, u_completion, u_mode); } fail:
include/asm-generic/bits/bind.h +25 -4
@@ -17,6 +17,8 @@#ifdef HAVE___THREAD __thread xnhandle_t xeno_current __attribute__ ((tls_model ("initial-exec"))) = XN_NO_HANDLE; +__threadunsigned long +xeno_current_mode __attribute__ ((tls_model ("initial-exec")));static inline void __xeno_set_current (xnhandle_t current) {
@@ -26,17 +28,36 @@ static inline void __xeno_set_current(xn __attribute__ ((weak))pthread_key_t xeno_current_key; __attribute__ ((weak)) -pthread_once_t xeno_init_current_key_once =PTHREAD_ONCE_INIT ; +pthread_key_t xeno_current_mode_key; +__attribute__ ((weak)) +pthread_once_t xeno_init_current_keys_once =PTHREAD_ONCE_INIT ;static inline void __xeno_set_current (xnhandle_t current) {pthread_setspecific (xeno_current_key, (void *)current); } -static void init_current_key (void ) +unsigned long *xeno_init_current_mode (void ) +{ +unsigned long *mode =malloc (sizeof (unsigned long )); +pthread_setspecific (xeno_current_mode_key, mode); +return mode; +} + +static void cleanup_current_mode (void *ptr) +{ +free (ptr); +} + +static void init_current_keys (void ) {int err =pthread_key_create (&xeno_current_key,NULL ); +if (err) + goto error_exit; + + err =pthread_key_create (&xeno_current_mode_key, cleanup_current_mode);if (err) { + error_exit:fprintf (stderr,"Xenomai: error creating TSD key: %s\n" ,strerror (err));exit (1 );
@@ -192,7 +213,7 @@ xeno_bind_skin(unsigned skin_magic, conssigaction (SIGXCPU , &sa,NULL );#ifndef HAVE___THREAD -pthread_once (&xeno_init_current_key_once, &init_current_key); +pthread_once (&xeno_init_current_keys_once, &init_current_keys);#endif /* !HAVE___THREAD */ #ifdef CONFIG_XENO_FASTSYNCH
@@ -270,7 +291,7 @@ xeno_bind_skin_opt(unsigned skin_magic,#endif /* xeno_arch_features_check */ #ifndef HAVE___THREAD -pthread_once (&xeno_init_current_key_once, &init_current_key); +pthread_once (&xeno_init_current_keys_once, &init_current_keys);#endif /* !HAVE___THREAD */ #ifdef CONFIG_XENO_FASTSYNCH
include/asm-generic/bits/current.h +20 -0
@@ -6,18 +6,38 @@#ifdef HAVE___THREAD extern __thread xnhandle_t xeno_current __attribute__ ((tls_model ("initial-exec"))); +extern __threadunsigned long +xeno_current_mode __attribute__ ((tls_model ("initial-exec")));static inline xnhandle_t xeno_get_current (void ) {return xeno_current; } + +static inline unsigned long xeno_get_current_mode (void ) +{ +return xeno_current_mode; +} + +static inline unsigned long *xeno_init_current_mode (void ) +{ +return &xeno_current_mode; +}#else /* ! HAVE___THREAD */ extern pthread_key_t xeno_current_key; +extern pthread_key_t xeno_current_mode_key;static inline xnhandle_t xeno_get_current (void ) {return (xnhandle_t )pthread_getspecific (xeno_current_key); } + +static inline unsigned long xeno_get_current_mode (void ) +{ +return *(unsigned long *)pthread_getspecific (xeno_current_mode_key); +} + +extern unsigned long *xeno_init_current_mode (void );#endif /* ! HAVE___THREAD */ extern void xeno_set_current (void );
src/skins/native/task.c +10 -0
@@ -89,6 +89,12 @@ static void *rt_task_trampoline(void *co bulk.a3 = (u_long )iargs->prio; bulk.a4 = (u_long )iargs->mode; bulk.a5 = (u_long )pthread_self (); + bulk.a6 = (u_long )xeno_init_current_mode (); + +if (!bulk.a6) { + err = -ENOMEM ; + goto fail; + } err = XENOMAI_SKINCALL2(__native_muxid, __native_task_create, &bulk,
@@ -205,6 +211,10 @@ int rt_task_shadow(RT_TASK *task, const 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) +return -ENOMEM ; err =XENOMAI_SKINCALL2 (__native_muxid, __native_task_create, &bulk,NULL );
src/skins/posix/thread.c +31 -2
@@ -47,11 +47,23 @@ int __wrap_pthread_setschedparam(pthread int policy, const struct sched_param *param) { pthread_t myself = pthread_self(); +unsigned long *mode_buf =NULL ;int err, promoted; +if (thread == myself) { +#ifdef HAVE___THREAD + mode_buf =xeno_init_current_mode (); +#else /* !HAVE___THREAD */ + mode_buf =malloc (sizeof (*mode_buf)); + +if (!mode_buf) +return ENOMEM ; +#endif /* !HAVE___THREAD */ + } + err = -XENOMAI_SKINCALL5 (__pse51_muxid, __pse51_thread_setschedparam, - thread, policy, param, myself, &promoted); + thread, policy, param, mode_buf, &promoted);if (err ==EPERM )return __real_pthread_setschedparam (thread, policy, param);
@@ -60,10 +72,17 @@ int __wrap_pthread_setschedparam(pthreadif (!err && promoted) { old_sigharden_handler =signal (SIGHARDEN , &__pthread_sigharden_handler); +#ifndef HAVE___THREAD +pthread_setspecific (xeno_current_mode_key, mode_buf); +#endif /* !HAVE___THREAD */ xeno_set_current ();if (policy !=SCHED_OTHER )XENOMAI_SYSCALL1 (__xn_sys_migrate,XENOMAI_XENO_DOMAIN ); } +#ifndef HAVE___THREAD + else +free (mode_buf ); +#endif /* !HAVE___THREAD */ return err; }
@@ -116,6 +135,7 @@ static void *__pthread_trampoline(void *struct sched_param param;void *status =NULL ;int parent_prio, policy; +unsigned long *mode_buf;long err; old_sigharden_handler =signal (SIGHARDEN , &__pthread_sigharden_handler);
@@ -123,10 +143,18 @@ static void *__pthread_trampoline(void * 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_SKINCALL1 (__pse51_muxid, __pse51_thread_create, tid); + err =XENOMAI_SKINCALL2 (__pse51_muxid, __pse51_thread_create, tid, + mode_buf); iargs->ret = -err;/* We must save anything we'll need to use from *iargs on our own
@@ -159,6 +187,7 @@ static void *__pthread_trampoline(void * }else status = (void *)-err; +out:pthread_exit (status); }
include/vrtx/syscall.h +1 -0
@@ -85,6 +85,7 @@ struct vrtx_arg_bulk {u_long a1;u_long a2;u_long a3; +u_long a4; };#ifdef __KERNEL__
include/vxworks/syscall.h +1 -0
@@ -77,6 +77,7 @@ struct wind_arg_bulk {u_long a2;u_long a3;u_long a4; +u_long a5; };#ifdef __KERNEL__
src/skins/vrtx/task.c +6 -0
@@ -118,6 +118,12 @@ static void *vrtx_task_trampoline(void * 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 (); + +if (!bulk.a4) { + err = -ENOMEM ; + goto fail; + } err = XENOMAI_SKINCALL3(__vrtx_muxid, __vrtx_tecreate,
src/skins/vxworks/taskLib.c +6 -0
@@ -118,6 +118,12 @@ static void *wind_task_trampoline(void * 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 (); + +if (!bulk.a5) { + err = -ENOMEM ; + goto fail; + } err = XENOMAI_SKINCALL3(__vxworks_muxid, __vxworks_task_init,
include/psos+/syscall.h +8 -0
@@ -74,6 +74,14 @@/* Xenomai extension: get raw count of jiffies */ #define __psos_tm_getc 46 +struct psos_arg_bulk { + +u_long a1; +u_long a2; +u_long a3; +u_long a4; +}; +#ifdef __KERNEL__#ifdef __cplusplus
src/skins/psos+/task.c +13 -3
@@ -72,6 +72,7 @@ static void *psos_task_trampoline(void *struct psos_task_iargs *iargs = (struct psos_task_iargs *)cookie;void (*entry)(u_long ,u_long ,u_long ,u_long );u_long dummy_args[4 ] = {0 ,0 ,0 ,0 }, *targs; +struct psos_arg_bulk bulk;struct sched_param param;int policy;long err;
@@ -83,10 +84,19 @@ static void *psos_task_trampoline(void * old_sigharden_handler =signal (SIGHARDEN , &psos_task_sigharden); - err =XENOMAI_SKINCALL5 (__psos_muxid, + 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 (); + +if (!bulk.a4) { + err = -ENOMEM ; + goto fail; + } + + err =XENOMAI_SKINCALL3 (__psos_muxid, __psos_t_create, - iargs->name, iargs->prio, iargs->flags, - iargs->tid_r, iargs->completionp); + &bulk, iargs->tid_r, iargs->completionp);if (err) goto fail;
src/skins/uitron/task.c +9 -2
@@ -68,6 +68,7 @@ static void *uitron_task_trampoline(void {struct uitron_task_iargs *iargs = (struct uitron_task_iargs *)cookie;struct sched_param param; +unsigned long *mode;void (*entry)(INT );int policy;long err;
@@ -83,10 +84,16 @@ static void *uitron_task_trampoline(voidpthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS ,NULL ); old_sigharden_handler =signal (SIGHARDEN , &uitron_task_sigharden); - err =XENOMAI_SKINCALL3 (__uitron_muxid, + 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); + iargs->completionp, mode);if (err) goto fail;
Re: [Xenomai-core] [PATCH 10/12] Report current shadow thread mode to user space
Jan Kiszka wrote:
Ok. I still liked the solution of using a piece of shared heap. This was more general and would have allowed us to use this piece of shared heap for future purposes.
Signature · 1 line
Gilles.
Re: [Xenomai-core] [PATCH 10/12] Report current shadow thread mode to user space
Quoted 5 lines · Gilles Chanteperdrix
Jan Kiszka wrote:
Ok. I still liked the solution of using a piece of shared heap. This was more general and would have allowed us to use this piece of shared heap for future purposes.
Shared heaps do not allow for the __thread optimization.
Jan
Re: [Xenomai-core] [PATCH 10/12] Report current shadow thread mode to user space
Quoted 8 lines · Jan Kiszka
Quoted 5 lines · Gilles Chanteperdrix
Jan Kiszka wrote:
Ok. I still liked the solution of using a piece of shared heap. This was more general and would have allowed us to use this piece of shared heap for future purposes.
Shared heaps do not allow for the
__threadoptimization.
Actually, not true. But it would add a level of indirection to this path.
So, before adding support for something that /may/ be of interest in future (and that still could be added at that time): What further use cases for _per-thread_ data that is shared between user space and kernel do you see? I do have the syscall-less real-time clock in mind, but that will be globally shared data.
Jan
PATCH 11/12 Ensure mode switch in mutex fast paths
In reply to Jan KiszkaWith the help of xeno_get_current_mode(), this patch ensures that shadow threads in secondary mode will be switched to primary again in case they acquire an uncontended native or POSIX mutex, thus would otherwise only pick the user space fast path. This prevents potential priority inversions that the fast mutex optimizations introduced.
--- src/skins/native/mutex.c | 31 ++++++++------- src/skins/posix/mutex.c | 94 +++++++++++++++++++++++++++-------------------- 2 files changed, 71 insertions(+), 54 deletions(-)
src/skins/native/mutex.c +17 -14
@@ -18,6 +18,7 @@#include <limits.h> #include <nucleus/synch.h> +#include <nucleus/thread.h> #include <native/syscall.h> #include <native/mutex.h> #include <asm-generic/bits/current.h>
@@ -78,22 +79,24 @@ static int rt_mutex_acquire_inner(RT_MUTif (!cur)return -EPERM ; - err =xnsynch_fast_acquire (mutex->fastlock, cur); -if (likely (!err)) { - mutex->lockcnt =1 ; -return 0 ; - } - -if (err == -EBUSY ) { -if (mutex->lockcnt ==UINT_MAX ) -return -EAGAIN ; +if (likely (!(xeno_get_current_mode () &XNRELAX ))) { + err =xnsynch_fast_acquire (mutex->fastlock, cur); +if (likely (!err)) { + mutex->lockcnt =1 ; +return 0 ; + } + +if (err == -EBUSY ) { +if (mutex->lockcnt ==UINT_MAX ) +return -EAGAIN ; + + mutex->lockcnt++; +return 0 ; + } - mutex->lockcnt++; -return 0 ; +if (timeout ==TM_NONBLOCK && mode ==XN_RELATIVE ) +return -EWOULDBLOCK ; } - -if (timeout ==TM_NONBLOCK && mode ==XN_RELATIVE ) -return -EWOULDBLOCK ;#endif /* CONFIG_XENO_FASTSYNCH */ err = XENOMAI_SKINCALL3(__native_muxid,
src/skins/posix/mutex.c +54 -40
124 lines not on this page · raw message
Re: [Xenomai-core] [PATCH 11/12] Ensure mode switch in mutex fast paths
Jan Kiszka wrote:
Ok.
Signature · 1 line
Gilles.
PATCH 12/12 Enable SMP support for user libs by default
In reply to Jan KiszkaWith fast xnsynch/mutex support in place, the importance of getting the user space library configuration right increases significantly. If the user fails to provide --enable-smp, (s)he risks to break the mutex fast path in a very subtle way. Thus, it is better to assume SMP by default (as far as the arch bothers at all) and let the user switch it off for intentional optimization for UP-only targets.
--- README.INSTALL | 2 +- configure.in | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
configure.in +3 -3
@@ -132,12 +132,12 @@ AC_ARG_ENABLE(debug, esac]) AC_MSG_RESULT(${debug_symbols:-no}) -dnl SMP support (default: off) +dnl SMP support (default: on) -CONFIG_SMP= +CONFIG_SMP=y AC_MSG_CHECKING(for SMP support) AC_ARG_ENABLE(smp, - AS_HELP_STRING([--enable-smp], [Enable SMP support]), + AS_HELP_STRING([--disable-smp], [Disable SMP support (if the target supports it at all)]), [case "$enableval" in y | yes) CONFIG_SMP=y ;; *) unset CONFIG_SMP ;;
README.INSTALL +1 -1
@@ -143,7 +143,7 @@ NAME DESCRIPTION --prefix Installation directory /usr/xenomai --enable-debug Enable debug symbols (-g) disabled ---enable-smp Enable SMP support weak,disabled +--disable-smp Disable SMP support weak,enabled 1.3.3 Arch-specific configure options -------------------------------------
Re: [Xenomai-core] [PATCH 12/12] Enable SMP support for user libs by default
Jan Kiszka wrote:
I do not like this patch. This sould be solved using the existing features system. I do not want SMP to be enabled by default.
Signature · 1 line
Gilles.
Re: [Xenomai-core] [PATCH 12/12] Enable SMP support for user libs by default
Quoted 4 lines · Gilles Chanteperdrix
Jan Kiszka wrote:
I do not like this patch. This sould be solved using the existing features system. I do not want SMP to be enabled by default.
On x86, SMP is already the default case, other archs will follow soon. I'm also fine with keeping those arch at default off which support SMP, but use it only rarely in practice yet. But at least for x86, staying with UP as default will quickly become annoying.
That said, I have no problem with additionally enforcing the right configuration via the feature system. Will add that.
Jan
Quoted 9 lines · Jan Kiszka
Here comes a significantly reworked patch series to improve fast mutex support of Xenomai.
This approach now introduces a generic fast xnsynch core and converts the existing POSIX implementation over. It also comes with a second user, the Native skin. Additionally, it improves
xeno_get_currentvia a TLS variable and addresses the issue that threads in secondary mode acquiring an uncontended mutex need to be migrated first.
Quoted 4 lines
At this chance, the TLS optimization is also applied on self-lookups of task handles (Native, VRTX and VxWorks). And I included my SMP-by-default patch for user libs which is highly recommended to reduce the risk of accidental code breakage on SMP with the new mutex code.
Looks like patches 11 and 12 are missing here.
Signature · 1 line
Gilles.
Quoted 9 lines · Jan Kiszka
Here comes a significantly reworked patch series to improve fast mutex support of Xenomai.
This approach now introduces a generic fast xnsynch core and converts the existing POSIX implementation over. It also comes with a second user, the Native skin. Additionally, it improves
xeno_get_currentvia a TLS variable and addresses the issue that threads in secondary mode acquiring an uncontended mutex need to be migrated first.
Quoted 4 lines
At this chance, the TLS optimization is also applied on self-lookups of task handles (Native, VRTX and VxWorks). And I included my SMP-by-default patch for user libs which is highly recommended to reduce the risk of accidental code breakage on SMP with the new mutex code.
A minor remark. This is the third round of patches for fast mutexes, and
each round, you submit even more changes to review than the previous
round. If I doubted of your honesty, I could think that you are trying to dilute some questionable changes into more changes so that they get unnoticed.
Could we focus on a small set of changes, reach consensus, merge them, and then move to the next set of changes?
Signature · 1 line
Gilles.
Quoted 15 lines · Gilles Chanteperdrix
Quoted 9 lines · Jan Kiszka
Here comes a significantly reworked patch series to improve fast mutex support of Xenomai.
This approach now introduces a generic fast xnsynch core and converts the existing POSIX implementation over. It also comes with a second user, the Native skin. Additionally, it improves
xeno_get_currentvia a TLS variable and addresses the issue that threads in secondary mode acquiring an uncontended mutex need to be migrated first.Quoted 4 lines
At this chance, the TLS optimization is also applied on self-lookups of task handles (Native, VRTX and VxWorks). And I included my SMP-by-default patch for user libs which is highly recommended to reduce the risk of accidental code breakage on SMP with the new mutex code.
Quoted 5 lines
A minor remark. This is the third round of patches for fast mutexes, and
each round, you submit even more changes to review than the previous
round. If I doubted of your honesty, I could think that you are trying to dilute some questionable changes into more changes so that they get unnoticed.
May I recall the changelog of this round? In short:
- generic xnsynch
- fixed prio-inversion when coming from secondary mode
These are major changes, addressing specifically the NACKs of the previous rounds.
If you find "questionable changes", please point them out. So far I only recall the discussion about lockcnt maintenance policy, and I will try to sort that one out.
Quoted 2 lines
Could we focus on a small set of changes, reach consensus, merge them, and then move to the next set of changes?
No problem. Maybe I missed or forgot the clear OK for patches 1..4 to commit them, but I will now soon. Moreover, I just felt uncomfortable with merging patch 5 without having written to following ones.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT SE 2 Corporate Competence Center Embedded Linux
Quoted 26 lines · Jan Kiszka
Quoted 14 lines · Gilles Chanteperdrix
Quoted 9 lines · Jan Kiszka
Here comes a significantly reworked patch series to improve fast mutex support of Xenomai.
This approach now introduces a generic fast xnsynch core and converts the existing POSIX implementation over. It also comes with a second user, the Native skin. Additionally, it improves
xeno_get_currentvia a TLS variable and addresses the issue that threads in secondary mode acquiring an uncontended mutex need to be migrated first.Quoted 4 lines
At this chance, the TLS optimization is also applied on self-lookups of task handles (Native, VRTX and VxWorks). And I included my SMP-by-default patch for user libs which is highly recommended to reduce the risk of accidental code breakage on SMP with the new mutex code.
Quoted 5 lines
A minor remark. This is the third round of patches for fast mutexes, and
each round, you submit even more changes to review than the previous
round. If I doubted of your honesty, I could think that you are trying to dilute some questionable changes into more changes so that they get unnoticed.May I recall the changelog of this round? In short:
- generic xnsynch
- fixed prio-inversion when coming from secondary mode
Quoted 6 lines
These are major changes, addressing specifically the NACKs of the previous rounds.
If you find "questionable changes", please point them out. So far I only recall the discussion about lockcnt maintenance policy, and I will try to sort that one out.
The problem is that it took me about one hour reviewing your 12 patches (I know, I am a slow guy), and that I am not even sure that I saw all the changes.
The lockcnt change in patch 8 for instance is not even mentioned in the patch comments, and it is only because I originally did not understand the change in rt_cond_wait_inner that I now know about this change.
Quoted 7 lines
Quoted 3 lines
Could we focus on a small set of changes, reach consensus, merge them, and then move to the next set of changes?
No problem. Maybe I missed or forgot the clear OK for patches 1..4 to commit them, but I will now soon. Moreover, I just felt uncomfortable with merging patch 5 without having written to following ones.
I think Philippe should merge the patches.
Signature · 1 line
Gilles.
Quoted 29 lines · Gilles Chanteperdrix
Quoted 28 lines · Jan Kiszka
Quoted 14 lines · Gilles Chanteperdrix
Quoted 9 lines · Jan Kiszka
Here comes a significantly reworked patch series to improve fast mutex support of Xenomai.
This approach now introduces a generic fast xnsynch core and converts the existing POSIX implementation over. It also comes with a second user, the Native skin. Additionally, it improves
xeno_get_currentvia a TLS variable and addresses the issue that threads in secondary mode acquiring an uncontended mutex need to be migrated first.Quoted 4 lines
At this chance, the TLS optimization is also applied on self-lookups of task handles (Native, VRTX and VxWorks). And I included my SMP-by-default patch for user libs which is highly recommended to reduce the risk of accidental code breakage on SMP with the new mutex code.
Quoted 5 lines
A minor remark. This is the third round of patches for fast mutexes, and
each round, you submit even more changes to review than the previous
round. If I doubted of your honesty, I could think that you are trying to dilute some questionable changes into more changes so that they get unnoticed.May I recall the changelog of this round? In short:
- generic xnsynch
- fixed prio-inversion when coming from secondary modeThese are major changes, addressing specifically the NACKs of the previous rounds.
Quoted 7 lines
Quoted 3 lines
If you find "questionable changes", please point them out. So far I only recall the discussion about lockcnt maintenance policy, and I will try to sort that one out.
The problem is that it took me about one hour reviewing your 12 patches (I know, I am a slow guy), and that I am not even sure that I saw all the changes.
I appreciate your effort very much, and you already provided valuable input. But I feel it is much better to have the full picture instead of scattered bits. And this 12 patches belong together until none of their features are merged.
Quoted 4 lines
The lockcnt change in patch 8 for instance is not even mentioned in the patch comments, and it is only because I originally did not understand the change in
rt_cond_wait_innerthat I now know about this change.
Sorry for that, but it fell under the table on which all the other significant changes were already lying. Moreover, I originally felt it was only a minor cleanup as I simply aligned the code to the POSIX implementation in this regard. Nevertheless, the next posting will contain a separate patch for this.
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
Could we focus on a small set of changes, reach consensus, merge them, and then move to the next set of changes?
No problem. Maybe I missed or forgot the clear OK for patches 1..4 to commit them, but I will now soon. Moreover, I just felt uncomfortable with merging patch 5 without having written to following ones.
I think Philippe should merge the patches.
Also fine.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT SE 2 Corporate Competence Center Embedded Linux
Quoted 41 lines · Gilles Chanteperdrix
Quoted 25 lines · Jan Kiszka
Quoted 14 lines · Gilles Chanteperdrix
Quoted 9 lines · Jan Kiszka
Here comes a significantly reworked patch series to improve fast mutex support of Xenomai.
This approach now introduces a generic fast xnsynch core and converts the existing POSIX implementation over. It also comes with a second user, the Native skin. Additionally, it improves
xeno_get_currentvia a TLS variable and addresses the issue that threads in secondary mode acquiring an uncontended mutex need to be migrated first.Quoted 4 lines
At this chance, the TLS optimization is also applied on self-lookups of task handles (Native, VRTX and VxWorks). And I included my SMP-by-default patch for user libs which is highly recommended to reduce the risk of accidental code breakage on SMP with the new mutex code.
Quoted 5 lines
A minor remark. This is the third round of patches for fast mutexes, and
each round, you submit even more changes to review than the previous
round. If I doubted of your honesty, I could think that you are trying to dilute some questionable changes into more changes so that they get unnoticed.May I recall the changelog of this round? In short:
- generic xnsynch
- fixed prio-inversion when coming from secondary modeQuoted 6 lines
These are major changes, addressing specifically the NACKs of the previous rounds.
If you find "questionable changes", please point them out. So far I only recall the discussion about lockcnt maintenance policy, and I will try to sort that one out.
The problem is that it took me about one hour reviewing your 12 patches (I know, I am a slow guy), and that I am not even sure that I saw all the changes.
The lockcnt change in patch 8 for instance is not even mentioned in the patch comments, and it is only because I originally did not understand the change in
rt_cond_wait_innerthat I now know about this change.
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
Could we focus on a small set of changes, reach consensus, merge them, and then move to the next set of changes?
No problem. Maybe I missed or forgot the clear OK for patches 1..4 to commit them, but I will now soon. Moreover, I just felt uncomfortable with merging patch 5 without having written to following ones.
I think Philippe should merge the patches.
Ack.
Signature · 1 line
Philippe.