Condition Variables, POSIX signals and system time changes

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

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

On 10/01/12 07:35, Johan Borkhuis wrote:
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?
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
participants (3)
-
Anthony Williams
-
Johan Borkhuis
-
Vicente J. Botet Escriba