mailing list of musl libc
 help / color / mirror / code / Atom feed
* std::condition_variable::wait_for() breakage when system_clock changes C++11 MIPS
@ 2016-08-02 23:33 Ward Willats
  2016-08-02 23:40 ` Patrick Oppenlander
  2016-08-03 11:27 ` Szabolcs Nagy
  0 siblings, 2 replies; 5+ messages in thread
From: Ward Willats @ 2016-08-02 23:33 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 2186 bytes --]

Hello.

This may be a little too C++ for this list, but I wasn't sure where to turn. Also, I thought I should at least document it for the Google, and see if you folks think I should take this problem elsewhere, or, perhaps more likely, if I have made some stupid error (!)

We are running a C++ 11 app on a MIPS-based Linux/OpenWRT platform and linking against MUSCL 1.1.12 and libstdc++ v3. On cold boot, our system clock is often some random time in the future until ntpd or other software corrects it. This led to odd behavior and this experiment:

If I use the busybox "date --set" to move our system's clock 24 hours into the future, and then call:

std::condition_variable::wait_for() with the pre-canned std::chrono::duration, std::chrono::milliseconds( 120000 ), as a 2 minute wait timeout AND then...

...set the clock BACK 24 hours to the correct/current time with ntpd, wait_for() doesn't return after 2 minutes (assuming no notify() of course). (Presumably, wait_for() is using system_clock, and not steady_clock, and will fire in 24 hours + 2 minutes -- but I haven't waited to find out.)

However, if I repeat this experiment and call std::condition_variable::wait_until() with a timeout time_point calculated as std::chrono::steady_clock::now() + std::chrono::milliseconds( 120000 ), which neatly binds a steady_clock ref into the time_point, it does indeed fire in 2 minutes after the clock is set back, as expected.

In short, the std::condition_variable API that takes a std::chrono:duration does not work, but the one that takes a std::chrono::time_point does.

This is strange to me since sites like cppreference.com <http://cppreference.com/> indicate that both methods use a steady_clock to calculate duration AND imply that wait_for() may even implemented internally in terms of wait_until(). However, in this implementation, both of these assertions seem incorrect. Anyway, it seems like a bug.

Personally, I am fine, as I can implement a wrapper that does our wait_for() in terms of wait_until(), but it took a few days of chasing through our code to pin this down, so figured I share and maybe save someone some pain.

-- Ward






[-- Attachment #2: Type: text/html, Size: 3067 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: std::condition_variable::wait_for() breakage when system_clock changes C++11 MIPS
  2016-08-02 23:33 std::condition_variable::wait_for() breakage when system_clock changes C++11 MIPS Ward Willats
@ 2016-08-02 23:40 ` Patrick Oppenlander
  2016-08-03 11:27 ` Szabolcs Nagy
  1 sibling, 0 replies; 5+ messages in thread
From: Patrick Oppenlander @ 2016-08-02 23:40 UTC (permalink / raw)
  To: musl

On 03/08/16 09:33, Ward Willats wrote:
> Hello.
>
> This may be a little too C++ for this list

Hi Ward,

if you're using libstdc++ (commonly if you're using GCC this will be the 
case) I would suggest asking on the libstdc++ mailing list 
(libstdc++@gcc.gnu.org).

		Patrick



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: std::condition_variable::wait_for() breakage when system_clock changes C++11 MIPS
  2016-08-02 23:33 std::condition_variable::wait_for() breakage when system_clock changes C++11 MIPS Ward Willats
  2016-08-02 23:40 ` Patrick Oppenlander
@ 2016-08-03 11:27 ` Szabolcs Nagy
  2016-08-03 17:29   ` Ward Willats
  1 sibling, 1 reply; 5+ messages in thread
From: Szabolcs Nagy @ 2016-08-03 11:27 UTC (permalink / raw)
  To: musl

* Ward Willats <musl@wardco.com> [2016-08-02 16:33:29 -0700]:
> 
> We are running a C++ 11 app on a MIPS-based Linux/OpenWRT platform and linking against MUSCL 1.1.12 and libstdc++ v3. On cold boot, our system clock is often some random time in the future until ntpd or other software corrects it. This led to odd behavior and this experiment:
> 
> If I use the busybox "date --set" to move our system's clock 24 hours into the future, and then call:
> 
> std::condition_variable::wait_for() with the pre-canned std::chrono::duration, std::chrono::milliseconds( 120000 ), as a 2 minute wait timeout AND then...
> 
> ...set the clock BACK 24 hours to the correct/current time with ntpd, wait_for() doesn't return after 2 minutes (assuming no notify() of course). (Presumably, wait_for() is using system_clock, and not steady_clock, and will fire in 24 hours + 2 minutes -- but I haven't waited to find out.)
> 
> However, if I repeat this experiment and call std::condition_variable::wait_until() with a timeout time_point calculated as std::chrono::steady_clock::now() + std::chrono::milliseconds( 120000 ), which neatly binds a steady_clock ref into the time_point, it does indeed fire in 2 minutes after the clock is set back, as expected.
> 
> In short, the std::condition_variable API that takes a std::chrono:duration does not work, but the one that takes a std::chrono::time_point does.
> 

this is a libstdc++ issue so the gcc version matters.
(i can see condvar related issues fixed in gcc bugzilla)

there are several issues with the c++11 condvar timeout api e.g.
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#887
so i'd avoid using c++, it's just a broken abstraction layer
on top of the pthreads api with poor specification.. meanwhile
pthreads works fine and is portable.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: std::condition_variable::wait_for() breakage when system_clock changes C++11 MIPS
  2016-08-03 11:27 ` Szabolcs Nagy
