[boost] Condition Variables, POSIX signals and system time changes

168 views
Skip to first unread message

Johan Borkhuis

unread,
Jan 10, 2012, 2:35:54 AM1/10/12
to bo...@lists.boost.org
I came across the following issue with condition variables. I don't know
if this is an issue with my application or with Boost condition variables.

First my setup. I am using Linux on an ARM system, running Boost 1.47. My
application needs accurate timing, and for this I use a POSIX timer using
SIGRTMIN. This part is not something that I can control, it is an external
library that implements this. I use condition variables are a timing
mechanism with in my software.

When I use condition variables without the POSIX timer there is no
problem. The timing continues correctly, even if I change the time forward
or backward.

When I start the POSIX timer the condition variable does not time-out when
I change the time backward. It only times out when the original time (plus
timeout) is reached.

The code I use to create the condition variable:

boost::mutex m;
boost::condition_variable cond;
boost::unique_lock<boost::mutex> lk(m);
cond.timed_wait(lk, duration);

I tested this also by extracting the code from Boost and implementing this
inline. This gave the same results. When I changed the clock of the
pthread condition variable to monotonic (call to
pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC)) the result was OK
again.

Is this an issue with my implementation, can I change some setting or is
this a (known) issue with the Boost condition variables?

If people are interested, I do have a small test application that I used
to test this issue that I can post here. I don't know however what the
policy is on this list wrt posting of attachments.

Kind regards,
Johan Borkhuis


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Vicente J. Botet Escriba

unread,
Jan 10, 2012, 4:38:07 PM1/10/12
to bo...@lists.boost.org
Le 10/01/12 08:35, Johan Borkhuis a écrit :

> I came across the following issue with condition variables. I don't know
> if this is an issue with my application or with Boost condition variables.
>
> First my setup. I am using Linux on an ARM system, running Boost 1.47. My
> application needs accurate timing, and for this I use a POSIX timer using
> SIGRTMIN. This part is not something that I can control, it is an external
> library that implements this. I use condition variables are a timing
> mechanism with in my software.
Do you mean that you are not using Boost.thread here?

> When I use condition variables without the POSIX timer there is no
> problem. The timing continues correctly, even if I change the time forward
> or backward.
>
> When I start the POSIX timer the condition variable does not time-out when
> I change the time backward. It only times out when the original time (plus
> timeout) is reached.
>
> The code I use to create the condition variable:
>
> boost::mutex m;
> boost::condition_variable cond;
> boost::unique_lock<boost::mutex> lk(m);
> cond.timed_wait(lk, duration);
>
> I tested this also by extracting the code from Boost and implementing this
> inline. This gave the same results. When I changed the clock of the
> pthread condition variable to monotonic (call to
> pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC)) the result was OK
> again.
What do you changed exactly? Could you post a patch?

> Is this an issue with my implementation, can I change some setting or is
> this a (known) issue with the Boost condition variables?
>
> If people are interested, I do have a small test application that I used
> to test this issue that I can post here. I don't know however what the
> policy is on this list wrt posting of attachments.
>
>

Please, could you post the test that fails and the one that succeeds, it
will help me a lot.

If you want you can open a Trac ticket and attach the examples and the
path there.

Best,
Vicente

Anthony Williams

unread,
Jan 11, 2012, 2:41:58 AM1/11/12
to bo...@lists.boost.org

I'm not aware of this specific issue, but I am aware that there are
issues around clocks and timeouts with condition variables. The boost
condition variables are wrappers around pthread_cond_t on POSIX systems
such as linux. A pthread_cond_t can only use one clock for timeouts.
Boost uses the system "real time" clock, but as you have seen you can
also use the monotonic clock on systems that support it.

There are issues both ways with how to handle timeouts based on a clock
other than the one being used --- e.g. timed_wait with an absolute time
from the system clock will have issues when used on a condition variable
that uses the monotonic clock if the clock is adjusted, as the condvar
will wait for the original duration, rather than waking earlier or later
as appropriate.

It appears that on your system, if you create a timer then it affects
the way that condition variable waits are timed out when the clock is
adjusted.

Anthony
--
Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/
just::thread C++11 thread library http://www.stdthread.co.uk
Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

Johan Borkhuis

unread,
Jan 11, 2012, 5:14:25 PM1/11/12
to bo...@lists.boost.org
Vicente,

Thank you for your quick reply.
I did not get the message from the mailing list, so I copied your
questions into this mail.

As requested I opened a ticket (ticket# 6377) and I attached the demo
application to it, with a small description.

> Do you mean that you are not using Boost.thread here?

No, the application is running in one thread. The condition variables
are used as an alternative sleep method. We discovered that other
sleep-methods are even more vulnerable to time changes, and also have
different responses to Posix signals. The condition variables continue
to work correctly, even with Posix signals, however in combination with
time changes there are some issues.
In our real application we are using boost threads quite heavily though.

> What do you changed exactly? Could you post a patch?

I attached the demo application to the issue. It includes the regular
Boost condition variable use and the changed implementation. It also
includes the Posix timer code to generate the signals.
I did not change the Boost code (yet), as I am not that familiar with it.

> Please, could you post the test that fails and the one that succeeds, it
> will help me a lot.


The demo application shows where things go right and wrong, so hopefully
you should be able to reproduce the issue.

Again, thank you for your quick response.

Regards,
Johan Borkhuis

Johan Borkhuis

unread,
Jan 12, 2012, 2:20:23 AM1/12/12
to Vicente J. Botet Escriba, bo...@lists.boost.org
Vicente,

> I'm reworking the timed wait interface using Boost.Chrono. In this case
> you could use a steady clock to mean a MONOTONIC clock. Unfortunately my
> refactoring did use pthread_condattr_setclock to force a monotonic clock
> while waiting on the condition. Even if this should not be the source of
> the problem as it works when you don't generate the signals, I think
> that this will be better when available. I will need some time to make
> this working but I hope I could release it for boost 1.50 :(

Looking forward to that. For the moment we have a workaround, but I will
keep an eye on changes in this area, so we can move back when this becomes
available.

>> The demo application shows where things go right and wrong, so hopefully
>> you should be able to reproduce the issue.
>

> I have not understood the example completely. How do you change the time
> forward or backward? Could you point me where or how do you do? by hand?

Sorry, should have mentioned that. I change the time externally by hand,
using the date command. When I change the time backwards (so an earlier
time) the problem occurs. When I change the time forward again to a time
equal to or before the time I changed the time the application continues.

>>
>> Again, thank you for your quick response.
>>
>>

> Thanks for reporting this and for the application example.
> Vicente

Thank you for your work on this.

Kind regards,

Reply all
Reply to author
Forward
0 new messages