* [Xenomai-help] What have I misunderstood about condition variables
@ 2008-03-11 18:19 Anders Blomdell
2008-03-11 18:27 ` Gilles Chanteperdrix
0 siblings, 1 reply; 8+ messages in thread
From: Anders Blomdell @ 2008-03-11 18:19 UTC (permalink / raw)
To: xenomai-help
Why do I get the following output (Xenomai 2.4.2 / kernel 2.6.24.3):
ABCaAbBCABCcd 3
aAbBCABCcd 5
aAbBCABCcd 7
aAbBCABCcd 9
aAbBCABCcd 11
aAbBCABCcd 13
>From this small program:
#include <native/cond.h>
#include <native/mutex.h>
#include <native/task.h>
#include <native/timer.h>
#include <rtdk.h>
#include <sys/mman.h>
RT_TASK main_task, producer_task, consumer_task;
RT_MUTEX mutex;
RT_COND cond;
int data;
static void producer(void *arg)
{
while(1) {
rt_task_set_mode(0, T_PRIMARY, 0);
rt_printf("A");
rt_mutex_acquire(&mutex, TM_INFINITE);
rt_printf("B");
data++;
rt_mutex_release(&mutex);
rt_mutex_acquire(&mutex, TM_INFINITE);
rt_cond_broadcast(&cond);
rt_printf("C");
rt_mutex_release(&mutex);
rt_task_sleep(100000000L);
}
}
static void consumer(void *arg)
{
while(1) {
int err;
rt_task_set_mode(T_PRIMARY, 0, 0);
rt_mutex_acquire(&mutex, TM_INFINITE);
rt_printf("a");
rt_task_sleep(1000000000L);
rt_printf("b");
err = rt_cond_wait(&cond, &mutex, TM_INFINITE);
rt_printf("c");
rt_mutex_release(&mutex);
rt_printf("d %d\n", data);
}
}
int main(int argc, char *argv[])
{
mlockall(MCL_CURRENT|MCL_FUTURE);
rt_print_auto_init(1);
rt_task_shadow(&main_task, NULL, 1, T_FPU);
rt_mutex_create(&mutex, NULL);
rt_cond_create (&cond, NULL);
rt_task_create(&producer_task, NULL, 0, 50, 0);
rt_task_start(&producer_task, &producer, NULL);
rt_task_create(&consumer_task, NULL, 0, 20, 0);
rt_task_start(&consumer_task, &consumer, &consumer_task);
while (1) {
rt_task_sleep(1000000000L);
}
return 0;
}
To me the symptoms indicate that the high priority producer gets the mutex and
signals it before the consumer has properly started to wait on the condition.
Regards
Anders Blomdell
--
Anders Blomdell Email: anders.blomdell@domain.hid
Department of Automatic Control
Lund University Phone: +46 46 222 4625
P.O. Box 118 Fax: +46 46 138118
SE-221 00 Lund, Sweden
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Xenomai-help] What have I misunderstood about condition variables
2008-03-11 18:19 [Xenomai-help] What have I misunderstood about condition variables Anders Blomdell
@ 2008-03-11 18:27 ` Gilles Chanteperdrix
2008-03-11 19:27 ` Anders Blomdell
0 siblings, 1 reply; 8+ messages in thread
From: Gilles Chanteperdrix @ 2008-03-11 18:27 UTC (permalink / raw)
To: Anders Blomdell; +Cc: xenomai-help
On Tue, Mar 11, 2008 at 7:19 PM, Anders Blomdell
> To me the symptoms indicate that the high priority producer gets the mutex and
> signals it before the consumer has properly started to wait on the condition.
I have not read your program in detail, but what may be your problem
is that condition variables are not semaphores: if you signal a
condition variable when nobody is waiting the signal is lost. A
condition variable is supposed to be associated with a condition
relying on variable external to the condition variables itself.
The following posix construct waits that the variable a changes values to 1:
waiter:
pthread_mutex_lock(&mutex);
while (a != 1)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
signaler:
pthread_mutex_lock(&mutex);
a = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
Note the while loop, instead of a simple if, it is necessary to handle
correctly spurious wakeups.
--
Gilles Chanteperdrix
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Xenomai-help] What have I misunderstood about condition variables
2008-03-11 18:27 ` Gilles Chanteperdrix
@ 2008-03-11 19:27 ` Anders Blomdell
2008-03-11 20:13 ` [Xenomai-core] " Anders Blomdell
2008-03-11 23:00 ` Gilles Chanteperdrix
0 siblings, 2 replies; 8+ messages in thread
From: Anders Blomdell @ 2008-03-11 19:27 UTC (permalink / raw)
To: Gilles Chanteperdrix; +Cc: xenomai-help
Gilles Chanteperdrix wrote:
> On Tue, Mar 11, 2008 at 7:19 PM, Anders Blomdell
>> To me the symptoms indicate that the high priority producer gets the mutex and
>> signals it before the consumer has properly started to wait on the condition.
>
> I have not read your program in detail, but what may be your problem
> is that condition variables are not semaphores: if you signal a
> condition variable when nobody is waiting the signal is lost.
I know this, but the problem is that the program loses signals when it is
waiting. In the consumer:
rt_mutex_acquire(&mutex, TM_INFINITE);
rt_printf("a");
rt_task_sleep(1000000000L);
rt_printf("b");
err = rt_cond_wait(&cond, &mutex, TM_INFINITE);
rt_printf("c");
rt_mutex_release(&mutex);
rt_printf("d %d\n", data);
i.e. after a 'b' has been written, the consumer is waiting on the condition
(Yes, I know that I access data outside the mutex...).
In the producer:
rt_printf("B");
data++;
rt_mutex_release(&mutex);
rt_mutex_acquire(&mutex, TM_INFINITE);
rt_cond_broadcast(&cond);
rt_printf("C");
rt_mutex_release(&mutex);
rt_task_sleep(100000000L);
i.e. the condition is signalled just before 'C' is written.
To elaborate on the [unexpected] output sequence:
a (consumer inside mutex)
A (producer about to enter mutex)
b (consumer starts waiting on condition)
B (producer has entered mutex)
C (producer has signalled condition)
...here I would have expected the consumer to resume...
A (producer has slept for 1 second, outside mutex)
B (producer has entered mutex)
C (producer has signalled condition)
c (consumer has got the second signal on condition)
d (consumer has left mutex)
> condition variable is supposed to be associated with a condition
> relying on variable external to the condition variables itself.
Yes I know all this, but the problem is that a high priority thread waiting for
the mutex, claims the mutex and signals the condition before the low priority
thread has started to wait for the condition (even ).
>...
> Note the while loop, instead of a simple if, it is necessary to handle
> correctly spurious wakeups.
My problem is the opposite, I don't get the wakeups :-(
The following program is more like my original problem (which was tricky to
isolate):
#include <native/cond.h>
#include <native/mutex.h>
#include <native/task.h>
#include <native/timer.h>
#include <rtdk.h>
#include <sys/mman.h>
RT_TASK main_task, producer_task, consumer_task;
RT_MUTEX mutex;
RT_COND cond;
int waiting, signalled;
static void producer(void *arg)
{
while(1) {
rt_task_set_mode(0, T_PRIMARY, 0);
rt_printf("Producer sleep...\n");
rt_task_sleep(1000000000L);
rt_printf("...producer slept\n");
rt_mutex_acquire(&mutex, TM_INFINITE);
rt_printf("Producer has entered waiting=%d, signalled=%d\n",
waiting, signalled);
if (waiting && !signalled) {
rt_cond_broadcast(&cond);
signalled = 1;
rt_printf(" sent signal\n");
}
rt_mutex_release(&mutex);
}
}
static void consumer(void *arg)
{
while(1) {
int err;
rt_task_set_mode(T_PRIMARY, 0, 0);
rt_mutex_acquire(&mutex, TM_INFINITE);
rt_task_sleep(1000000000L);
waiting = 1;
signalled = 0;
rt_printf("Consumer about to wait waiting=%d, signalled=%d\n",
waiting, signalled);
err = rt_cond_wait(&cond, &mutex, 2000000000L);
if (err != 0 && signalled) {
rt_printf("Consumer not awoken err=%d, signalled=%d\n",
err, signalled);
} else {
rt_printf("Consumer awoken\n");
}
rt_mutex_release(&mutex);
}
}
int main(int argc, char *argv[])
{
mlockall(MCL_CURRENT|MCL_FUTURE);
rt_print_auto_init(1);
rt_task_shadow(&main_task, NULL, 1, T_FPU);
rt_mutex_create(&mutex, NULL);
rt_cond_create (&cond, NULL);
rt_task_create(&producer_task, NULL, 0, 50, 0);
rt_task_start(&producer_task, &producer, NULL);
rt_task_create(&consumer_task, NULL, 0, 20, 0);
rt_task_start(&consumer_task, &consumer, &consumer_task);
while (1) {
rt_task_sleep(1000000000L);
}
return 0;
}
And here I get the output:
Producer sleep...
...producer slept
Consumer about to wait waiting=1, signalled=0
Producer has entered waiting=1, signalled=0
sent signal
Producer sleep...
...producer slept
Producer has entered waiting=1, signalled=1
Producer sleep...
Consumer not awoken err=-110, signalled=1
...producer slept
Producer has entered waiting=1, signalled=1
Producer sleep...
...producer slept
Consumer about to wait waiting=1, signalled=0
Producer has entered waiting=1, signalled=0
sent signal
Producer sleep...
...producer slept
Producer has entered waiting=1, signalled=1
Producer sleep...
Consumer not awoken err=-110, signalled=1
...producer slept
Producer has entered waiting=1, signalled=1
Producer sleep...
What am I missing?
--
Anders Blomdell Email: anders.blomdell@domain.hid
Department of Automatic Control
Lund University Phone: +46 46 222 4625
P.O. Box 118 Fax: +46 46 138118
SE-221 00 Lund, Sweden
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Xenomai-core] [Xenomai-help] What have I misunderstood about condition variables
2008-03-11 19:27 ` Anders Blomdell
@ 2008-03-11 20:13 ` Anders Blomdell
2008-03-12 14:14 ` Philippe Gerum
2008-03-11 23:00 ` Gilles Chanteperdrix
1 sibling, 1 reply; 8+ messages in thread
From: Anders Blomdell @ 2008-03-11 20:13 UTC (permalink / raw)
To: xenomai-core; +Cc: xenomai-help
Anders Blomdell wrote:
> Gilles Chanteperdrix wrote:
>> On Tue, Mar 11, 2008 at 7:19 PM, Anders Blomdell
>>> To me the symptoms indicate that the high priority producer gets the mutex and
>>> signals it before the consumer has properly started to wait on the condition.
>> I have not read your program in detail, but what may be your problem
>> is that condition variables are not semaphores: if you signal a
>> condition variable when nobody is waiting the signal is lost.
> I know this, but the problem is that the program loses signals when it is
> waiting. In the consumer:
>
> rt_mutex_acquire(&mutex, TM_INFINITE);
> rt_printf("a");
> rt_task_sleep(1000000000L);
> rt_printf("b");
> err = rt_cond_wait(&cond, &mutex, TM_INFINITE);
> rt_printf("c");
> rt_mutex_release(&mutex);
> rt_printf("d %d\n", data);
>
> i.e. after a 'b' has been written, the consumer is waiting on the condition
> (Yes, I know that I access data outside the mutex...).
>
> In the producer:
>
> rt_printf("B");
> data++;
> rt_mutex_release(&mutex);
> rt_mutex_acquire(&mutex, TM_INFINITE);
> rt_cond_broadcast(&cond);
> rt_printf("C");
> rt_mutex_release(&mutex);
> rt_task_sleep(100000000L);
>
> i.e. the condition is signalled just before 'C' is written.
>
> To elaborate on the [unexpected] output sequence:
>
> a (consumer inside mutex)
> A (producer about to enter mutex)
> b (consumer starts waiting on condition)
> B (producer has entered mutex)
> C (producer has signalled condition)
> ...here I would have expected the consumer to resume...
> A (producer has slept for 1 second, outside mutex)
> B (producer has entered mutex)
> C (producer has signalled condition)
> c (consumer has got the second signal on condition)
> d (consumer has left mutex)
>
>
>
>> condition variable is supposed to be associated with a condition
>> relying on variable external to the condition variables itself.
> Yes I know all this, but the problem is that a high priority thread waiting for
> the mutex, claims the mutex and signals the condition before the low priority
> thread has started to wait for the condition (even ).
>
>> ...
>> Note the while loop, instead of a simple if, it is necessary to handle
>> correctly spurious wakeups.
> My problem is the opposite, I don't get the wakeups :-(
>
> The following program is more like my original problem (which was tricky to
> isolate):
>
> #include <native/cond.h>
> #include <native/mutex.h>
> #include <native/task.h>
> #include <native/timer.h>
> #include <rtdk.h>
> #include <sys/mman.h>
>
> RT_TASK main_task, producer_task, consumer_task;
> RT_MUTEX mutex;
> RT_COND cond;
> int waiting, signalled;
>
> static void producer(void *arg)
> {
> while(1) {
> rt_task_set_mode(0, T_PRIMARY, 0);
>
> rt_printf("Producer sleep...\n");
> rt_task_sleep(1000000000L);
> rt_printf("...producer slept\n");
>
> rt_mutex_acquire(&mutex, TM_INFINITE);
> rt_printf("Producer has entered waiting=%d, signalled=%d\n",
> waiting, signalled);
> if (waiting && !signalled) {
> rt_cond_broadcast(&cond);
> signalled = 1;
> rt_printf(" sent signal\n");
> }
> rt_mutex_release(&mutex);
> }
> }
>
>
> static void consumer(void *arg)
> {
> while(1) {
> int err;
>
> rt_task_set_mode(T_PRIMARY, 0, 0);
> rt_mutex_acquire(&mutex, TM_INFINITE);
> rt_task_sleep(1000000000L);
> waiting = 1;
> signalled = 0;
> rt_printf("Consumer about to wait waiting=%d, signalled=%d\n",
> waiting, signalled);
> err = rt_cond_wait(&cond, &mutex, 2000000000L);
> if (err != 0 && signalled) {
> rt_printf("Consumer not awoken err=%d, signalled=%d\n",
> err, signalled);
> } else {
> rt_printf("Consumer awoken\n");
> }
> rt_mutex_release(&mutex);
> }
> }
>
>
> int main(int argc, char *argv[])
> {
> mlockall(MCL_CURRENT|MCL_FUTURE);
> rt_print_auto_init(1);
> rt_task_shadow(&main_task, NULL, 1, T_FPU);
> rt_mutex_create(&mutex, NULL);
> rt_cond_create (&cond, NULL);
> rt_task_create(&producer_task, NULL, 0, 50, 0);
> rt_task_start(&producer_task, &producer, NULL);
> rt_task_create(&consumer_task, NULL, 0, 20, 0);
> rt_task_start(&consumer_task, &consumer, &consumer_task);
> while (1) {
> rt_task_sleep(1000000000L);
> }
> return 0;
> }
>
> And here I get the output:
>
> Producer sleep...
> ...producer slept
> Consumer about to wait waiting=1, signalled=0
> Producer has entered waiting=1, signalled=0
> sent signal
> Producer sleep...
> ...producer slept
> Producer has entered waiting=1, signalled=1
> Producer sleep...
> Consumer not awoken err=-110, signalled=1
> ...producer slept
> Producer has entered waiting=1, signalled=1
> Producer sleep...
> ...producer slept
> Consumer about to wait waiting=1, signalled=0
> Producer has entered waiting=1, signalled=0
> sent signal
> Producer sleep...
> ...producer slept
> Producer has entered waiting=1, signalled=1
> Producer sleep...
> Consumer not awoken err=-110, signalled=1
> ...producer slept
> Producer has entered waiting=1, signalled=1
> Producer sleep...
>
> What am I missing?
OK, found the bug (not mine!). I suggest something like this:
--- ksrc/skins/native/cond.c.orig 2008-03-11 20:42:52.000000000 +0100
+++ ksrc/skins/native/cond.c 2008-03-11 21:00:10.000000000 +0100
@@ -438,13 +438,20 @@
int rt_cond_wait(RT_COND *cond, RT_MUTEX *mutex, RTIME timeout)
{
- int err, kicked = 0;
+ /* We can't use rt_mutex_release since that might reschedule
+ before we do our xnsynch_sleep_on, hence most of of the code
+ is duplicated here */
+ int err = 0, kicked = 0;
xnthread_t *thread;
spl_t s;
+ int lockcnt;
if (timeout == TM_NONBLOCK)
return -EWOULDBLOCK;
+ if (xnpod_unblockable_p())
+ return -EPERM;
+
xnlock_get_irqsave(&nklock, s);
cond = xeno_h2obj_validate(cond, XENO_COND_MAGIC, RT_COND);
@@ -454,10 +461,26 @@
goto unlock_and_exit;
}
- err = rt_mutex_release(mutex);
+ mutex = xeno_h2obj_validate(mutex, XENO_MUTEX_MAGIC, RT_MUTEX);
- if (err)
+ if (!mutex) {
+ err = xeno_handle_error(mutex, XENO_MUTEX_MAGIC, RT_MUTEX);
+ goto unlock_and_exit;
+ }
+
+ if (xnpod_current_thread() != xnsynch_owner(&mutex->synch_base)) {
+ err = -EPERM;
goto unlock_and_exit;
+ }
+
+ lockcnt = mutex->lockcnt; /* Leave even if mutex is nested */
+
+ mutex->lockcnt = 0;
+
+ if (xnsynch_wakeup_one_sleeper(&mutex->synch_base)) {
+ mutex->lockcnt = 1;
+ /* Scheduling deferred */
+ }
thread = xnpod_current_thread();
@@ -474,6 +497,8 @@
rt_mutex_acquire(mutex, TM_INFINITE);
+ mutex->lockcnt = lockcnt; /* Adjust lockcnt */
+
if (kicked)
xnthread_set_info(thread, XNKICKED);
--
Anders Blomdell Email: anders.blomdell@domain.hid
Department of Automatic Control
Lund University Phone: +46 46 222 4625
P.O. Box 118 Fax: +46 46 138118
SE-221 00 Lund, Sweden
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Xenomai-help] What have I misunderstood about condition variables
2008-03-11 19:27 ` Anders Blomdell
2008-03-11 20:13 ` [Xenomai-core] " Anders Blomdell
@ 2008-03-11 23:00 ` Gilles Chanteperdrix
2008-03-12 12:00 ` Anders Blomdell
1 sibling, 1 reply; 8+ messages in thread
From: Gilles Chanteperdrix @ 2008-03-11 23:00 UTC (permalink / raw)
To: Anders Blomdell; +Cc: xenomai-help
Anders Blomdell wrote:
> Gilles Chanteperdrix wrote:
> > On Tue, Mar 11, 2008 at 7:19 PM, Anders Blomdell
> >> To me the symptoms indicate that the high priority producer gets the mutex and
> >> signals it before the consumer has properly started to wait on the condition.
> >
> > I have not read your program in detail, but what may be your problem
> > is that condition variables are not semaphores: if you signal a
> > condition variable when nobody is waiting the signal is lost.
> I know this, but the problem is that the program loses signals when it is
> waiting. In the consumer:
Sorry for the noise (and thanks for the patch).
--
Gilles Chanteperdrix.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Xenomai-help] What have I misunderstood about condition variables
2008-03-11 23:00 ` Gilles Chanteperdrix
@ 2008-03-12 12:00 ` Anders Blomdell
2008-03-12 13:11 ` Gilles Chanteperdrix
0 siblings, 1 reply; 8+ messages in thread
From: Anders Blomdell @ 2008-03-12 12:00 UTC (permalink / raw)
To: Gilles Chanteperdrix; +Cc: xenomai-help
Gilles Chanteperdrix wrote:
> Anders Blomdell wrote:
> > Gilles Chanteperdrix wrote:
> > > On Tue, Mar 11, 2008 at 7:19 PM, Anders Blomdell
> > >> To me the symptoms indicate that the high priority producer gets the mutex and
> > >> signals it before the consumer has properly started to wait on the condition.
> > >
> > > I have not read your program in detail, but what may be your problem
> > > is that condition variables are not semaphores: if you signal a
> > > condition variable when nobody is waiting the signal is lost.
> > I know this, but the problem is that the program loses signals when it is
> > waiting. In the consumer:
>
> Sorry for the noise (and thanks for the patch).
You are welcome.
Small afterthought/question. In the following code:
xnlock_get_irqsave(&nklock, s);
...
mutex->lockcnt = 0;
if (xnsynch_wakeup_one_sleeper(&mutex->synch_base)) {
mutex->lockcnt = 1;
/* Scheduling deferred */
}
thread = xnpod_current_thread();
xnsynch_sleep_on(&cond->synch_base, timeout, XN_RELATIVE);
Am I correct in assuming that no other task (even on a multiprocessor) can claim
the mutex until xnsynch_sleep_on has done its rescheduling?
/Anders
--
Anders Blomdell Email: anders.blomdell@domain.hid
Department of Automatic Control
Lund University Phone: +46 46 222 4625
P.O. Box 118 Fax: +46 46 138118
SE-221 00 Lund, Sweden
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Xenomai-help] What have I misunderstood about condition variables
2008-03-12 12:00 ` Anders Blomdell
@ 2008-03-12 13:11 ` Gilles Chanteperdrix
0 siblings, 0 replies; 8+ messages in thread
From: Gilles Chanteperdrix @ 2008-03-12 13:11 UTC (permalink / raw)
To: Anders Blomdell; +Cc: xenomai-help
On Wed, Mar 12, 2008 at 1:00 PM, Anders Blomdell
<anders.blomdell@domain.hid> wrote:
>
> Gilles Chanteperdrix wrote:
> > Anders Blomdell wrote:
> > > Gilles Chanteperdrix wrote:
> > > > On Tue, Mar 11, 2008 at 7:19 PM, Anders Blomdell
> > > >> To me the symptoms indicate that the high priority producer gets the mutex and
> > > >> signals it before the consumer has properly started to wait on the condition.
> > > >
> > > > I have not read your program in detail, but what may be your problem
> > > > is that condition variables are not semaphores: if you signal a
> > > > condition variable when nobody is waiting the signal is lost.
> > > I know this, but the problem is that the program loses signals when it is
> > > waiting. In the consumer:
> >
> > Sorry for the noise (and thanks for the patch).
> You are welcome.
>
> Small afterthought/question. In the following code:
>
>
> xnlock_get_irqsave(&nklock, s);
>
> ...
>
>
> mutex->lockcnt = 0;
>
> if (xnsynch_wakeup_one_sleeper(&mutex->synch_base)) {
> mutex->lockcnt = 1;
> /* Scheduling deferred */
> }
>
> thread = xnpod_current_thread();
>
> xnsynch_sleep_on(&cond->synch_base, timeout, XN_RELATIVE);
>
>
> Am I correct in assuming that no other task (even on a multiprocessor) can claim
> the mutex until xnsynch_sleep_on has done its rescheduling?
Yes, the nklock is a spin lock, so when you hold it (with interrupts
disabled), no one else ca have it.
--
Gilles Chanteperdrix
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Xenomai-core] [Xenomai-help] What have I misunderstood about condition variables
2008-03-11 20:13 ` [Xenomai-core] " Anders Blomdell
@ 2008-03-12 14:14 ` Philippe Gerum
0 siblings, 0 replies; 8+ messages in thread
From: Philippe Gerum @ 2008-03-12 14:14 UTC (permalink / raw)
To: Anders Blomdell; +Cc: xenomai-help, xenomai-core
Anders Blomdell wrote:
> OK, found the bug (not mine!).
No, it's mine. Actually, you fixed two of them, since nested locks would not be
released properly when entering cond_wait. Will merge, thanks.
I suggest something like this:
>
> --- ksrc/skins/native/cond.c.orig 2008-03-11 20:42:52.000000000 +0100
> +++ ksrc/skins/native/cond.c 2008-03-11 21:00:10.000000000 +0100
> @@ -438,13 +438,20 @@
>
> int rt_cond_wait(RT_COND *cond, RT_MUTEX *mutex, RTIME timeout)
> {
> - int err, kicked = 0;
> + /* We can't use rt_mutex_release since that might reschedule
> + before we do our xnsynch_sleep_on, hence most of of the code
> + is duplicated here */
> + int err = 0, kicked = 0;
> xnthread_t *thread;
> spl_t s;
> + int lockcnt;
>
> if (timeout == TM_NONBLOCK)
> return -EWOULDBLOCK;
>
> + if (xnpod_unblockable_p())
> + return -EPERM;
> +
> xnlock_get_irqsave(&nklock, s);
>
> cond = xeno_h2obj_validate(cond, XENO_COND_MAGIC, RT_COND);
> @@ -454,10 +461,26 @@
> goto unlock_and_exit;
> }
>
> - err = rt_mutex_release(mutex);
> + mutex = xeno_h2obj_validate(mutex, XENO_MUTEX_MAGIC, RT_MUTEX);
>
> - if (err)
> + if (!mutex) {
> + err = xeno_handle_error(mutex, XENO_MUTEX_MAGIC, RT_MUTEX);
> + goto unlock_and_exit;
> + }
> +
> + if (xnpod_current_thread() != xnsynch_owner(&mutex->synch_base)) {
> + err = -EPERM;
> goto unlock_and_exit;
> + }
> +
> + lockcnt = mutex->lockcnt; /* Leave even if mutex is nested */
> +
> + mutex->lockcnt = 0;
> +
> + if (xnsynch_wakeup_one_sleeper(&mutex->synch_base)) {
> + mutex->lockcnt = 1;
> + /* Scheduling deferred */
> + }
>
> thread = xnpod_current_thread();
>
> @@ -474,6 +497,8 @@
>
> rt_mutex_acquire(mutex, TM_INFINITE);
>
> + mutex->lockcnt = lockcnt; /* Adjust lockcnt */
> +
> if (kicked)
> xnthread_set_info(thread, XNKICKED);
>
>
>
>
--
Philippe.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2008-03-12 14:14 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-03-11 18:19 [Xenomai-help] What have I misunderstood about condition variables Anders Blomdell
2008-03-11 18:27 ` Gilles Chanteperdrix
2008-03-11 19:27 ` Anders Blomdell
2008-03-11 20:13 ` [Xenomai-core] " Anders Blomdell
2008-03-12 14:14 ` Philippe Gerum
2008-03-11 23:00 ` Gilles Chanteperdrix
2008-03-12 12:00 ` Anders Blomdell
2008-03-12 13:11 ` Gilles Chanteperdrix
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.