All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Kiszka <jan.kiszka@domain.hid>
To: Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
Cc: xenomai-core <xenomai@xenomai.org>
Subject: Re: [Xenomai-core] [RFC][PATCH] Factor out xnsynch_acquire/release
Date: Sun, 21 Sep 2008 20:07:41 +0200	[thread overview]
Message-ID: <48D68D6D.9070909@domain.hid> (raw)
In-Reply-To: <48D688EE.7010404@domain.hid>


[-- Attachment #1.1: Type: text/plain, Size: 2017 bytes --]

Gilles Chanteperdrix wrote:
> Jan Kiszka wrote:
>> Jan Kiszka wrote:
>>> Slowly moving on toward generic fast mutex support for Xenomai, this
>>> patch is a proposal to address the increasing divergence of
>>> owner-tracking vs. owner-less xnsynch objects.
>>>
>>> The services dealing with the former will likely include a new, lockless
>>> prologues for the mutex 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.
>> Any comments on this? I plan to resume the work on fast xnsynch once
>> this building block is clarified (or replaced by an alternative).
> 
> I have to admit that I have to dig into my e-mails to find back all the
> patches to which I have not answered, and this is hard. Is it easy for
> you to repost all of them in a unique thread ?

Find them here [1]. The second one is rebased in by local tree, likely
only a trivial refresh. However, I attached the base (1..4) for reference.

That said, the concrete implementation itself is not that important for
me now. More interesting are comments on the general direction.

Jan

[1]http://thread.gmane.org/gmane.linux.real-time.xenomai.devel/5412/focus=5405

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: always-put-xnthread-base-into-registry.patch --]
[-- Type: text/x-patch; name="always-put-xnthread-base-into-registry.patch", Size: 14541 bytes --]

---
 ksrc/skins/native/syscall.c  |   56 +++++++++++++++++++++++++------------------
 ksrc/skins/native/task.c     |    2 -
 ksrc/skins/psos+/syscall.c   |   14 +++++-----
 ksrc/skins/psos+/task.c      |    7 +++--
 ksrc/skins/vxworks/syscall.c |   28 +++++++++++----------
 ksrc/skins/vxworks/taskLib.c |    4 +--
 6 files changed, 63 insertions(+), 48 deletions(-)

Index: b/ksrc/skins/native/syscall.c
===================================================================
--- a/ksrc/skins/native/syscall.c
+++ b/ksrc/skins/native/syscall.c
@@ -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
@@ -223,7 +224,9 @@ static int __rt_task_bind(struct pt_regs
 	RT_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 +256,7 @@ static int __rt_task_start(struct pt_reg
 				     sizeof(ph)))
 		return -EFAULT;
 
-	task = (RT_TASK *)xnregistry_fetch(ph.opaque);
+	task = thread2rtask((xnthread_t *)xnregistry_fetch(ph.opaque));
 
 	if (!task)
 		return -ESRCH;
@@ -279,7 +282,7 @@ static int __rt_task_suspend(struct pt_r
 					     sizeof(ph)))
 			return -EFAULT;
 
-		task = (RT_TASK *)xnregistry_fetch(ph.opaque);
+		task = thread2rtask((xnthread_t *)xnregistry_fetch(ph.opaque));
 	} else
 		task = __rt_task_current(p);
 
@@ -302,7 +305,7 @@ static int __rt_task_resume(struct pt_re
 				     sizeof(ph)))
 		return -EFAULT;
 
-	task = (RT_TASK *)xnregistry_fetch(ph.opaque);
+	task = thread2rtask((xnthread_t *)xnregistry_fetch(ph.opaque));
 
 	if (!task)
 		return -ESRCH;
@@ -326,7 +329,7 @@ static int __rt_task_delete(struct pt_re
 					     sizeof(ph)))
 			return -EFAULT;
 
-		task = (RT_TASK *)xnregistry_fetch(ph.opaque);
+		task = thread2rtask((xnthread_t *)xnregistry_fetch(ph.opaque));
 	} else
 		task = __rt_task_current(p);
 
@@ -364,7 +367,7 @@ static int __rt_task_set_periodic(struct
 					     sizeof(ph)))
 			return -EFAULT;
 
-		task = (RT_TASK *)xnregistry_fetch(ph.opaque);
+		task = thread2rtask((xnthread_t *)xnregistry_fetch(ph.opaque));
 	} else
 		task = __rt_task_current(p);
 
@@ -418,7 +421,7 @@ static int __rt_task_set_priority(struct
 					     sizeof(ph)))
 			return -EFAULT;
 
-		task = (RT_TASK *)xnregistry_fetch(ph.opaque);
+		task = thread2rtask((xnthread_t *)xnregistry_fetch(ph.opaque));
 	} else
 		task = __rt_task_current(p);
 
@@ -473,7 +476,7 @@ static int __rt_task_unblock(struct pt_r
 				     sizeof(ph)))
 		return -EFAULT;
 
-	task = (RT_TASK *)xnregistry_fetch(ph.opaque);
+	task = thread2rtask((xnthread_t *)xnregistry_fetch(ph.opaque));
 
 	if (!task)
 		return -ESRCH;
@@ -500,7 +503,7 @@ static int __rt_task_inquire(struct pt_r
 					     sizeof(ph)))
 			return -EFAULT;
 
