* [Xenomai-core] [RFC][PATCH] Factor out xnsynch_acquire/release
@ 2008-09-15 15:14 Jan Kiszka
2008-09-15 17:10 ` Jan Kiszka
2008-09-21 10:24 ` Jan Kiszka
0 siblings, 2 replies; 16+ messages in thread
From: Jan Kiszka @ 2008-09-15 15:14 UTC (permalink / raw)
To: xenomai-core
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.
Find a first draft of this approach attached (compile-tested). Before
going down this round, I would like to collect opinions and finally an
Ack on this (or and alternative approach). I also briefly thought about
branching two xnsynch sub-objects for owner/no-owner. But that would
likely make the changes far more complicated and invasive.
Jan
---
include/nucleus/synch.h | 16 +
include/rtdm/rtdm_driver.h | 2
ksrc/nucleus/synch.c | 390 ++++++++++++++++++++++++++++++--------------
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, 314 insertions(+), 163 deletions(-)
Index: b/include/nucleus/synch.h
===================================================================
--- a/include/nucleus/synch.h
+++ b/include/nucleus/synch.h
@@ -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);
Index: b/ksrc/nucleus/synch.c
===================================================================
--- a/ksrc/nucleus/synch.c
+++ b/ksrc/nucleus/synch.c
@@ -59,6 +59,12 @@
* - XNSYNCH_PRIO causes the threads waiting for the resource to pend
* in priority order. Otherwise, FIFO ordering is used (XNSYNCH_FIFO).
*
+ * - XNSYNCH_OWNER indicates that the synchronization object shall
+ * track its owning thread (required if XNSYNCH_PIP is selected). Note
+ * that setting this flag implies the use xnsynch_acquire and
+ * xnsynch_release instead of xnsynch_sleep_on and
+ * xnsynch_wakeup_one_sleeper/xnsynch_wakeup_this_sleeper.
+ *
* - XNSYNCH_PIP causes the priority inheritance mechanism to be
* automatically activated when a priority inversion is detected among
* threads using this object. Otherwise, no priority inheritance takes
@@ -89,7 +95,7 @@ void xnsynch_init(xnsynch_t *synch, xnfl
initph(&synch->link);
if (flags & XNSYNCH_PIP)
- flags |= XNSYNCH_PRIO; /* Obviously... */
+ flags |= XNSYNCH_PRIO | XNSYNCH_OWNER; /* Obviously... */
synch->status = flags & ~XNSYNCH_CLAIMED;
synch->owner = NULL;
@@ -98,6 +104,211 @@ void xnsynch_init(xnsynch_t *synch, xnfl
xnarch_init_display_context(synch);
}
+/*!
+ * \fn void xnsynch_sleep_on(xnsynch_t *synch, xnticks_t timeout,
+ * xntmode_t timeout_mode)
+ *
+ * \brief Sleep on an ownerless synchronization object.
+ *
+ * Makes the calling thread sleep on the specified synchronization
+ * object, waiting for it to be signaled.
+ *
+ * This service should be called by upper interfaces wanting the
+ * current thread to pend on the given resource. It must not be used
+ * with synchronization objects that are supposed to track ownership
+ * (XNSYNCH_OWNER).
+ *
+ * @param synch The descriptor address of the synchronization object
+ * to sleep on.
+ *
+ * @param timeout The timeout which may be used to limit the time the
+ * thread pends on the resource. This value is a wait time given in
+ * ticks (see note). It can either be relative, absolute monotonic, or
+ * absolute adjustable depending on @a timeout_mode. Passing XN_INFINITE
+ * @b and setting @a mode to XN_RELATIVE specifies an unbounded wait. All
+ * other values are used to initialize a watchdog timer.
+ *
+ * @param timeout_mode The mode of the @a timeout parameter. It can
+ * either be set to XN_RELATIVE, XN_ABSOLUTE, or XN_REALTIME (see also
+ * xntimer_start()).
+ *
+ * Environments:
+ *
+ * This service can be called from:
+ *
+ * - Kernel module initialization/cleanup code
+ * - Kernel-based task
+ * - User-space task
+ *
+ * Rescheduling: always.
+ *
+ * @note The @a timeout value will be interpreted as jiffies if the
+ * current thread is bound to a periodic time base (see
+ * xnpod_init_thread), or nanoseconds otherwise.
+ */
+
+void xnsynch_sleep_on(xnsynch_t *synch, xnticks_t timeout,
+ xntmode_t timeout_mode)
+{
+ xnthread_t *thread = xnpod_current_thread();
+ spl_t s;
+
+ XENO_BUGON(NUCLEUS, testbits(synch->status, XNSYNCH_OWNER));
+
+ xnlock_get_irqsave(&nklock, s);
+
+ trace_mark(xn_nucleus_synch_sleepon,
+ "thread %p thread_name %s synch %p",
+ thread, xnthread_name(thread), synch);
+
+ if (!testbits(synch->status, XNSYNCH_PRIO)) /* i.e. FIFO */
+ appendpq(&synch->pendq, &thread->plink);
+ else /* i.e. priority-sorted */
+ insertpqf(&synch->pendq, &thread->plink, thread->cprio);
+
+ xnpod_suspend_thread(thread, XNPEND, timeout, timeout_mode, synch);
+
+ xnlock_put_irqrestore(&nklock, s);
+}
+
+/*!
+ * \fn xnthread_t *xnsynch_wakeup_one_sleeper(xnsynch_t *synch);
+ * \brief Give the resource ownership to the next waiting thread.
+ *
+ * This service wakes up the thread which is currently leading the
+ * synchronization object's pending list. The sleeping thread is
+ * unblocked from its pending state, but no reschedule is performed.
+ *
+ * This service should be called by upper interfaces wanting to signal
+ * the given resource so that a single waiter is resumed. It must not
+ * be used with synchronization objects that are supposed to track
+ * ownership (XNSYNCH_OWNER not set).
+ *
+ * @param synch The descriptor address of the synchronization object
+ * whose ownership is changed.
+ *
+ * @return The descriptor address of the unblocked thread.
+ *
+ * Side-effects:
+ *
+ * - The effective priority of the previous resource owner might be
+ * lowered to its base priority value as a consequence of the priority
+ * inheritance boost being cleared.
+ *
+ * - The synchronization object ownership is transfered to the
+ * unblocked thread.
+ *
+ * Environments:
+ *
+ * This service can be called from:
+ *
+ * - Kernel module initialization/cleanup code
+ * - Interrupt service routine
+ * - Kernel-based task
+ * - User-space task
+ *
+ * Rescheduling: never.
+ */
+
+xnthread_t *xnsynch_wakeup_one_sleeper(xnsynch_t *synch)
+{
+ xnthread_t *thread = NULL;
+ xnpholder_t *holder;
+ spl_t s;
+
+ XENO_BUGON(NUCLEUS, testbits(synch->status, XNSYNCH_OWNER));
+
+ xnlock_get_irqsave(&nklock, s);
+
+ holder = getpq(&synch->pendq);
+
+ if (holder) {
+ thread = link2thread(holder, plink);
+ thread->wchan = NULL;
+ trace_mark(xn_nucleus_synch_wakeup_one,
+ "thread %p thread_name %s synch %p",
+ thread, xnthread_name(thread), synch);
+ xnpod_resume_thread(thread, XNPEND);
+ }
+
+ xnlock_put_irqrestore(&nklock, s);
+
+ xnarch_post_graph_if(synch, 0, emptypq_p(&synch->pendq));
+
+ return thread;
+}
+
+/*!
+ * \fn void xnsynch_wakeup_this_sleeper(xnsynch_t *synch, xnpholder_t *holder);
+ * \brief Give the resource ownership to a given waiting thread.
+ *
+ * This service wakes up a specific thread which is currently pending on
+ * the given synchronization object. The sleeping thread is unblocked
+ * from its pending state, but no reschedule is performed.
+ *
+ * This service should be called by upper interfaces wanting to signal
+ * the given resource so that a specific waiter is resumed. It must not
+ * be used with synchronization objects that are supposed to track
+ * ownership (XNSYNCH_OWNER not set).
+ *
+ * @param synch The descriptor address of the synchronization object
+ * whose ownership is changed.
+ *
+ * @param holder The link holder address of the thread to unblock
+ * (&thread->plink) which MUST be currently linked to the
+ * synchronization object's pending queue (i.e. synch->pendq).
+ *
+ * @return The link address of the unblocked thread in the
+ * synchronization object's pending queue.
+ *
+ * Side-effects:
+ *
+ * - The effective priority of the previous resource owner might be
+ * lowered to its base priority value as a consequence of the priority
+ * inheritance boost being cleared.
+ *
+ * - The synchronization object ownership is transfered to the
+ * unblocked thread.
+ *
+ * Environments:
+ *
+ * This service can be called from:
+ *
+ * - Kernel module initialization/cleanup code
+ * - Interrupt service routine
+ * - Kernel-based task
+ * - User-space task
+ *
+ * Rescheduling: never.
+ */
+
+xnpholder_t *xnsynch_wakeup_this_sleeper(xnsynch_t *synch, xnpholder_t *holder)
+{
+ xnthread_t *thread, *lastowner;
+ xnpholder_t *nholder;
+ spl_t s;
+
+ XENO_BUGON(NUCLEUS, testbits(synch->status, XNSYNCH_OWNER));
+
+ xnlock_get_irqsave(&nklock, s);
+
+ lastowner = synch->owner;
+ nholder = poppq(&synch->pendq, holder);
+
+ thread = link2thread(holder, plink);
+ thread->wchan = NULL;
+ trace_mark(xn_nucleus_synch_wakeup_this,
+ "thread %p thread_name %s synch %p",
+ thread, xnthread_name(thread), synch);
+ xnpod_resume_thread(thread, XNPEND);
+
+ xnlock_put_irqrestore(&nklock, s);
+
+ xnarch_post_graph_if(synch, 0, emptypq_p(&synch->pendq));
+
+ return nholder;
+}
+
/*
* xnsynch_renice_thread() -- This service is used by the PIP code to
* raise/lower a thread's priority. The thread's base priority value
@@ -125,19 +336,21 @@ static void xnsynch_renice_thread(xnthre
}
/*!
- * \fn void xnsynch_sleep_on(xnsynch_t *synch, xnticks_t timeout,
+ * \fn void xnsynch_acquire(xnsynch_t *synch, xnticks_t timeout,
* xntmode_t timeout_mode)
*
- * \brief Sleep on a synchronization object.
- *
- * Makes the calling thread sleep on the specified synchronization
- * object, waiting for it to be signaled.
+ * \brief Acquire the ownership of a synchronization object.
*
* This service should be called by upper interfaces wanting the
- * current thread to pend on the given resource.
+ * current thread to acquire the ownership of the given resource. If
+ * the resource is already assigned to a thread, the caller is
+ * suspended.
+ *
+ * This service must be used only with synchronization objects that
+ * track ownership (XNSYNCH_OWNER set.
*
* @param synch The descriptor address of the synchronization object
- * to sleep on.
+ * to acquire.
*
* @param timeout The timeout which may be used to limit the time the
* thread pends on the resource. This value is a wait time given in
@@ -158,37 +371,27 @@ static void xnsynch_renice_thread(xnthre
* - Kernel-based task
* - User-space task
*
- * Rescheduling: always.
+ * Rescheduling: possible.
*
* @note The @a timeout value will be interpreted as jiffies if the
* current thread is bound to a periodic time base (see
* xnpod_init_thread), or nanoseconds otherwise.
*/
-void xnsynch_sleep_on(xnsynch_t *synch, xnticks_t timeout,
- xntmode_t timeout_mode)
+void xnsynch_acquire(xnsynch_t *synch, xnticks_t timeout,
+ xntmode_t timeout_mode)
{
xnthread_t *thread = xnpod_current_thread(), *owner;
spl_t s;
+ XENO_BUGON(NUCLEUS, !testbits(synch->status, XNSYNCH_OWNER));
+
xnlock_get_irqsave(&nklock, s);
- trace_mark(xn_nucleus_synch_sleepon,
+ trace_mark(xn_nucleus_synch_acquire,
"thread %p thread_name %s synch %p",
thread, xnthread_name(thread), synch);
- if (!testbits(synch->status, XNSYNCH_PRIO)) { /* i.e. FIFO */
- appendpq(&synch->pendq, &thread->plink);
- xnpod_suspend_thread(thread, XNPEND, timeout, timeout_mode, synch);
- goto unlock_and_exit;
- }
-
- if (!testbits(synch->status, XNSYNCH_PIP)) { /* i.e. no ownership */
- insertpqf(&synch->pendq, &thread->plink, thread->cprio);
- xnpod_suspend_thread(thread, XNPEND, timeout, timeout_mode, synch);
- goto unlock_and_exit;
- }
-
redo:
owner = synch->owner;
@@ -198,6 +401,12 @@ redo:
goto unlock_and_exit;
}
+ if (!testbits(synch->status, XNSYNCH_PRIO)) { /* i.e. FIFO */
+ appendpq(&synch->pendq, &thread->plink);
+ xnpod_suspend_thread(thread, XNPEND, timeout, timeout_mode, synch);
+ goto unlock_and_exit;
+ }
+
if (thread->cprio > owner->cprio) {
if (xnthread_test_info(owner, XNWAKEN) && owner->wwake == synch) {
/* Ownership is still pending, steal the resource. */
@@ -207,19 +416,22 @@ redo:
goto unlock_and_exit;
}
- if (!xnthread_test_state(owner, XNBOOST)) {
- owner->bprio = owner->cprio;
- xnthread_set_state(owner, XNBOOST);
- }
+ insertpqf(&synch->pendq, &thread->plink, thread->cprio);
- if (testbits(synch->status, XNSYNCH_CLAIMED))
- removepq(&owner->claimq, &synch->link);
- else
- __setbits(synch->status, XNSYNCH_CLAIMED);
+ if (testbits(synch->status, XNSYNCH_PIP)) {
+ if (!xnthread_test_state(owner, XNBOOST)) {
+ owner->bprio = owner->cprio;
+ xnthread_set_state(owner, XNBOOST);
+ }
+
+ if (testbits(synch->status, XNSYNCH_CLAIMED))
+ removepq(&owner->claimq, &synch->link);
+ else
+ __setbits(synch->status, XNSYNCH_CLAIMED);
- insertpqf(&owner->claimq, &synch->link, thread->cprio);
- insertpqf(&synch->pendq, &thread->plink, thread->cprio);
- xnsynch_renice_thread(owner, thread->cprio);
+ insertpqf(&owner->claimq, &synch->link, thread->cprio);
+ xnsynch_renice_thread(owner, thread->cprio);
+ }
} else
insertpqf(&synch->pendq, &thread->plink, thread->cprio);
@@ -335,17 +547,17 @@ void xnsynch_renice_sleeper(xnthread_t *
}
}
-/*!
+/*!
* \fn xnthread_t *xnsynch_wakeup_one_sleeper(xnsynch_t *synch);
* \brief Give the resource ownership to the next waiting thread.
*
- * This service gives the ownership of a synchronization object to the
- * thread which is currently leading the object's pending list. The
- * sleeping thread is unblocked, but no action is taken regarding the
- * previous owner of the resource.
+ * This service releases the ownership of the given synchronization
+ * object. The thread which is currently leading the object's pending
+ * list, if any, is unblocked from its pending state. However, no
+ * reschedule is performed.
*
- * This service should be called by upper interfaces wanting to signal
- * the given resource so that a single waiter is resumed.
+ * This service must be used only with synchronization objects that
+ * track ownership (XNSYNCH_OWNER set.
*
* @param synch The descriptor address of the synchronization object
* whose ownership is changed.
@@ -373,33 +585,35 @@ void xnsynch_renice_sleeper(xnthread_t *
* Rescheduling: never.
*/
-xnthread_t *xnsynch_wakeup_one_sleeper(xnsynch_t *synch)
+struct xnthread *xnsynch_release(xnsynch_t *synch)
{
xnthread_t *thread = NULL, *lastowner;
xnpholder_t *holder;
spl_t s;
+ XENO_BUGON(NUCLEUS, !testbits(synch->status, XNSYNCH_OWNER));
+
xnlock_get_irqsave(&nklock, s);
- lastowner = synch->owner;
holder = getpq(&synch->pendq);
if (holder) {
thread = link2thread(holder, plink);
thread->wchan = NULL;
thread->wwake = synch;
+ lastowner = synch->owner;
synch->owner = thread;
xnthread_set_info(thread, XNWAKEN);
- trace_mark(xn_nucleus_synch_wakeup_one,
+ trace_mark(xn_nucleus_synch_release,
"thread %p thread_name %s synch %p",
thread, xnthread_name(thread), synch);
xnpod_resume_thread(thread, XNPEND);
+
+ if (testbits(synch->status, XNSYNCH_CLAIMED))
+ xnsynch_clear_boost(synch, lastowner);
} else
synch->owner = NULL;
- if (testbits(synch->status, XNSYNCH_CLAIMED))
- xnsynch_clear_boost(synch, lastowner);
-
xnlock_put_irqrestore(&nklock, s);
xnarch_post_graph_if(synch, 0, emptypq_p(&synch->pendq));
@@ -446,80 +660,6 @@ xnthread_t *xnsynch_peek_pendq(xnsynch_t
}
/*!
- * \fn void xnsynch_wakeup_this_sleeper(xnsynch_t *synch, xnpholder_t *holder);
- * \brief Give the resource ownership to a given waiting thread.
- *
- * This service gives the ownership of a given synchronization object
- * to a specific thread which is currently pending on it. The sleeping
- * thread is unblocked from its pending state. No action is taken
- * regarding the previous resource owner.
- *
- * This service should be called by upper interfaces wanting to signal
- * the given resource so that a specific waiter is resumed.
- *
- * @param synch The descriptor address of the synchronization object
- * whose ownership is changed.
- *
- * @param holder The link holder address of the thread to unblock
- * (&thread->plink) which MUST be currently linked to the
- * synchronization object's pending queue (i.e. synch->pendq).
- *
- * @return The link address of the unblocked thread in the
- * synchronization object's pending queue.
- *
- * Side-effects:
- *
- * - The effective priority of the previous resource owner might be
- * lowered to its base priority value as a consequence of the priority
- * inheritance boost being cleared.
- *
- * - The synchronization object ownership is transfered to the
- * unblocked thread.
- *
- * Environments:
- *
- * This service can be called from:
- *
- * - Kernel module initialization/cleanup code
- * - Interrupt service routine
- * - Kernel-based task
- * - User-space task
- *
- * Rescheduling: never.
- */
-
-xnpholder_t *xnsynch_wakeup_this_sleeper(xnsynch_t *synch, xnpholder_t *holder)
-{
- xnthread_t *thread, *lastowner;
- xnpholder_t *nholder;
- spl_t s;
-
- xnlock_get_irqsave(&nklock, s);
-
- lastowner = synch->owner;
- nholder = poppq(&synch->pendq, holder);
-
- thread = link2thread(holder, plink);
- thread->wchan = NULL;
- thread->wwake = synch;
- synch->owner = thread;
- xnthread_set_info(thread, XNWAKEN);
- trace_mark(xn_nucleus_synch_wakeup_all,
- "thread %p thread_name %s synch %p",
- thread, xnthread_name(thread), synch);
- xnpod_resume_thread(thread, XNPEND);
-
- if (testbits(synch->status, XNSYNCH_CLAIMED))
- xnsynch_clear_boost(synch, lastowner);
-
- xnlock_put_irqrestore(&nklock, s);
-
- xnarch_post_graph_if(synch, 0, emptypq_p(&synch->pendq));
-
- return nholder;
-}
-
-/*!
* \fn void xnsynch_flush(xnsynch_t *synch, xnflags_t reason);
* \brief Unblock all waiters pending on a resource.
*
@@ -679,12 +819,12 @@ void xnsynch_release_all_ownerships(xnth
for (holder = getheadpq(&thread->claimq); holder != NULL;
holder = nholder) {
- /* Since xnsynch_wakeup_one_sleeper() alters the claim
+ /* Since xnsynch_release() alters the claim
queue, we need to be conservative while scanning
it. */
xnsynch_t *synch = link2synch(holder);
nholder = nextpq(&thread->claimq, holder);
- xnsynch_wakeup_one_sleeper(synch);
+ xnsynch_release(synch);
if (synch->cleanup)
synch->cleanup(synch);
}
@@ -701,3 +841,5 @@ EXPORT_SYMBOL(xnsynch_sleep_on);
EXPORT_SYMBOL(xnsynch_wakeup_one_sleeper);
EXPORT_SYMBOL(xnsynch_wakeup_this_sleeper);
EXPORT_SYMBOL(xnsynch_peek_pendq);
+EXPORT_SYMBOL(xnsynch_acquire);
+EXPORT_SYMBOL(xnsynch_release);
Index: b/include/rtdm/rtdm_driver.h
===================================================================
--- a/include/rtdm/rtdm_driver.h
+++ b/include/rtdm/rtdm_driver.h
@@ -1134,7 +1134,7 @@ static inline void rtdm_mutex_unlock(rtd
trace_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();
}
Index: b/ksrc/skins/native/cond.c
===================================================================
--- a/ksrc/skins/native/cond.c
+++ b/ksrc/skins/native/cond.c
@@ -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 */
}
Index: b/ksrc/skins/native/mutex.c
===================================================================
--- a/ksrc/skins/native/mutex.c
+++ b/ksrc/skins/native/mutex.c
@@ -170,7 +170,8 @@ int rt_mutex_create(RT_MUTEX *mutex, con
if (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();
}
Index: b/ksrc/skins/native/task.c
===================================================================
--- a/ksrc/skins/native/task.c
+++ b/ksrc/skins/native/task.c
@@ -275,7 +275,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 */
@@ -1784,7 +1785,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
Index: b/ksrc/skins/posix/cond.c
===================================================================
--- a/ksrc/skins/posix/cond.c
+++ b/ksrc/skins/posix/cond.c
@@ -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)));
Index: b/ksrc/skins/posix/mutex.c
===================================================================
--- a/ksrc/skins/posix/mutex.c
+++ b/ksrc/skins/posix/mutex.c
@@ -85,7 +85,7 @@ int pse51_mutex_init_internal(struct __s
xnarch_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)) {
Index: b/ksrc/skins/posix/mutex.h
===================================================================
--- a/ksrc/skins/posix/mutex.h
+++ b/ksrc/skins/posix/mutex.h
@@ -173,9 +173,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)) {
@@ -219,7 +219,7 @@ static inline void pse51_mutex_unlock_in
return;
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)
Index: b/ksrc/skins/rtai/sem.c
===================================================================
--- a/ksrc/skins/rtai/sem.c
+++ b/ksrc/skins/rtai/sem.c
@@ -28,7 +28,7 @@ void rt_typed_sem_init(SEM * sem, int va
int 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. */
Index: b/ksrc/skins/rtdm/drvlib.c
===================================================================
--- a/ksrc/skins/rtdm/drvlib.c
+++ b/ksrc/skins/rtdm/drvlib.c
@@ -1384,7 +1384,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);
}
@@ -1528,14 +1529,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,
Index: b/ksrc/skins/vrtx/mx.c
===================================================================
--- a/ksrc/skins/vrtx/mx.c
+++ b/ksrc/skins/vrtx/mx.c
@@ -161,7 +161,7 @@ int sc_mcreate(unsigned int opt, int *er
inith(&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 tim
if (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;
Index: b/ksrc/skins/vxworks/semLib.c
===================================================================
--- a/ksrc/skins/vxworks/semLib.c
+++ b/ksrc/skins/vxworks/semLib.c
@@ -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;
}
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Xenomai-core] [RFC][PATCH] Factor out xnsynch_acquire/release
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
1 sibling, 1 reply; 16+ messages in thread
From: Jan Kiszka @ 2008-09-15 17:10 UTC (permalink / raw)
To: xenomai-core
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.
>
> Find a first draft of this approach attached (compile-tested). Before
> going down this round, I would like to collect opinions and finally an
> Ack on this (or and alternative approach). I also briefly thought about
> branching two xnsynch sub-objects for owner/no-owner. But that would
> likely make the changes far more complicated and invasive.
Forgot to mention that the patch applies on top of the first 4 patches
of my "fast mutex rework" series (conflicts in posix only).
Jan
PS: gna.org is dead. Hope it will recover soon...
--
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Xenomai-core] [RFC][PATCH] Factor out xnsynch_acquire/release
2008-09-15 17:10 ` Jan Kiszka
@ 2008-09-16 17:15 ` Philippe Gerum
0 siblings, 0 replies; 16+ messages in thread
From: Philippe Gerum @ 2008-09-16 17:15 UTC (permalink / raw)
To: Jan Kiszka; +Cc: xenomai-core
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.
>>
>> Find a first draft of this approach attached (compile-tested). Before
>> going down this round, I would like to collect opinions and finally an
>> Ack on this (or and alternative approach). I also briefly thought about
>> branching two xnsynch sub-objects for owner/no-owner. But that would
>> likely make the changes far more complicated and invasive.
>
> Forgot to mention that the patch applies on top of the first 4 patches
> of my "fast mutex rework" series (conflicts in posix only).
>
> Jan
>
> PS: gna.org is dead. Hope it will recover soon...
>
Server has moved. DNS are slowly catching up.
--
Philippe.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Xenomai-core] [RFC][PATCH] Factor out xnsynch_acquire/release
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-21 10:24 ` Jan Kiszka
2008-09-21 17:48 ` Gilles Chanteperdrix
1 sibling, 1 reply; 16+ messages in thread
From: Jan Kiszka @ 2008-09-21 10:24 UTC (permalink / raw)
To: xenomai-core
[-- Attachment #1: Type: text/plain, Size: 1338 bytes --]
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).
Jan
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 257 bytes --]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Xenomai-core] [RFC][PATCH] Factor out xnsynch_acquire/release
2008-09-21 10:24 ` Jan Kiszka
@ 2008-09-21 17:48 ` Gilles Chanteperdrix
2008-09-21 18:07 ` Jan Kiszka
0 siblings, 1 reply; 16+ messages in thread
From: Gilles Chanteperdrix @ 2008-09-21 17:48 UTC (permalink / raw)
To: Jan Kiszka; +Cc: xenomai-core
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 ?
--
Gilles.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Xenomai-core] [RFC][PATCH] Factor out xnsynch_acquire/release
2008-09-21 17:48 ` Gilles Chanteperdrix
@ 2008-09-21 18:07 ` Jan Kiszka
2008-09-21 19:03 ` Gilles Chanteperdrix
0 siblings, 1 reply; 16+ messages in thread
From: Jan Kiszka @ 2008-09-21 18:07 UTC (permalink / raw)
To: Gilles Chanteperdrix; +Cc: xenomai-core
[-- 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, ¶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)
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 --]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Xenomai-core] [RFC][PATCH] Factor out xnsynch_acquire/release
2008-09-21 18:07 ` Jan Kiszka
@ 2008-09-21 19:03 ` Gilles Chanteperdrix
2008-09-22 8:09 ` Jan Kiszka
2008-09-22 8:19 ` Philippe Gerum
0 siblings, 2 replies; 16+ messages in thread
From: Gilles Chanteperdrix @ 2008-09-21 19:03 UTC (permalink / raw)
To: Jan Kiszka; +Cc: xenomai-core
Jan Kiszka wrote:
> [1]http://thread.gmane.org/gmane.linux.real-time.xenomai.devel/5412/focus=5405
>
always-put-xnthread-base-into-registry.patch:
I understand the need, but I will cowardly let Philippe decide whether
he likes the implementation details.
handle-base-xn_sys_current-1.patch:
In some places (pse51_mutex_timedlock_inner for instances) you use
XN_NO_HANDLE, in others (pse51_mutex_timedlock for instances) you use
NULL, are the two equivalents ? If yes, should not we always use the
same consistently ? Otherwise looks ok.
remove-xnarch_atomic_intptr.patch:
Ok.
spread-xeno_set_current.patch:
Ok. This is even a bug fix.
xnsynch refactoring:
things have moved too much to see what has really changed in
xnsynch_wakeup_one_sleeper and xnsynch_sleep_on. But is not there a
common behaviour between the old and new services that could be factored
? But otherwise I agree with the general idea of the patch, this is what
we had discussed with Philippe.
--
Gilles.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Xenomai-core] [RFC][PATCH] Factor out xnsynch_acquire/release
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:19 ` Philippe Gerum
1 sibling, 1 reply; 16+ messages in thread
From: Jan Kiszka @ 2008-09-22 8:09 UTC (permalink / raw)
To: Gilles Chanteperdrix; +Cc: xenomai-core
Gilles Chanteperdrix wrote:
> Jan Kiszka wrote:
>
>> [1]http://thread.gmane.org/gmane.linux.real-time.xenomai.devel/5412/focus=5405
>>
> always-put-xnthread-base-into-registry.patch:
> I understand the need, but I will cowardly let Philippe decide whether
> he likes the implementation details.
>
> handle-base-xn_sys_current-1.patch:
> In some places (pse51_mutex_timedlock_inner for instances) you use
> XN_NO_HANDLE, in others (pse51_mutex_timedlock for instances) you use
> NULL, are the two equivalents ? If yes, should not we always use the
> same consistently ? Otherwise looks ok.
I fail to find the NULL spots - which pse51_mutex_timedlock do you mean?
>
> remove-xnarch_atomic_intptr.patch:
> Ok.
>
> spread-xeno_set_current.patch:
> Ok. This is even a bug fix.
>
> xnsynch refactoring:
> things have moved too much to see what has really changed in
> xnsynch_wakeup_one_sleeper and xnsynch_sleep_on. But is not there a
> common behaviour between the old and new services that could be factored
> ? But otherwise I agree with the general idea of the patch, this is what
> we had discussed with Philippe.
Yes, the diff is unfortunate due to a reordering of the function within
synch.c. Here is a direct diff of both services:
--- a 2008-09-22 10:06:56.000000000 +0200
+++ b 2008-09-22 10:07:39.000000000 +0200
@@ -1,112 +1,47 @@
void xnsynch_sleep_on(xnsynch_t *synch, xnticks_t timeout,
xntmode_t timeout_mode)
{
- xnthread_t *thread = xnpod_current_thread(), *owner;
+ xnthread_t *thread = xnpod_current_thread();
spl_t s;
+ XENO_BUGON(NUCLEUS, testbits(synch->status, XNSYNCH_OWNER));
+
xnlock_get_irqsave(&nklock, s);
trace_mark(xn_nucleus_synch_sleepon,
"thread %p thread_name %s synch %p",
thread, xnthread_name(thread), synch);
- if (!testbits(synch->status, XNSYNCH_PRIO)) { /* i.e. FIFO */
+ if (!testbits(synch->status, XNSYNCH_PRIO)) /* i.e. FIFO */
appendpq(&synch->pendq, &thread->plink);
- xnpod_suspend_thread(thread, XNPEND, timeout, timeout_mode, synch);
- goto unlock_and_exit;
- }
-
- if (!testbits(synch->status, XNSYNCH_PIP)) { /* i.e. no ownership */
- insertpqf(&synch->pendq, &thread->plink, thread->cprio);
- xnpod_suspend_thread(thread, XNPEND, timeout, timeout_mode, synch);
- goto unlock_and_exit;
- }
-
-redo:
- owner = synch->owner;
-
- if (!owner) {
- synch->owner = thread;
- xnthread_clear_info(thread, XNRMID | XNTIMEO | XNBREAK);
- goto unlock_and_exit;
- }
-
- if (thread->cprio > owner->cprio) {
- if (xnthread_test_info(owner, XNWAKEN) && owner->wwake == synch) {
- /* Ownership is still pending, steal the resource. */
- synch->owner = thread;
- xnthread_clear_info(thread, XNRMID | XNTIMEO | XNBREAK);
- xnthread_set_info(owner, XNROBBED);
- goto unlock_and_exit;
- }
-
- if (!xnthread_test_state(owner, XNBOOST)) {
- owner->bprio = owner->cprio;
- xnthread_set_state(owner, XNBOOST);
- }
-
- if (testbits(synch->status, XNSYNCH_CLAIMED))
- removepq(&owner->claimq, &synch->link);
- else
- __setbits(synch->status, XNSYNCH_CLAIMED);
-
- insertpqf(&owner->claimq, &synch->link, thread->cprio);
- insertpqf(&synch->pendq, &thread->plink, thread->cprio);
- xnsynch_renice_thread(owner, thread->cprio);
- } else
+ else /* i.e. priority-sorted */
insertpqf(&synch->pendq, &thread->plink, thread->cprio);
xnpod_suspend_thread(thread, XNPEND, timeout, timeout_mode, synch);
- if (xnthread_test_info(thread, XNRMID | XNTIMEO | XNBREAK))
- goto unlock_and_exit;
-
- if (xnthread_test_info(thread, XNROBBED)) {
- /* Somebody stole us the ownership while we were ready
- to run, waiting for the CPU: we need to wait again
- for the resource. */
- if (timeout_mode != XN_RELATIVE || timeout == XN_INFINITE)
- goto redo;
- timeout = xntimer_get_timeout_stopped(&thread->rtimer);
- if (timeout > 1) /* Otherwise, it's too late. */
- goto redo;
- xnthread_set_info(thread, XNTIMEO);
- }
-
- unlock_and_exit:
-
- thread->wwake = NULL;
- xnthread_clear_info(thread, XNWAKEN);
-
xnlock_put_irqrestore(&nklock, s);
}
xnthread_t *xnsynch_wakeup_one_sleeper(xnsynch_t *synch)
{
- xnthread_t *thread = NULL, *lastowner;
+ xnthread_t *thread = NULL;
xnpholder_t *holder;
spl_t s;
+ XENO_BUGON(NUCLEUS, testbits(synch->status, XNSYNCH_OWNER));
+
xnlock_get_irqsave(&nklock, s);
- lastowner = synch->owner;
holder = getpq(&synch->pendq);
if (holder) {
thread = link2thread(holder, plink);
thread->wchan = NULL;
- thread->wwake = synch;
- synch->owner = thread;
- xnthread_set_info(thread, XNWAKEN);
trace_mark(xn_nucleus_synch_wakeup_one,
"thread %p thread_name %s synch %p",
thread, xnthread_name(thread), synch);
xnpod_resume_thread(thread, XNPEND);
- } else
- synch->owner = NULL;
-
- if (testbits(synch->status, XNSYNCH_CLAIMED))
- xnsynch_clear_boost(synch, lastowner);
+ }
xnlock_put_irqrestore(&nklock, s);
Jan
--
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Xenomai-core] [RFC][PATCH] Factor out xnsynch_acquire/release
2008-09-22 8:09 ` Jan Kiszka
@ 2008-09-22 8:18 ` Gilles Chanteperdrix
2008-09-22 8:57 ` Jan Kiszka
0 siblings, 1 reply; 16+ messages in thread
From: Gilles Chanteperdrix @ 2008-09-22 8:18 UTC (permalink / raw)
To: Jan Kiszka; +Cc: xenomai-core
Jan Kiszka wrote:
> Gilles Chanteperdrix wrote:
>> Jan Kiszka wrote:
>>
>>> [1]http://thread.gmane.org/gmane.linux.real-time.xenomai.devel/5412/focus=5405
>>>
>> always-put-xnthread-base-into-registry.patch:
>> I understand the need, but I will cowardly let Philippe decide whether
>> he likes the implementation details.
>>
>> handle-base-xn_sys_current-1.patch:
>> In some places (pse51_mutex_timedlock_inner for instances) you use
>> XN_NO_HANDLE, in others (pse51_mutex_timedlock for instances) you use
>> NULL, are the two equivalents ? If yes, should not we always use the
>> same consistently ? Otherwise looks ok.
>
> I fail to find the NULL spots - which pse51_mutex_timedlock do you mean?
A few excerpts:
@@ -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;
@@ -128,32 +136,41 @@ static inline int pse51_mutex_timedlock_
(...)
- 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);
@@ -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)
--
Gilles.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Xenomai-core] [RFC][PATCH] Factor out xnsynch_acquire/release
2008-09-21 19:03 ` Gilles Chanteperdrix
2008-09-22 8:09 ` Jan Kiszka
@ 2008-09-22 8:19 ` Philippe Gerum
2008-09-23 14:59 ` Jan Kiszka
1 sibling, 1 reply; 16+ messages in thread
From: Philippe Gerum @ 2008-09-22 8:19 UTC (permalink / raw)
To: Gilles Chanteperdrix; +Cc: Jan Kiszka, xenomai-core
Gilles Chanteperdrix wrote:
> Jan Kiszka wrote:
>
>> [1]http://thread.gmane.org/gmane.linux.real-time.xenomai.devel/5412/focus=5405
>>
> always-put-xnthread-base-into-registry.patch:
> I understand the need, but I will cowardly let Philippe decide whether
> he likes the implementation details.
>
I'm ok with the basic purpose of those changes, but if they are aimed at
allowing direct lookups from the xnsynch code into the registry so that base
object pointers can be safely assumed to be returned for threads, I would define
specialized xnthread_register() and xnthread_lookup() calls to explicitly state
that we do want to index struct xnthread pointers, and not any random type as
the registry would otherwise permit.
Also, for readability purpose, please factor the outer lookup code as much as
possible.
e.g.
static inline RT_TASK *lookup_task(xnhandle_t handle)
{
return thread2rtask(xnthread_lookup(handle));
}
> handle-base-xn_sys_current-1.patch:
> In some places (pse51_mutex_timedlock_inner for instances) you use
> XN_NO_HANDLE, in others (pse51_mutex_timedlock for instances) you use
> NULL, are the two equivalents ? If yes, should not we always use the
> same consistently ? Otherwise looks ok.
>
> remove-xnarch_atomic_intptr.patch:
> Ok.
>
> spread-xeno_set_current.patch:
> Ok. This is even a bug fix.
>
> xnsynch refactoring:
> things have moved too much to see what has really changed in
> xnsynch_wakeup_one_sleeper and xnsynch_sleep_on. But is not there a
> common behaviour between the old and new services that could be factored
> ? But otherwise I agree with the general idea of the patch, this is what
> we had discussed with Philippe.
>
--
Philippe.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Xenomai-core] [RFC][PATCH] Factor out xnsynch_acquire/release
2008-09-22 8:18 ` Gilles Chanteperdrix
@ 2008-09-22 8:57 ` Jan Kiszka
2008-09-22 18:41 ` Gilles Chanteperdrix
0 siblings, 1 reply; 16+ messages in thread
From: Jan Kiszka @ 2008-09-22 8:57 UTC (permalink / raw)
To: Gilles Chanteperdrix; +Cc: xenomai-core
Gilles Chanteperdrix wrote:
> Jan Kiszka wrote:
>> Gilles Chanteperdrix wrote:
>>> Jan Kiszka wrote:
>>>
>>>> [1]http://thread.gmane.org/gmane.linux.real-time.xenomai.devel/5412/focus=5405
>>>>
>>> always-put-xnthread-base-into-registry.patch:
>>> I understand the need, but I will cowardly let Philippe decide whether
>>> he likes the implementation details.
>>>
>>> handle-base-xn_sys_current-1.patch:
>>> In some places (pse51_mutex_timedlock_inner for instances) you use
>>> XN_NO_HANDLE, in others (pse51_mutex_timedlock for instances) you use
>>> NULL, are the two equivalents ? If yes, should not we always use the
>>> same consistently ? Otherwise looks ok.
>> I fail to find the NULL spots - which pse51_mutex_timedlock do you mean?
>
> A few excerpts:
>
> @@ -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;
>
>
> @@ -128,32 +136,41 @@ static inline int pse51_mutex_timedlock_
> (...)
> - 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);
>
> @@ -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)
>
Ah, you mean checking against non-zero - that can be changed of course.
Updated patch below, hope I caught them all.
Jan
---
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 | 41 ++++++++++++-----------
22 files changed, 208 insertions(+), 83 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) != 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;
}
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 != XN_NO_HANDLE)) {
+ 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 == XN_NO_HANDLE) {
/* 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) != XN_NO_HANDLE)
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,10 +149,10 @@ 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)
+ if (cur == XN_NO_HANDLE)
return EPERM;
if (unlikely(cb_try_read_lock(&shadow->lock, s)))
@@ -163,8 +163,8 @@ int __wrap_pthread_mutex_lock(pthread_mu
goto out;
}
- owner = xnarch_atomic_intptr_cmpxchg(get_ownerp(shadow), NULL, cur);
- if (likely(!owner)) {
+ owner = xnarch_atomic_cmpxchg(get_ownerp(shadow), XN_NO_HANDLE, cur);
+ if (likely(owner == XN_NO_HANDLE)) {
shadow->lockcnt = 1;
cb_read_unlock(&shadow->lock, s);
return 0;
@@ -210,10 +210,10 @@ 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)
+ if (cur == XN_NO_HANDLE)
return EPERM;
if (unlikely(cb_try_read_lock(&shadow->lock, s)))
@@ -224,8 +224,8 @@ int __wrap_pthread_mutex_timedlock(pthre
goto out;
}
- owner = xnarch_atomic_intptr_cmpxchg(get_ownerp(shadow), NULL, cur);
- if (likely(!owner)) {
+ owner = xnarch_atomic_cmpxchg(get_ownerp(shadow), XN_NO_HANDLE, cur);
+ if (likely(owner == XN_NO_HANDLE)) {
shadow->lockcnt = 1;
cb_read_unlock(&shadow->lock, s);
return 0;
@@ -271,10 +271,10 @@ 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)
+ if (cur == XN_NO_HANDLE)
return EPERM;
if (unlikely(cb_try_read_lock(&shadow->lock, s)))
@@ -285,8 +285,8 @@ int __wrap_pthread_mutex_trylock(pthread
goto out;
}
- owner = xnarch_atomic_intptr_cmpxchg(get_ownerp(shadow), NULL, cur);
- if (likely(!owner)) {
+ owner = xnarch_atomic_cmpxchg(get_ownerp(shadow), XN_NO_HANDLE, cur);
+ if (likely(owner == XN_NO_HANDLE)) {
shadow->lockcnt = 1;
cb_read_unlock(&shadow->lock, s);
return 0;
@@ -325,11 +325,11 @@ 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)
+ if (cur == XN_NO_HANDLE)
return EPERM;
if (unlikely(cb_try_read_lock(&shadow->lock, s)))
@@ -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.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Xenomai-core] [RFC][PATCH] Factor out xnsynch_acquire/release
2008-09-22 8:57 ` Jan Kiszka
@ 2008-09-22 18:41 ` Gilles Chanteperdrix
2008-09-23 8:44 ` Jan Kiszka
0 siblings, 1 reply; 16+ messages in thread
From: Gilles Chanteperdrix @ 2008-09-22 18:41 UTC (permalink / raw)
To: Jan Kiszka; +Cc: xenomai-core
Jan Kiszka wrote:
> Gilles Chanteperdrix wrote:
>> Jan Kiszka wrote:
>>> Gilles Chanteperdrix wrote:
>>>> Jan Kiszka wrote:
>>>>
>>>>> [1]http://thread.gmane.org/gmane.linux.real-time.xenomai.devel/5412/focus=5405
>>>>>
>>>> always-put-xnthread-base-into-registry.patch:
>>>> I understand the need, but I will cowardly let Philippe decide whether
>>>> he likes the implementation details.
>>>>
>>>> handle-base-xn_sys_current-1.patch:
>>>> In some places (pse51_mutex_timedlock_inner for instances) you use
>>>> XN_NO_HANDLE, in others (pse51_mutex_timedlock for instances) you use
>>>> NULL, are the two equivalents ? If yes, should not we always use the
>>>> same consistently ? Otherwise looks ok.
>>> I fail to find the NULL spots - which pse51_mutex_timedlock do you mean?
>> A few excerpts:
>
> Ah, you mean checking against non-zero - that can be changed of course.
> Updated patch below, hope I caught them all.
Ok. Looks good to me. Minus the bug in mutex_save_count, but this can be
changed later.
--
Gilles.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Xenomai-core] [RFC][PATCH] Factor out xnsynch_acquire/release
2008-09-22 18:41 ` Gilles Chanteperdrix
@ 2008-09-23 8:44 ` Jan Kiszka
2008-09-23 8:45 ` Gilles Chanteperdrix
0 siblings, 1 reply; 16+ messages in thread
From: Jan Kiszka @ 2008-09-23 8:44 UTC (permalink / raw)
To: Gilles Chanteperdrix; +Cc: xenomai-core
Gilles Chanteperdrix wrote:
> Jan Kiszka wrote:
>> Gilles Chanteperdrix wrote:
>>> Jan Kiszka wrote:
>>>> Gilles Chanteperdrix wrote:
>>>>> Jan Kiszka wrote:
>>>>>
>>>>>> [1]http://thread.gmane.org/gmane.linux.real-time.xenomai.devel/5412/focus=5405
>>>>>>
>>>>> always-put-xnthread-base-into-registry.patch:
>>>>> I understand the need, but I will cowardly let Philippe decide whether
>>>>> he likes the implementation details.
>>>>>
>>>>> handle-base-xn_sys_current-1.patch:
>>>>> In some places (pse51_mutex_timedlock_inner for instances) you use
>>>>> XN_NO_HANDLE, in others (pse51_mutex_timedlock for instances) you use
>>>>> NULL, are the two equivalents ? If yes, should not we always use the
>>>>> same consistently ? Otherwise looks ok.
>>>> I fail to find the NULL spots - which pse51_mutex_timedlock do you mean?
>>> A few excerpts:
>> Ah, you mean checking against non-zero - that can be changed of course.
>> Updated patch below, hope I caught them all.
>
> Ok. Looks good to me. Minus the bug in mutex_save_count, but this can be
> changed later.
??? Which bug?
Jan
--
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Xenomai-core] [RFC][PATCH] Factor out xnsynch_acquire/release
2008-09-23 8:44 ` Jan Kiszka
@ 2008-09-23 8:45 ` Gilles Chanteperdrix
2008-09-23 9:01 ` Jan Kiszka
0 siblings, 1 reply; 16+ messages in thread
From: Gilles Chanteperdrix @ 2008-09-23 8:45 UTC (permalink / raw)
To: Jan Kiszka; +Cc: xenomai-core
Jan Kiszka wrote:
> Gilles Chanteperdrix wrote:
>> Jan Kiszka wrote:
>>> Gilles Chanteperdrix wrote:
>>>> Jan Kiszka wrote:
>>>>> Gilles Chanteperdrix wrote:
>>>>>> Jan Kiszka wrote:
>>>>>>
>>>>>>> [1]http://thread.gmane.org/gmane.linux.real-time.xenomai.devel/5412/focus=5405
>>>>>>>
>>>>>> always-put-xnthread-base-into-registry.patch:
>>>>>> I understand the need, but I will cowardly let Philippe decide whether
>>>>>> he likes the implementation details.
>>>>>>
>>>>>> handle-base-xn_sys_current-1.patch:
>>>>>> In some places (pse51_mutex_timedlock_inner for instances) you use
>>>>>> XN_NO_HANDLE, in others (pse51_mutex_timedlock for instances) you use
>>>>>> NULL, are the two equivalents ? If yes, should not we always use the
>>>>>> same consistently ? Otherwise looks ok.
>>>>> I fail to find the NULL spots - which pse51_mutex_timedlock do you mean?
>>>> A few excerpts:
>>> Ah, you mean checking against non-zero - that can be changed of course.
>>> Updated patch below, hope I caught them all.
>> Ok. Looks good to me. Minus the bug in mutex_save_count, but this can be
>> changed later.
>
> ??? Which bug?
The fact that mutex_save_count uses xnsynch_nsleepers instead of
mutex->sleepers.
--
Gilles.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Xenomai-core] [RFC][PATCH] Factor out xnsynch_acquire/release
2008-09-23 8:45 ` Gilles Chanteperdrix
@ 2008-09-23 9:01 ` Jan Kiszka
0 siblings, 0 replies; 16+ messages in thread
From: Jan Kiszka @ 2008-09-23 9:01 UTC (permalink / raw)
To: Gilles Chanteperdrix; +Cc: xenomai-core
Gilles Chanteperdrix wrote:
> Jan Kiszka wrote:
>> Gilles Chanteperdrix wrote:
>>> Jan Kiszka wrote:
>>>> Gilles Chanteperdrix wrote:
>>>>> Jan Kiszka wrote:
>>>>>> Gilles Chanteperdrix wrote:
>>>>>>> Jan Kiszka wrote:
>>>>>>>
>>>>>>>> [1]http://thread.gmane.org/gmane.linux.real-time.xenomai.devel/5412/focus=5405
>>>>>>>>
>>>>>>> always-put-xnthread-base-into-registry.patch:
>>>>>>> I understand the need, but I will cowardly let Philippe decide whether
>>>>>>> he likes the implementation details.
>>>>>>>
>>>>>>> handle-base-xn_sys_current-1.patch:
>>>>>>> In some places (pse51_mutex_timedlock_inner for instances) you use
>>>>>>> XN_NO_HANDLE, in others (pse51_mutex_timedlock for instances) you use
>>>>>>> NULL, are the two equivalents ? If yes, should not we always use the
>>>>>>> same consistently ? Otherwise looks ok.
>>>>>> I fail to find the NULL spots - which pse51_mutex_timedlock do you mean?
>>>>> A few excerpts:
>>>> Ah, you mean checking against non-zero - that can be changed of course.
>>>> Updated patch below, hope I caught them all.
>>> Ok. Looks good to me. Minus the bug in mutex_save_count, but this can be
>>> changed later.
>> ??? Which bug?
>
> The fact that mutex_save_count uses xnsynch_nsleepers instead of
> mutex->sleepers.
Ah, ok. Forgot about this as some of my rejected patches changed that
part anyway.
Jan
--
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Xenomai-core] [RFC][PATCH] Factor out xnsynch_acquire/release
2008-09-22 8:19 ` Philippe Gerum
@ 2008-09-23 14:59 ` Jan Kiszka
0 siblings, 0 replies; 16+ messages in thread
From: Jan Kiszka @ 2008-09-23 14:59 UTC (permalink / raw)
To: rpm; +Cc: xenomai-core
Philippe Gerum wrote:
> Gilles Chanteperdrix wrote:
>> Jan Kiszka wrote:
>>
>>> [1]http://thread.gmane.org/gmane.linux.real-time.xenomai.devel/5412/focus=5405
>>>
>> always-put-xnthread-base-into-registry.patch:
>> I understand the need, but I will cowardly let Philippe decide whether
>> he likes the implementation details.
>>
>
> I'm ok with the basic purpose of those changes, but if they are aimed at
> allowing direct lookups from the xnsynch code into the registry so that base
> object pointers can be safely assumed to be returned for threads, I would define
> specialized xnthread_register() and xnthread_lookup() calls to explicitly state
> that we do want to index struct xnthread pointers, and not any random type as
> the registry would otherwise permit.
>
> Also, for readability purpose, please factor the outer lookup code as much as
> possible.
>
> e.g.
> static inline RT_TASK *lookup_task(xnhandle_t handle)
> {
> return thread2rtask(xnthread_lookup(handle));
> }
Makes sense, will refactor the patch accordingly.
>
>> handle-base-xn_sys_current-1.patch:
>> In some places (pse51_mutex_timedlock_inner for instances) you use
>> XN_NO_HANDLE, in others (pse51_mutex_timedlock for instances) you use
>> NULL, are the two equivalents ? If yes, should not we always use the
>> same consistently ? Otherwise looks ok.
>>
>> remove-xnarch_atomic_intptr.patch:
>> Ok.
>>
>> spread-xeno_set_current.patch:
>> Ok. This is even a bug fix.
>>
>> xnsynch refactoring:
>> things have moved too much to see what has really changed in
>> xnsynch_wakeup_one_sleeper and xnsynch_sleep_on. But is not there a
>> common behaviour between the old and new services that could be factored
>> ? But otherwise I agree with the general idea of the patch, this is what
>> we had discussed with Philippe.
>>
The rest, specifically the approach of the last patch, is OK for you as
well?
Jan
--
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2008-09-23 14:59 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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
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.