From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/10347 Path: news.gmane.org!.POSTED!not-for-mail From: Ward Willats Newsgroups: gmane.linux.lib.musl.general Subject: std::condition_variable::wait_for() breakage when system_clock changes C++11 MIPS Date: Tue, 2 Aug 2016 16:33:29 -0700 Message-ID: <3008FD15-1C92-4870-9CD9-BC8B694ACCD0@wardco.com> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 (Mac OS X Mail 9.3 \(3124\)) Content-Type: multipart/alternative; boundary="Apple-Mail=_3D0D96E7-0221-4672-BDFD-1E1433990247" X-Trace: blaine.gmane.org 1470180832 19727 195.159.176.226 (2 Aug 2016 23:33:52 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Tue, 2 Aug 2016 23:33:52 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-10360-gllmg-musl=m.gmane.org@lists.openwall.com Wed Aug 03 01:33:48 2016 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1bUjBz-0004iL-3a for gllmg-musl@m.gmane.org; Wed, 03 Aug 2016 01:33:47 +0200 Original-Received: (qmail 11844 invoked by uid 550); 2 Aug 2016 23:33:45 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 11806 invoked from network); 2 Aug 2016 23:33:43 -0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=wardco.com; s=wardco01; h=Mime-Version:Message-Id:To:Subject:Date:Content-Type:From: Sender:Reply-To:Cc:Content-Transfer-Encoding:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=XzZMBEbSjsLYuXa86UxYjuz6G5Fa2fyXdhuIUnkrEm0=; b=mNnYfEgX1uxGG9k5n4XQTh0IfP hxbTzb9G/CwNP5gitk7UQnlRkc52ym2hRraPclWp/oVkGj8nZ5aYXFOHkZa+0oUCZfiwVIUGCKI1+ b7z2cTDFgNnR+QSg+KODNSNS8d2Le5Xo6Fv4YxyZQjc0khu6/urjsparxk8E136iORz8=; X-Mailer: Apple Mail (2.3124) X-SA-Exim-Connect-IP: 70.36.190.2 X-SA-Exim-Mail-From: musl@wardco.com X-SA-Exim-Scanned: No (on mail.wardco.com); SAEximRunCond expanded to false Xref: news.gmane.org gmane.linux.lib.musl.general:10347 Archived-At: --Apple-Mail=_3D0D96E7-0221-4672-BDFD-1E1433990247 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii 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 = 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 --Apple-Mail=_3D0D96E7-0221-4672-BDFD-1E1433990247 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=us-ascii 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 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





= --Apple-Mail=_3D0D96E7-0221-4672-BDFD-1E1433990247--