-		task = (RT_TASK *)xnregistry_fetch(ph.opaque);
+		task = thread2rtask((xnthread_t *)xnregistry_fetch(ph.opaque));
 	} else
 		task = __rt_task_current(p);
 
@@ -541,7 +544,7 @@ static int __rt_task_notify(struct pt_re
 					     sizeof(ph)))
 			return -EFAULT;
 
-		task = (RT_TASK *)xnregistry_fetch(ph.opaque);
+		task = thread2rtask((xnthread_t *)xnregistry_fetch(ph.opaque));
 	} else
 		task = __rt_task_current(p);
 
@@ -627,7 +630,7 @@ static int __rt_task_slice(struct pt_reg
 					     sizeof(ph)))
 			return -EFAULT;
 
-		task = (RT_TASK *)xnregistry_fetch(ph.opaque);
+		task = thread2rtask((xnthread_t *)xnregistry_fetch(ph.opaque));
 	} else
 		task = __rt_task_current(current);
 
@@ -667,7 +670,7 @@ static int __rt_task_send(struct pt_regs
 					     sizeof(ph)))
 			return -EFAULT;
 
-		task = (RT_TASK *)xnregistry_fetch(ph.opaque);
+		task = thread2rtask((xnthread_t *)xnregistry_fetch(ph.opaque));
 	} else
 		task = __rt_task_current(current);
 