@ 2016-08-03 17:29   ` Ward Willats
  2016-08-04  3:47     ` Rich Felker
  0 siblings, 1 reply; 5+ messages in thread
From: Ward Willats @ 2016-08-03 17:29 UTC (permalink / raw)
  To: musl


> On Aug 3, 2016, at 4:27 AM, Szabolcs Nagy <nsz@port70.net> wrote:
> 
> * Ward Willats <musl@wardco.com> [2016-08-02 16:33:29 -0700]:
>> 
>> In short, the std::condition_variable API that takes a std::chrono:duration does not work, but the one that takes a std::chrono::time_point does.
>> 
> 
> this is a libstdc++ issue so the gcc version matters.
> (i can see condvar related issues fixed in gcc bugzilla)
> 
> there are several issues with the c++11 condvar timeout api e.g.
> http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#887
> so i'd avoid using c++, it's just a broken abstraction layer
> on top of the pthreads api with poor specification.. meanwhile
> pthreads works fine and is portable.
> 

Thanks. Don't need the portability, but <thread> is arguably MORE portable -- depending on the platforms of interest. Anyway the pthread_t is available if we want to get down and dirty -- and we do sometimes (e.g. thread cancelling, naming). The link just demonstrates that poor-old pthreads can't model the rich abstraction of C++ without work arounds! :) 

Anyway to each their own. I'll copy this problem over to libstdc++ library as Patrick suggested w/appropriate versioning. Thanks for the use of the hall.

Best,

-- Ward





^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: std::condition_variable::wait_for() breakage when system_clock changes C++11 MIPS
  2016-08-03 17:29   ` Ward Willats
@ 2016-08-04  3:47     ` Rich Felker
  0 siblings, 0 replies; 5+ messages in thread
From: Rich Felker @ 2016-08-04  3:47 UTC (permalink / raw)
  To: musl

On Wed, Aug 03, 2016 at 10:29:45AM -0700, Ward Willats wrote:
> 
> > On Aug 3, 2016, at 4:27 AM, Szabolcs Nagy <nsz@port70.net> wrote:
> > 
> > * Ward Willats <musl@wardco.com> [2016-08-02 16:33:29 -0700]:
> >> 
> >> In short, the std::condition_variable API that takes a
> >> std::chrono:duration does not work, but the one that takes a
> >> std::chrono::time_point does.
> >> 
> > 
> > this is a libstdc++ issue so the gcc version matters.
> > (i can see condvar related issues fixed in gcc bugzilla)
> > 
> > there are several issues with the c++11 condvar timeout api e.g.
> > http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#887
> > so i'd avoid using c++, it's just a broken abstraction layer
> > on top of the pthreads api with poor specification.. meanwhile
> > pthreads works fine and is portable.
> > 
> 
> Thanks. Don't need the portability, but <thread> is arguably MORE
> portable -- depending on the platforms of interest. Anyway the
> pthread_t is available if we want to get down and dirty -- and we do
> sometimes (e.g. thread cancelling, naming). The link just
> demonstrates that poor-old pthreads can't model the rich abstraction
> of C++ without work arounds! :)

pthread cond variables can wait on CLOCK_REALTIME or CLOCK_MONOTONIC,
addressing this issue, always with "until" instead of "for" semantics
(but for monotonic, "for" and "until" are functionally equivalent).
However musl may not correctly handle the case where the realtime
clock changes during the wait. I'll look into this.

Rich


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-08-04  3:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-02 23:33 std::condition_variable::wait_for() breakage when system_clock changes C++11 MIPS Ward Willats
2016-08-02 23:40 ` Patrick Oppenlander
2016-08-03 11:27 ` Szabolcs Nagy
2016-08-03 17:29   ` Ward Willats
2016-08-04  3:47     ` Rich Felker

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).