@@ -1104,7 +1107,9 @@ static int __rt_sem_bind(struct pt_regs
 	RT_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 +1329,8 @@ static int __rt_event_bind(struct pt_reg
 	int 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 +1573,8 @@ static int __rt_mutex_bind(struct pt_reg
 	int 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 +1765,8 @@ static int __rt_cond_bind(struct pt_regs
 	int 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 +2016,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 +2515,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 +3026,7 @@ static int __rt_intr_bind(struct pt_regs
 	RT_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 +3283,7 @@ static int __rt_pipe_bind(struct pt_regs
 	RT_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 +3559,9 @@ static int __rt_buffer_bind(struct pt_re
 	RT_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;
 
Index: b/ksrc/skins/native/task.c
===================================================================
--- a/ksrc/skins/native/task.c
+++ b/ksrc/skins/native/task.c
@@ -292,7 +292,7 @@ int rt_task_create(RT_TASK *task,
 
 	if (name) {
 		err = xnregistry_enter(task->rname,
-				       task,
+				       &task->thread_base,
 				       &xnthread_handle(&task->thread_base),
 				       NULL);
 		if (err)
Index: b/ksrc/skins/psos+/syscall.c
===================================================================
--- a/ksrc/skins/psos+/syscall.c
+++ b/ksrc/skins/psos+/syscall.c
@@ -131,7 +131,7 @@ static int __t_start(struct pt_regs *reg
 	psostask_t *task;
 
 	handle = __xn_reg_arg1(regs);
-	task = (psostask_t *)xnregistry_fetch(handle);
+	task = thread2psostask((xnthread_t *)xnregistry_fetch(handle));
 
 	if (!task)
 		return ERR_OBJID;
@@ -162,7 +162,7 @@ static int __t_delete(struct pt_regs *re
 	handle = __xn_reg_arg1(regs);
 
 	if (handle)
-		task = (psostask_t *)xnregistry_fetch(handle);
+		task = thread2psostask((xnthread_t *)xnregistry_fetch(handle));
 	else
 		task = __psos_task_current(current);
 
@@ -182,7 +182,7 @@ static int __t_suspend(struct pt_regs *r
 	psostask_t *task;
 
 	if (handle)
-		task = (psostask_t *)xnregistry_fetch(handle);
+		task = thread2psostask((xnthread_t *)xnregistry_fetch(handle));
 	else
 		task = __psos_task_current(current);
 
@@ -202,7 +202,7 @@ static int __t_resume(struct pt_regs *re
 	psostask_t *task;
 
 	if (handle)
-		task = (psostask_t *)xnregistry_fetch(handle);
+		task = thread2psostask((xnthread_t *)xnregistry_fetch(handle));
 	else
 		task = __psos_task_current(current);
 
@@ -284,7 +284,7 @@ static int __t_setpri(struct pt_regs *re
 	psostask_t *task;
 
 	if (handle)
-		task = (psostask_t *)xnregistry_fetch(handle);
+		task = thread2psostask((xnthread_t *)xnregistry_fetch(handle));
 	else
 		task = __psos_task_current(current);
 
@@ -314,7 +314,7 @@ static int __ev_send(struct pt_regs *reg
 	u_long events;
 
 	if (handle)
-		task = (psostask_t *)xnregistry_fetch(handle);
+		task = thread2psostask((xnthread_t *)xnregistry_fetch(handle));
 	else
 		task = __psos_task_current(current);
 
@@ -1317,7 +1317,7 @@ static int __as_send(struct pt_regs *reg
 	psostask_t *task;
 
 	if (handle)
-		task = (psostask_t *)xnregistry_fetch(handle);
+		task = thread2psostask((xnthread_t *)xnregistry_fetch(handle));
 	else
 		task = __psos_task_current(current);
 
Index: b/ksrc/skins/psos+/task.c
===================================================================
--- a/ksrc/skins/psos+/task.c
+++ b/ksrc/skins/psos+/task.c
@@ -161,8 +161,11 @@ u_long t_create(const char *name,
 
 #ifdef CONFIG_XENO_OPT_REGISTRY
 	{
-		u_long err = xnregistry_enter(task->name,
-					      task, &xnthread_handle(&task->threadbase), NULL);
+		u_long err =
+			xnregistry_enter(task->name,
+					 &task->threadbase,
+					 &xnthread_handle(&task->threadbase),
+					 NULL);
 		if (err) {
 			t_delete((u_long)task);
 			return err;
Index: b/ksrc/skins/vxworks/syscall.c
===================================================================
--- a/ksrc/skins/vxworks/syscall.c
+++ b/ksrc/skins/vxworks/syscall.c
@@ -146,7 +146,8 @@ out:
 
 static int __wind_task_activate(struct pt_regs *regs)
 {
-	WIND_TCB *pTcb = (WIND_TCB *)xnregistry_fetch(__xn_reg_arg1(regs));
+	WIND_TCB *pTcb = thread2wind_task(
+		(xnthread_t *)xnregistry_fetch(__xn_reg_arg1(regs)));
 
 	if (!pTcb)
 		return S_objLib_OBJ_ID_ERROR;
@@ -167,7 +168,7 @@ static int __wind_task_deleteforce(struc
 	WIND_TCB *pTcb;
 
 	if (handle)
-		pTcb = (WIND_TCB *)xnregistry_fetch(handle);
+		pTcb = thread2wind_task((xnthread_t *)xnregistry_fetch(handle));
 	else
 		pTcb = __wind_task_current(current);
 
@@ -190,7 +191,7 @@ static int __wind_task_delete(struct pt_
 	WIND_TCB *pTcb;
 
 	if (handle)
-		pTcb = (WIND_TCB *)xnregistry_fetch(handle);
+		pTcb = thread2wind_task((xnthread_t *)xnregistry_fetch(handle));
 	else
 		pTcb = __wind_task_current(current);
 
@@ -213,7 +214,7 @@ static int __wind_task_suspend(struct pt
 	WIND_TCB *pTcb;
 
 	if (handle)
-		pTcb = (WIND_TCB *)xnregistry_fetch(handle);
+		pTcb = thread2wind_task((xnthread_t *)xnregistry_fetch(handle));
 	else
 		pTcb = __wind_task_current(current);
 
@@ -232,7 +233,8 @@ static int __wind_task_suspend(struct pt
 
 static int __wind_task_resume(struct pt_regs *regs)
 {
-	WIND_TCB *pTcb = (WIND_TCB *)xnregistry_fetch(__xn_reg_arg1(regs));
+	WIND_TCB *pTcb = thread2wind_task(
+		(xnthread_t *)xnregistry_fetch(__xn_reg_arg1(regs)));
 
 	if (!pTcb)
 		return S_objLib_OBJ_ID_ERROR;
@@ -275,7 +277,7 @@ static int __wind_task_priorityset(struc
 	WIND_TCB *pTcb;
 
 	if (handle)
-		pTcb = (WIND_TCB *)xnregistry_fetch(handle);
+		pTcb = thread2wind_task((xnthread_t *)xnregistry_fetch(handle));
 	else
 		pTcb = __wind_task_current(current);
 
@@ -299,7 +301,7 @@ static int __wind_task_priorityget(struc
 	int prio;
 
 	if (handle)
-		pTcb = (WIND_TCB *)xnregistry_fetch(handle);
+		pTcb = thread2wind_task((xnthread_t *)xnregistry_fetch(handle));
 	else
 		pTcb = __wind_task_current(current);
 
@@ -374,7 +376,7 @@ static int __wind_task_verifyid(struct p
 	xnhandle_t handle = __xn_reg_arg1(regs);
 	WIND_TCB *pTcb;
 
-	pTcb = (WIND_TCB *)xnregistry_fetch(handle);
+	pTcb = (thread2wind_task((xnthread_t *)xnregistry_fetch(handle)));
 
 	if (!pTcb)
 		return S_objLib_OBJ_ID_ERROR;
@@ -574,7 +576,7 @@ static int __wind_taskinfo_name(struct p
 	const char *name;
 	WIND_TCB *pTcb;
 
-	pTcb = (WIND_TCB *)xnregistry_fetch(handle);
+	pTcb = thread2wind_task((xnthread_t *)xnregistry_fetch(handle));
 
 	if (!pTcb)
 		return S_objLib_OBJ_ID_ERROR;
@@ -618,7 +620,7 @@ static int __wind_taskinfo_status(struct
 
 	xnlock_get_irqsave(&nklock, s);
 
-	pTcb = (WIND_TCB *)xnregistry_fetch(handle);
+	pTcb = thread2wind_task((xnthread_t *)xnregistry_fetch(handle));
 
 	if (!pTcb || pTcb->magic != WIND_TASK_MAGIC) {
 		xnlock_put_irqrestore(&nklock, s);
@@ -643,7 +645,7 @@ static int __wind_taskinfo_get(struct pt
 	WIND_TCB *pTcb;
 	int err;
 
-	pTcb = (WIND_TCB *)xnregistry_fetch(handle);
+	pTcb = thread2wind_task((xnthread_t *)xnregistry_fetch(handle));
 	if (!pTcb)
 		return S_objLib_OBJ_ID_ERROR;
 
@@ -673,7 +675,7 @@ static int __wind_errno_taskset(struct p
  		return 0;
  	}
  
- 	pTcb = (WIND_TCB *)xnregistry_fetch(handle);
+ 	pTcb = thread2wind_task((xnthread_t *)xnregistry_fetch(handle));
 	if (!pTcb)
 		return S_objLib_OBJ_ID_ERROR;
 
@@ -696,7 +698,7 @@ static int __wind_errno_taskget(struct p
  	if (!handle)
  		errcode = wind_errnoget();
  	else {
- 		pTcb = (WIND_TCB *)xnregistry_fetch(handle);
+ 		pTcb = thread2wind_task((xnthread_t *)xnregistry_fetch(handle));
  		if (!pTcb)
  			return S_objLib_OBJ_ID_ERROR;
  
Index: b/ksrc/skins/vxworks/taskLib.c
===================================================================
--- a/ksrc/skins/vxworks/taskLib.c
+++ b/ksrc/skins/vxworks/taskLib.c
@@ -171,8 +171,8 @@ STATUS taskInit(WIND_TCB *pTcb,
 	xnlock_put_irqrestore(&nklock, s);
 
 #ifdef CONFIG_XENO_OPT_REGISTRY
-	if (xnregistry_enter(pTcb->name,
-			     pTcb, &xnthread_handle(&pTcb->threadbase), NULL)) {
+	if (xnregistry_enter(pTcb->name, &pTcb->threadbase,
+			     &xnthread_handle(&pTcb->threadbase), NULL)) {
 		wind_errnoset(S_objLib_OBJ_ID_ERROR);
 		taskDeleteForce((TASK_ID) pTcb);
 		return ERROR;

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.3: handle-based-xn_sys_current.patch --]
[-- Type: text/x-patch; name="handle-based-xn_sys_current.patch", Size: 27117 bytes --]

---
 include/asm-generic/bits/bind.h    |    9 ++++-
 include/asm-generic/bits/current.h |    5 +-
 include/nucleus/types.h            |   13 +++++++
 ksrc/nucleus/shadow.c              |   17 ++++++++-
 ksrc/skins/native/Kconfig          |    1 
 ksrc/skins/native/task.c           |   14 +++-----
 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           |   64 ++++++++++++++++++++++++-------------
 ksrc/skins/posix/syscall.c         |   11 +++---
 ksrc/skins/posix/thread.c          |   16 +++++++++
 ksrc/skins/psos+/Kconfig           |    2 -
 ksrc/skins/rtai/Kconfig            |    1 
 ksrc/skins/rtai/task.c             |   12 ++++++
 ksrc/skins/uitron/Kconfig          |    1 
 ksrc/skins/uitron/task.c           |   11 ++++++
 ksrc/skins/vrtx/Kconfig            |    2 -
 ksrc/skins/vrtx/task.c             |   20 ++++++++++-
 ksrc/skins/vxworks/Kconfig         |    2 -
 src/skins/posix/mutex.c            |   27 ++++++++-------
 22 files changed, 201 insertions(+), 76 deletions(-)

Index: b/include/asm-generic/bits/current.h
===================================================================
--- a/include/asm-generic/bits/current.h
+++ b/include/asm-generic/bits/current.h
@@ -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 */
Index: b/include/nucleus/types.h
===================================================================
--- a/include/nucleus/types.h
+++ b/include/nucleus/types.h
@@ -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);
Index: b/ksrc/nucleus/shadow.c
===================================================================
--- a/ksrc/nucleus/shadow.c
+++ b/ksrc/nucleus/shadow.c
@@ -52,6 +52,7 @@
 #include <nucleus/trace.h>
 #include <nucleus/stat.h>
 #include <nucleus/sys_ppd.h>
+#include <nucleus/registry.h>
 #include <asm/xenomai/features.h>
 #include <asm/xenomai/syscall.h>
 #include <asm/xenomai/bits/shadow.h>
@@ -1908,13 +1909,21 @@ static int xnshadow_sys_sem_heap(struct
 	return __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 +1934,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)
Index: b/ksrc/skins/posix/cb_lock.h
===================================================================
--- a/ksrc/skins/posix/cb_lock.h
+++ b/ksrc/skins/posix/cb_lock.h
@@ -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
 
Index: b/ksrc/skins/posix/cond.c
===================================================================
--- a/ksrc/skins/posix/cond.c
+++ b/ksrc/skins/posix/cond.c
@@ -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. */
Index: b/ksrc/skins/posix/mutex.c
===================================================================
--- a/ksrc/skins/posix/mutex.c
+++ b/ksrc/skins/posix/mutex.c
@@ -82,7 +82,7 @@ int pse51_mutex_check_init(struct __shad
 
 int 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)) {
 		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))
+		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;
 	}
Index: b/ksrc/skins/posix/mutex.h
===================================================================
--- a/ksrc/skins/posix/mutex.h
+++ b/ksrc/skins/posix/mutex.h
@@ -34,7 +34,7 @@ union __xeno_mutex {
 		xnarch_atomic_t lock;
 		union {
 			unsigned owner_offset;
-			xnarch_atomic_intptr_t *owner;
+			xnarch_atomic_t *owner;
 		};
 		struct pse51_mutexattr attr;
 #endif /* CONFIG_XENO_FASTSEM */
@@ -43,6 +43,7 @@ union __xeno_mutex {
 
 #ifdef __KERNEL__
 
+#include <nucleus/registry.h>
 #include <posix/internal.h>
 #include <posix/thread.h>
 #include <posix/cb_lock.h>
@@ -54,7 +55,7 @@ typedef struct pse51_mutex {
 #define link2mutex(laddr)                                               \
 	((pse51_mutex_t *)(((char *)laddr) - offsetof(pse51_mutex_t, link)))
 
-	xnarch_atomic_intptr_t *owner;
+	xnarch_atomic_t *owner;
 	pthread_mutexattr_t attr;
 	unsigned sleepers;
 	pse51_kqueues_t *owningq;
@@ -77,7 +78,7 @@ int pse51_mutex_check_init(struct __shad
 
 int 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);
 
 void pse51_mutex_destroy_internal(pse51_mutex_t *mutex,
@@ -88,6 +89,7 @@ pse51_mutex_trylock_internal(xnthread_t
 			     struct __shadow_mutex *shadow, unsigned count)
 {
 	pse51_mutex_t *mutex = shadow->mutex;
+	xnhandle_t ownerh;
 	xnthread_t *owner;
 
 	if (xnpod_unblockable_p())
@@ -101,9 +103,14 @@ pse51_mutex_trylock_internal(xnthread_t
 		return ERR_PTR(-EPERM);
 #endif /* XENO_DEBUG(POSIX) */
 
-	owner = xnarch_atomic_intptr_cmpxchg(mutex->owner, NULL, cur);
-	if (unlikely(owner != NULL))
+	ownerh = xnarch_atomic_cmpxchg(mutex->owner, XN_NO_HANDLE,
+				       xnthread_handle(cur));
+	if (unlikely(ownerh)) {
+		owner = xnregistry_fetch(clear_claimed(ownerh));
+		if (!owner)
+			return ERR_PTR(-EINVAL);
 		return owner;
+	}
 
 	shadow->lockcnt = count;
 	return NULL;
@@ -118,7 +125,8 @@ static inline int pse51_mutex_timedlock_
 
 {
 	pse51_mutex_t *mutex;
-	xnthread_t *owner, *old;
+	xnthread_t *owner;
+	xnhandle_t ownerh, old;
 	spl_t s;
 	int err;
 
@@ -128,32 +136,41 @@ static inline int pse51_mutex_timedlock_
 		return PTR_ERR(owner);
 
 	mutex = shadow->mutex;
-	if (clear_claimed(owner) == cur)
+	if (owner == cur)
 		return -EBUSY;
 
 	/* Set bit 0, so that mutex_unlock will know that the mutex is claimed.
 	   Hold the nklock, for mutual exclusion with slow mutex_unlock. */
 	xnlock_get_irqsave(&nklock, s);
-	if (test_claimed(owner)) {
-		old = xnarch_atomic_intptr_get(mutex->owner);
+	if (test_claimed(ownerh)) {
+		old = xnarch_atomic_get(mutex->owner);
 		goto test_no_owner;
 	}
 	do {
-		old = xnarch_atomic_intptr_cmpxchg(mutex->owner,
-						   owner, set_claimed(owner, 1));
-		if (likely(old == owner))
+		old = xnarch_atomic_cmpxchg(mutex->owner, ownerh,
+					    set_claimed(ownerh, 1));
+		if (likely(old == ownerh))
 			break;
 	  test_no_owner:
-		if (old == NULL) {
+		if (!old) {
 			/* Owner called fast mutex_unlock
 			   (on another cpu) */
 			xnlock_put_irqrestore(&nklock, s);
 			goto retry_lock;
 		}
-		owner = old;
-	} while (!test_claimed(owner));
+		ownerh = old;
+	} while (!test_claimed(ownerh));
+
+	owner = xnregistry_fetch(clear_claimed(ownerh));
+
+	/* Consistency check for owner handle - is the object a thread? */
+	if (unlikely(!owner ||
+		     xnthread_handle(owner) != clear_claimed(ownerh))) {
+		err = -EINVAL;
+		goto error;
+	}
 
-	xnsynch_set_owner(&mutex->synchbase, clear_claimed(owner));
+	xnsynch_set_owner(&mutex->synchbase, owner);
 	++mutex->sleepers;
 	if (timed)
 		xnsynch_sleep_on(&mutex->synchbase, abs_to, XN_REALTIME);
@@ -174,7 +191,8 @@ static inline int pse51_mutex_timedlock_
 		goto error;
 	}
 
-	xnarch_atomic_intptr_set(mutex->owner,set_claimed(cur, mutex->sleepers));
+	ownerh = set_claimed(xnthread_handle(cur), mutex->sleepers);
+	xnarch_atomic_set(mutex->owner, ownerh);
 	shadow->lockcnt = count;
 	xnlock_put_irqrestore(&nklock, s);
 
@@ -182,9 +200,9 @@ static inline int pse51_mutex_timedlock_
 
   error:
 	if (!mutex->sleepers)
-		xnarch_atomic_intptr_set
+		xnarch_atomic_set
 			(mutex->owner,
-			 clear_claimed(xnarch_atomic_intptr_get(mutex->owner)));
+			 clear_claimed(xnarch_atomic_get(mutex->owner)));
 	xnlock_put_irqrestore(&nklock, s);
 	return err;
 }
@@ -192,16 +210,18 @@ static inline int pse51_mutex_timedlock_
 static inline void pse51_mutex_unlock_internal(xnthread_t *cur,
 					       pse51_mutex_t *mutex)
 {
+	xnhandle_t ownerh;
 	xnthread_t *owner;
 	spl_t s;
 
-	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;
 
 	xnlock_get_irqsave(&nklock, s);
 	owner = xnsynch_wakeup_one_sleeper(&mutex->synchbase);
-	xnarch_atomic_intptr_set(mutex->owner,
-				 set_claimed(owner, mutex->sleepers));
+	ownerh = set_claimed(xnthread_handle(owner), mutex->sleepers);
+	xnarch_atomic_set(mutex->owner, ownerh);
 	if (owner)
 		xnpod_schedule();
 	xnlock_put_irqrestore(&nklock, s);
Index: b/ksrc/skins/posix/syscall.c
===================================================================
--- a/ksrc/skins/posix/syscall.c
+++ b/ksrc/skins/posix/syscall.c
@@ -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 p
 	pthread_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 p
 	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;
@@ -1185,7 +1186,7 @@ static int __pthread_mutex_destroy(struc
 	if (pse51_kqueues(mutex->attr.pshared) != mutex->owningq)
 		return -EPERM;
 
-	if (xnarch_atomic_intptr_get(mutex->owner))
+	if (xnarch_atomic_get(mutex->owner))
 		return -EBUSY;
 
 	pse51_mark_deleted(shadow);
Index: b/src/skins/posix/mutex.c
===================================================================
--- a/src/skins/posix/mutex.c
+++ b/src/skins/posix/mutex.c
@@ -31,12 +31,12 @@ extern int __pse51_muxid;
 
 extern unsigned long xeno_sem_heap[2];
 
-static xnarch_atomic_intptr_t *get_ownerp(struct __shadow_mutex *shadow)
+static xnarch_atomic_t *get_ownerp(struct __shadow_mutex *shadow)
 {
 	if (likely(!shadow->attr.pshared))
 		return shadow->owner;
 	
-	return (xnarch_atomic_intptr_t *) (xeno_sem_heap[1] + shadow->owner_offset);
+	return (xnarch_atomic_t *) (xeno_sem_heap[1] + shadow->owner_offset);
 }
 #endif /* CONFIG_XENO_FASTSEM */
 
@@ -117,7 +117,7 @@ int __wrap_pthread_mutex_init(pthread_mu
 
 #ifdef CONFIG_XENO_FASTSEM
 	if (!shadow->attr.pshared)
-		shadow->owner = (xnarch_atomic_intptr_t *)
+		shadow->owner = (xnarch_atomic_t *)
 			(xeno_sem_heap[0] + shadow->owner_offset);
 	
 	cb_write_unlock(&shadow->lock, s);
@@ -149,7 +149,7 @@ int __wrap_pthread_mutex_lock(pthread_mu
 	int err = 0;
 
 #ifdef CONFIG_XENO_FASTSEM
-	xnthread_t *cur, *owner;
+	xnhandle_t cur, owner;
 
 	cur = xeno_get_current();
 	if (!cur)
@@ -163,7 +163,7 @@ int __wrap_pthread_mutex_lock(pthread_mu
 		goto out;
 	}
 
-	owner = xnarch_atomic_intptr_cmpxchg(get_ownerp(shadow), NULL, cur);
+	owner = xnarch_atomic_cmpxchg(get_ownerp(shadow), XN_NO_HANDLE, cur);
 	if (likely(!owner)) {
 		shadow->lockcnt = 1;
 		cb_read_unlock(&shadow->lock, s);
@@ -210,7 +210,7 @@ int __wrap_pthread_mutex_timedlock(pthre
 	int err = 0;
 
 #ifdef CONFIG_XENO_FASTSEM
-	xnthread_t *cur, *owner;
+	xnhandle_t cur, owner;
 
 	cur = xeno_get_current();
 	if (!cur)
@@ -224,7 +224,7 @@ int __wrap_pthread_mutex_timedlock(pthre
 		goto out;
 	}	
 
-	owner = xnarch_atomic_intptr_cmpxchg(get_ownerp(shadow), NULL, cur);
+	owner = xnarch_atomic_cmpxchg(get_ownerp(shadow), XN_NO_HANDLE, cur);
 	if (likely(!owner)) {
 		shadow->lockcnt = 1;
 		cb_read_unlock(&shadow->lock, s);
@@ -271,7 +271,7 @@ int __wrap_pthread_mutex_trylock(pthread
 	int err = 0;
 
 #ifdef CONFIG_XENO_FASTSEM
-	xnthread_t *cur, *owner;
+	xnhandle_t cur, owner;
 
 	cur = xeno_get_current();
 	if (!cur)
@@ -285,7 +285,7 @@ int __wrap_pthread_mutex_trylock(pthread
 		goto out;
 	}	
 
-	owner = xnarch_atomic_intptr_cmpxchg(get_ownerp(shadow), NULL, cur);
+	owner = xnarch_atomic_cmpxchg(get_ownerp(shadow), XN_NO_HANDLE, cur);
 	if (likely(!owner)) {
 		shadow->lockcnt = 1;
 		cb_read_unlock(&shadow->lock, s);
@@ -325,8 +325,8 @@ int __wrap_pthread_mutex_unlock(pthread_
 	int err = 0;
 
 #ifdef CONFIG_XENO_FASTSEM
-	xnarch_atomic_intptr_t *ownerp;
-	xnthread_t *cur;
+	xnarch_atomic_t *ownerp;
+	xnhandle_t cur, owner;
 
 	cur = xeno_get_current();
 	if (!cur)
@@ -341,7 +341,8 @@ int __wrap_pthread_mutex_unlock(pthread_
 	}
 
 	ownerp = get_ownerp(shadow);
-	if (unlikely(clear_claimed(xnarch_atomic_intptr_get(ownerp)) != cur)) {
+	owner = clear_claimed(xnarch_atomic_get(ownerp));
+	if (unlikely(owner != cur)) {
 		err = -EPERM;
 		goto out_err;
 	}
@@ -352,7 +353,7 @@ int __wrap_pthread_mutex_unlock(pthread_
 		goto out;
 	}
 
-	if (likely(xnarch_atomic_intptr_cmpxchg(ownerp, cur, NULL) == cur)) {
+	if (likely(xnarch_atomic_cmpxchg(ownerp, cur, XN_NO_HANDLE) == cur)) {
 	  out:
 		cb_read_unlock(&shadow->lock, s);
 		return 0;
Index: b/ksrc/skins/posix/thread.c
===================================================================
--- a/ksrc/skins/posix/thread.c
+++ b/ksrc/skins/posix/thread.c
@@ -28,6 +28,7 @@
  * 
  *@{*/
 
+#include <nucleus/registry.h>
 #include <posix/thread.h>
 #include <posix/cancel.h>
 #include <posix/timer.h>
@@ -234,6 +235,21 @@ 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 =
+		    xnregistry_enter("", &thread->threadbase,
+				     &xnthread_handle(&thread->threadbase),
+						      NULL);
+		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). */
Index: b/ksrc/skins/posix/Kconfig
===================================================================
--- a/ksrc/skins/posix/Kconfig
+++ b/ksrc/skins/posix/Kconfig
@@ -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
Index: b/include/asm-generic/bits/bind.h
===================================================================
--- a/include/asm-generic/bits/bind.h
+++ b/include/asm-generic/bits/bind.h
@@ -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);
 }
 
Index: b/ksrc/skins/native/Kconfig
===================================================================
--- a/ksrc/skins/native/Kconfig
+++ b/ksrc/skins/native/Kconfig
@@ -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
Index: b/ksrc/skins/native/task.c
===================================================================
--- a/ksrc/skins/native/task.c
+++ b/ksrc/skins/native/task.c
@@ -290,14 +290,12 @@ int rt_task_create(RT_TASK *task,
 	   complete objects, so that the registry cannot return handles to
 	   half-baked objects... */
 
-	if (name) {
-		err = xnregistry_enter(task->rname,
-				       &task->thread_base,
-				       &xnthread_handle(&task->thread_base),
-				       NULL);
-		if (err)
-			xnpod_delete_thread(&task->thread_base);
-	}
+	err = xnregistry_enter(name ? task->rname : "",
+			       &task->thread_base,
+			       &xnthread_handle(&task->thread_base),
+			       NULL);
+	if (err)
+		xnpod_delete_thread(&task->thread_base);
 #endif /* CONFIG_XENO_OPT_REGISTRY */
 
 	return err;
Index: b/ksrc/skins/psos+/Kconfig
===================================================================
--- a/ksrc/skins/psos+/Kconfig
+++ b/ksrc/skins/psos+/Kconfig
@@ -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.
Index: b/ksrc/skins/uitron/Kconfig
===================================================================
--- a/ksrc/skins/uitron/Kconfig
+++ b/ksrc/skins/uitron/Kconfig
@@ -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
 
Index: b/ksrc/skins/uitron/task.c
===================================================================
--- a/ksrc/skins/uitron/task.c
+++ b/ksrc/skins/uitron/task.c
@@ -151,6 +151,17 @@ 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 (xnregistry_enter("", &task->threadbase,
+			     &xnthread_handle(&task->threadbase), NULL)) {
+		xnmap_remove(ui_task_idmap, tskid);
+		xnpod_abort_thread(&task->threadbase);
+		return E_NOMEM;
+	}
+#endif /* CONFIG_XENO_FASTSEM */
+
 	return E_OK;
 }
 
Index: b/ksrc/skins/rtai/Kconfig
===================================================================
--- a/ksrc/skins/rtai/Kconfig
+++ b/ksrc/skins/rtai/Kconfig
@@ -1,5 +1,6 @@
 menuconfig XENO_SKIN_RTAI
 	depends on XENO_OPT_NUCLEUS
+	select XENO_OPT_REGISTRY if XENO_FASTSEM
 	tristate "RTAI emulator"
 	help
 
Index: b/ksrc/skins/rtai/task.c
===================================================================
--- a/ksrc/skins/rtai/task.c
+++ b/ksrc/skins/rtai/task.c
@@ -20,6 +20,7 @@
 
 #include <nucleus/pod.h>
 #include <nucleus/heap.h>
+#include <nucleus/registry.h>
 #include <rtai/task.h>
 
 static DEFINE_XNQUEUE(__rtai_task_q);
@@ -152,6 +153,17 @@ 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 = xnregistry_enter("", &task->thread_base,
+			       &xnthread_handle(&task->thread_base), NULL);
+	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. */
 
Index: b/ksrc/skins/vrtx/Kconfig
===================================================================
--- a/ksrc/skins/vrtx/Kconfig
+++ b/ksrc/skins/vrtx/Kconfig
@@ -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
Index: b/ksrc/skins/vrtx/task.c
===================================================================
--- a/ksrc/skins/vrtx/task.c
+++ b/ksrc/skins/vrtx/task.c
@@ -188,12 +188,28 @@ 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 =
+		    xnregistry_enter("", &task->threadbase,
+				     &xnthread_handle(&task->threadbase),
+						      NULL);
+		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);
Index: b/ksrc/skins/vxworks/Kconfig
===================================================================
--- a/ksrc/skins/vxworks/Kconfig
+++ b/ksrc/skins/vxworks/Kconfig
@@ -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.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.4: remove-xnarch_atomic_intptr.patch --]
[-- Type: text/x-patch; name="remove-xnarch_atomic_intptr.patch", Size: 4315 bytes --]

---
 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(-)

Index: b/include/asm-arm/atomic.h
===================================================================
--- a/include/asm-arm/atomic.h
+++ b/include/asm-arm/atomic.h
@@ -412,9 +412,6 @@ static __inline__ void xnarch_atomic_cle
 
 typedef 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
Index: b/include/asm-blackfin/atomic.h
===================================================================
--- a/include/asm-blackfin/atomic.h
+++ b/include/asm-blackfin/atomic.h
@@ -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>
Index: b/include/asm-generic/Makefile.am
===================================================================
--- a/include/asm-generic/Makefile.am
+++ b/include/asm-generic/Makefile.am
@@ -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
Index: b/include/asm-generic/Makefile.in
===================================================================
--- a/include/asm-generic/Makefile.in
+++ b/include/asm-generic/Makefile.in
@@ -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
 
Index: b/include/asm-generic/atomic.h
===================================================================
--- a/include/asm-generic/atomic.h
+++ /dev/null
@@ -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 */
Index: b/include/asm-ia64/atomic.h
===================================================================
--- a/include/asm-ia64/atomic.h
+++ b/include/asm-ia64/atomic.h
@@ -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>
Index: b/include/asm-powerpc/atomic.h
===================================================================
--- a/include/asm-powerpc/atomic.h
+++ b/include/asm-powerpc/atomic.h
@@ -262,6 +262,4 @@ xnarch_atomic_cmpxchg(xnarch_atomic_t *p
 
 typedef unsigned long atomic_flags_t;
 
-#include <asm-generic/xenomai/atomic.h>
-
 #endif /* !_XENO_ASM_POWERPC_ATOMIC_H */
Index: b/include/asm-x86/atomic.h
===================================================================
--- a/include/asm-x86/atomic.h
+++ b/include/asm-x86/atomic.h
@@ -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 */

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.5: spread-xeno_set_current.patch --]
[-- Type: text/x-patch; name="spread-xeno_set_current.patch", Size: 5594 bytes --]

---
 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(-)

Index: b/src/skins/native/task.c
===================================================================
--- a/src/skins/native/task.c
+++ b/src/skins/native/task.c
@@ -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 *co
 	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. */
@@ -169,6 +172,7 @@ int rt_task_shadow(RT_TASK *task, const
 	struct 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)
Index: b/src/skins/psos+/task.c
===================================================================
--- a/src/skins/psos+/task.c
+++ b/src/skins/psos+/task.c
@@ -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, /* Xen
 		u_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,
Index: b/src/skins/uitron/task.c
===================================================================
--- a/src/skins/uitron/task.c
+++ b/src/skins/uitron/task.c
@@ -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(void
 	if (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, &param);
@@ -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)
Index: b/src/skins/vrtx/task.c
===================================================================
--- a/src/skins/vrtx/task.c
+++ b/src/skins/vrtx/task.c
@@ -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;
 
@@ -106,6 +107,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. */
Index: b/src/skins/vxworks/taskLib.c
===================================================================
--- a/src/skins/vxworks/taskLib.c
+++ b/src/skins/vxworks/taskLib.c
@@ -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. */

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 257 bytes --]

  reply	other threads:[~2008-09-21 18:07 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-15 15:14 [Xenomai-core] [RFC][PATCH] Factor out xnsynch_acquire/release Jan Kiszka
2008-09-15 17:10 ` Jan Kiszka
2008-09-16 17:15   ` Philippe Gerum
2008-09-21 10:24 ` Jan Kiszka
2008-09-21 17:48   ` Gilles Chanteperdrix
2008-09-21 18:07     ` Jan Kiszka [this message]
2008-09-21 19:03       ` Gilles Chanteperdrix
2008-09-22  8:09         ` Jan Kiszka
2008-09-22  8:18           ` Gilles Chanteperdrix
2008-09-22  8:57             ` Jan Kiszka
2008-09-22 18:41               ` Gilles Chanteperdrix
2008-09-23  8:44                 ` Jan Kiszka
2008-09-23  8:45                   ` Gilles Chanteperdrix
2008-09-23  9:01                     ` Jan Kiszka
2008-09-22  8:19         ` Philippe Gerum
2008-09-23 14:59           ` Jan Kiszka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=48D68D6D.9070909@domain.hid \
    --to=jan.kiszka@domain.hid \
    --cc=gilles.chanteperdrix@xenomai.org \
    --cc=xenomai@xenomai.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.