From patchwork Sun Jan 7 20:55:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Crowe X-Patchwork-Id: 856613 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-470340-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="YQqh+fd8"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zF9fv0SN0z9ryT for ; Mon, 8 Jan 2018 07:56:06 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; q=dns; s= default; b=oZcVMf/Rte/Mvlcm4F+Rh1JH8w0W62eJK3RVga9ppfiQN7SPlT//g ObAWyuzYGLXlfvNq1YKiIWV65Y63kZf/ZevM4k9HztO14aiBusS1nDoF8/dW19M2 he2xw6phy7WLWmiqAvB3yp8FWlndabUq7J9nDNKIlm6WNelTUaNtU8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; s= default; bh=O7TQlHX8+rjmCPC9pqdLxCdVmHg=; b=YQqh+fd8JTKOrPw4R17W AQARsZtBxzJUdphNi3MeI6sgEKHGDTac+egL2OH+Bts9Y4pB5TmrmwOOjM99aNdG BGKRqzHTnjXF22L7hk1UKgkydgbhN4v9Oh/OMAMZ7+Bzy/V1E9hQ0QkQkrQ/057Y opNeX8qVzVzjVSyzADHB4qI= Received: (qmail 15163 invoked by alias); 7 Jan 2018 20:55:51 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 15145 invoked by uid 89); 7 Jan 2018 20:55:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-27.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=5253, Hx-languages-length:2408 X-Spam-User: qpsmtpd, 2 recipients X-HELO: relay.appriver.com Received: from relay101a.appriver.com (HELO relay.appriver.com) (207.97.230.14) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 07 Jan 2018 20:55:49 +0000 X-Note: This Email was scanned by AppRiver SecureTide X-Note-AR-ScanTimeLocal: 01/07/2018 3:53:48 PM X-Note: SecureTide Build: 12/19/2017 1:37:44 PM UTC (2.6.27.2) X-Note: Filtered by 10.238.11.161 X-Note-AR-Scan: None - PIPE Received: by relay.appriver.com (CommuniGate Pro PIPE 6.1.7) with PIPE id 273613007; Sun, 07 Jan 2018 15:53:48 -0500 Received: from [213.210.30.29] (HELO elite.brightsign) by relay.appriver.com (CommuniGate Pro SMTP 6.1.7) with ESMTPS id 273613003; Sun, 07 Jan 2018 15:53:48 -0500 Received: from chuckie.brightsign ([fd44:d8b8:cab5:cb01::19] helo=chuckie) by elite.brightsign with esmtp (Exim 4.89) (envelope-from ) id 1eYHyr-0008us-K0; Sun, 07 Jan 2018 20:55:45 +0000 Received: from mac by chuckie with local (Exim 4.89) (envelope-from ) id 1eYHyr-0003RB-Jc; Sun, 07 Jan 2018 20:55:45 +0000 From: Mike Crowe To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Cc: Mike Crowe Subject: [PATCH 1/5] Improve libstdc++-v3 async test Date: Sun, 7 Jan 2018 20:55:28 +0000 Message-Id: <20180107205532.13138-2-mac@mcrowe.com> In-Reply-To: <20180107205532.13138-1-mac@mcrowe.com> References: <20180107205532.13138-1-mac@mcrowe.com> X-Note: This Email was scanned by AppRiver SecureTide X-Note-AR-ScanTimeLocal: 01/07/2018 3:53:48 PM X-Note: SecureTide Build: 12/19/2017 1:37:44 PM UTC (2.6.27.2) X-Note: Filtered by 10.238.11.161 X-Policy: brightsign.biz X-Primary: brightsign.biz@brightsign.biz X-Virus-Scan: V- X-Note: ICH-CT/SI:0-0/SG:1 1/1/0001 12:00:00 AM X-Note-SnifferID: 0 X-Note: TCH-CT/SI:0-43/SG:1 1/7/2018 3:53:04 PM X-GBUdb-Analysis: 0, 213.210.30.29, Ugly c=0.476605 p=-0.960784 Source Normal X-Signature-Violations: 0-0-0-5663-c X-Note: Spam Tests Failed: X-Country-Path: ->->United Kingdom->United States X-Note-Sending-IP: 213.210.30.29 X-Note-Reverse-DNS: elite.brightsigndigital.co.uk X-Note-Return-Path: mcrowe@brightsign.biz X-Note: User Rule Hits: X-Note: Global Rule Hits: G293 G294 G295 G296 G300 G301 G433 X-Note: Encrypt Rule Hits: X-Note: Mail Class: VALID Add tests for waiting for the future using both std::chrono::steady_clock and std::chrono::system_clock in preparation for dealing with those clocks properly in futex.cc. --- libstdc++-v3/testsuite/30_threads/async/async.cc | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/libstdc++-v3/testsuite/30_threads/async/async.cc b/libstdc++-v3/testsuite/30_threads/async/async.cc index 8071cb133fc..7326c5f7cd6 100644 --- a/libstdc++-v3/testsuite/30_threads/async/async.cc +++ b/libstdc++-v3/testsuite/30_threads/async/async.cc @@ -52,17 +52,53 @@ void test02() VERIFY( status == std::future_status::timeout ); status = f1.wait_until(std::chrono::system_clock::now()); VERIFY( status == std::future_status::timeout ); + status = f1.wait_until(std::chrono::steady_clock::now()); + VERIFY( status == std::future_status::timeout ); l.unlock(); // allow async thread to proceed f1.wait(); // wait for it to finish status = f1.wait_for(std::chrono::milliseconds(0)); VERIFY( status == std::future_status::ready ); status = f1.wait_until(std::chrono::system_clock::now()); VERIFY( status == std::future_status::ready ); + status = f1.wait_until(std::chrono::steady_clock::now()); + VERIFY( status == std::future_status::ready ); +} + +void work03() +{ + std::this_thread::sleep_for(std::chrono::seconds(15)); +} + +// This test is slow in order to try and avoid failing on a loaded +// machine. Nevertheless, it could still fail if the kernel decides +// not to schedule us for several seconds. It also assumes that no-one +// will change CLOCK_REALTIME whilst the test is running. +template +void test03() +{ + auto const start = CLOCK::now(); + future f1 = async(launch::async, &work03); + std::future_status status; + + status = f1.wait_for(std::chrono::seconds(5)); + VERIFY( status == std::future_status::timeout ); + + status = f1.wait_until(start + std::chrono::seconds(10)); + VERIFY( status == std::future_status::timeout ); + + status = f1.wait_until(start + std::chrono::seconds(25)); + VERIFY( status == std::future_status::ready ); + + auto const elapsed = CLOCK::now() - start; + VERIFY( elapsed >= std::chrono::seconds(15) ); + VERIFY( elapsed < std::chrono::seconds(20) ); } int main() { test01(); test02(); + test03(); + test03(); return 0; } From patchwork Sun Jan 7 20:55:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Crowe X-Patchwork-Id: 856618 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-470345-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="uw2VBsuA"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zF9hn4kkwz9ryT for ; Mon, 8 Jan 2018 07:57:45 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; q=dns; s= default; b=UgXNlAb1pN4/InVxcFOcGXdZAfwbHoccXDMNDfw2/k9lBeRPChq+X vDV39GHJ7v6lh5j7Fk7u7ImjUrJrY3EGRH+7Mc4KhruO/Z20hgZUc1Thl8q6AtOd JIchoPtU7Oi8257ZW8EeAbY/QK3BI/X6FzxtlhLJkVUaFN+Q5AhjBk= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; s= default; bh=x/gp1/bUT0eVFSbVasNVKB6BKoU=; b=uw2VBsuAuydIdubyI17/ AskYZuGtay7ID9vOTqmpEzWXl/00/V4l7CH9IgjWBk7aw2WqfmQekARNMUW7IxP5 9mojQ0HAxmBs8TYVONb3toqx1M2Q/xasCosZjri0PLug5AbWwQY38uTxIYmF1BrH 5OEKtUDPG7DwlabJ6apS8lg= Received: (qmail 16469 invoked by alias); 7 Jan 2018 20:55:58 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 16378 invoked by uid 89); 7 Jan 2018 20:55:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-27.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=expire, 1000000000, Hx-languages-length:2134 X-Spam-User: qpsmtpd, 2 recipients X-HELO: relay.appriver.com Received: from relay101a.appriver.com (HELO relay.appriver.com) (207.97.230.14) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 07 Jan 2018 20:55:55 +0000 X-Note: This Email was scanned by AppRiver SecureTide X-Note-AR-ScanTimeLocal: 01/07/2018 3:53:48 PM X-Note: SecureTide Build: 12/19/2017 1:37:44 PM UTC (2.6.27.2) X-Note: Filtered by 10.238.11.161 X-Note-AR-Scan: None - PIPE Received: by relay.appriver.com (CommuniGate Pro PIPE 6.1.7) with PIPE id 273613011; Sun, 07 Jan 2018 15:53:48 -0500 Received: from [213.210.30.29] (HELO elite.brightsign) by relay.appriver.com (CommuniGate Pro SMTP 6.1.7) with ESMTPS id 273612990; Sun, 07 Jan 2018 15:53:48 -0500 Received: from chuckie.brightsign ([fd44:d8b8:cab5:cb01::19] helo=chuckie) by elite.brightsign with esmtp (Exim 4.89) (envelope-from ) id 1eYHyr-0008ut-KO; Sun, 07 Jan 2018 20:55:45 +0000 Received: from mac by chuckie with local (Exim 4.89) (envelope-from ) id 1eYHyr-0003RE-K0; Sun, 07 Jan 2018 20:55:45 +0000 From: Mike Crowe To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Cc: Mike Crowe Subject: [PATCH 2/5] libstdc++ futex: Use FUTEX_CLOCK_REALTIME for wait Date: Sun, 7 Jan 2018 20:55:29 +0000 Message-Id: <20180107205532.13138-3-mac@mcrowe.com> In-Reply-To: <20180107205532.13138-1-mac@mcrowe.com> References: <20180107205532.13138-1-mac@mcrowe.com> X-Note: This Email was scanned by AppRiver SecureTide X-Note-AR-ScanTimeLocal: 01/07/2018 3:53:48 PM X-Note: SecureTide Build: 12/19/2017 1:37:44 PM UTC (2.6.27.2) X-Note: Filtered by 10.238.11.161 X-Policy: brightsign.biz X-Primary: brightsign.biz@brightsign.biz X-Virus-Scan: V- X-Note: ICH-CT/SI:0-0/SG:1 1/1/0001 12:00:00 AM X-Note-SnifferID: 0 X-Note: TCH-CT/SI:0-43/SG:1 1/7/2018 3:53:04 PM X-GBUdb-Analysis: 0, 213.210.30.29, Ugly c=0.476605 p=-0.960784 Source Normal X-Signature-Violations: 0-0-0-4764-c X-Note: Spam Tests Failed: X-Country-Path: ->->United Kingdom->United States X-Note-Sending-IP: 213.210.30.29 X-Note-Reverse-DNS: elite.brightsigndigital.co.uk X-Note-Return-Path: mcrowe@brightsign.biz X-Note: User Rule Hits: X-Note: Global Rule Hits: G293 G294 G295 G296 G300 G301 G433 X-Note: Encrypt Rule Hits: X-Note: Mail Class: VALID The futex system call supports waiting for an absolute time if FUTEX_WAIT_BITSET is used rather than FUTEX_WAIT. Doing so provides two benefits: 1. The call to gettimeofday is not required in order to calculate a relative timeout. 2. If someone changes the system clock during the wait then the futex timeout will correctly expire earlier or later. Currently that only happens if the clock is changed prior to the call to gettimeofday. According to futex(2), support for FUTEX_CLOCK_REALTIME was added in the v2.6.28 Linux kernel and FUTEX_WAIT_BITSET was added in v2.6.25. There is no attempt to detect the kernel version and fall back to the previous method. --- libstdc++-v3/src/c++11/futex.cc | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/libstdc++-v3/src/c++11/futex.cc b/libstdc++-v3/src/c++11/futex.cc index f5000aa77b3..40ec7f9b0f7 100644 --- a/libstdc++-v3/src/c++11/futex.cc +++ b/libstdc++-v3/src/c++11/futex.cc @@ -35,6 +35,9 @@ // Constants for the wait/wake futex syscall operations const unsigned futex_wait_op = 0; +const unsigned futex_wait_bitset_op = 9; +const unsigned futex_clock_realtime_flag = 256; +const unsigned futex_bitset_match_any = ~0; const unsigned futex_wake_op = 1; namespace std _GLIBCXX_VISIBILITY(default) @@ -58,22 +61,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } else { - struct timeval tv; - gettimeofday (&tv, NULL); - // Convert the absolute timeout value to a relative timeout struct timespec rt; - rt.tv_sec = __s.count() - tv.tv_sec; - rt.tv_nsec = __ns.count() - tv.tv_usec * 1000; - if (rt.tv_nsec < 0) - { - rt.tv_nsec += 1000000000; - --rt.tv_sec; - } - // Did we already time out? - if (rt.tv_sec < 0) - return false; - - if (syscall (SYS_futex, __addr, futex_wait_op, __val, &rt) == -1) + rt.tv_sec = __s.count(); + rt.tv_nsec = __ns.count(); + if (syscall (SYS_futex, __addr, futex_wait_bitset_op | futex_clock_realtime_flag, __val, &rt, nullptr, futex_bitset_match_any) == -1) { _GLIBCXX_DEBUG_ASSERT(errno == EINTR || errno == EAGAIN || errno == ETIMEDOUT); From patchwork Sun Jan 7 20:55:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Crowe X-Patchwork-Id: 856614 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-470341-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="LBRSebY5"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zF9gN4BD3z9ryT for ; Mon, 8 Jan 2018 07:56:31 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; q=dns; s= default; b=dUwxPRU3g5STq/e/1NnvX/jjxnzMgVATiZN8XDqalFqhO5vKTJ8ct 9dG1YsuRELgVE2daCrc+aXmayTIXIn36Z5RdPOpTGfAD2GFd4AnfYgH/9fU/XiaP VUgJBM4ueVlBe6baDIbwJVL4mEccKHbwx8Iiz+fkHvEBv3vBgqqQ6U= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; s= default; bh=h/s/kRsjvoBgGRLoLKEomnvIMc8=; b=LBRSebY5lbmrgceuY7Gs dHloa5PCNwj3zeQt0OSbg9WBFT4+1VSgbxTPspqDhyI047I4I1VSYUzUPnIREfWQ GowuVr1RsgG9tOKuv6Nep3cE/2VOWbSrus8P1fIz3+LevaVCrsxG4cgBkWhG11Nc WQ6fGAFywB2mlU6hHZTf5YM= Received: (qmail 15382 invoked by alias); 7 Jan 2018 20:55:52 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 15306 invoked by uid 89); 7 Jan 2018 20:55:52 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-27.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=risks, wake, steady, opportunity X-Spam-User: qpsmtpd, 2 recipients X-HELO: relay.appriver.com Received: from relay101b.appriver.com (HELO relay.appriver.com) (207.97.230.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 07 Jan 2018 20:55:50 +0000 X-Note: This Email was scanned by AppRiver SecureTide X-Note-AR-ScanTimeLocal: 01/07/2018 3:53:50 PM X-Note: SecureTide Build: 12/19/2017 1:37:44 PM UTC (2.6.27.2) X-Note: Filtered by 10.238.11.162 X-Note-AR-Scan: None - PIPE Received: by relay.appriver.com (CommuniGate Pro PIPE 6.1.7) with PIPE id 275441481; Sun, 07 Jan 2018 15:53:50 -0500 Received: from [213.210.30.29] (HELO elite.brightsign) by relay.appriver.com (CommuniGate Pro SMTP 6.1.7) with ESMTPS id 275441489; Sun, 07 Jan 2018 15:53:48 -0500 Received: from chuckie.brightsign ([fd44:d8b8:cab5:cb01::19] helo=chuckie) by elite.brightsign with esmtp (Exim 4.89) (envelope-from ) id 1eYHyr-0008uv-Ko; Sun, 07 Jan 2018 20:55:45 +0000 Received: from mac by chuckie with local (Exim 4.89) (envelope-from ) id 1eYHyr-0003RH-KO; Sun, 07 Jan 2018 20:55:45 +0000 From: Mike Crowe To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Cc: Mike Crowe Subject: [PATCH 3/5] libstdc++ futex: Support waiting on std::chrono::steady_clock directly Date: Sun, 7 Jan 2018 20:55:30 +0000 Message-Id: <20180107205532.13138-4-mac@mcrowe.com> In-Reply-To: <20180107205532.13138-1-mac@mcrowe.com> References: <20180107205532.13138-1-mac@mcrowe.com> X-Note: This Email was scanned by AppRiver SecureTide X-Note-AR-ScanTimeLocal: 01/07/2018 3:53:48 PM X-Note: SecureTide Build: 12/19/2017 1:37:44 PM UTC (2.6.27.2) X-Note: Filtered by 10.238.11.162 X-Policy: brightsign.biz X-Primary: brightsign.biz@brightsign.biz X-Virus-Scan: V- X-Note: ICH-CT/SI:0-0/SG:1 1/1/0001 12:00:00 AM X-Note-SnifferID: 0 X-Note: TCH-CT/SI:0-43/SG:1 1/7/2018 3:53:21 PM X-GBUdb-Analysis: 0, 213.210.30.29, Ugly c=0.524278 p=-0.925926 Source Normal X-Signature-Violations: 0-0-0-16293-c X-Note: Spam Tests Failed: X-Country-Path: ->->United Kingdom->United States X-Note-Sending-IP: 213.210.30.29 X-Note-Reverse-DNS: elite.brightsigndigital.co.uk X-Note-Return-Path: mcrowe@brightsign.biz X-Note: User Rule Hits: X-Note: Global Rule Hits: G293 G294 G295 G296 G300 G301 G433 X-Note: Encrypt Rule Hits: X-Note: Mail Class: VALID The user-visible effect of this change is for std::future::wait_until to use CLOCK_MONOTONIC when passed a timeout of std::chrono::steady_clock type. This makes it immune to any changes made to the system clock CLOCK_REALTIME. Add an overload of __atomic_futex_unsigned::_M_load_and_text_until_impl that accepts a std::chrono::steady_clock, and correctly passes this through to __atomic_futex_unsigned_base::_M_futex_wait_until_steady which uses CLOCK_MONOTONIC for the timeout within the futex system call. These functions are mostly just copies of the std::chrono::system_clock versions with small tweaks. Prior to this commit, a std::chrono::steady timeout would be converted via std::chrono::system_clock which risks reducing or increasing the timeout if someone changes CLOCK_REALTIME whilst the wait is happening. (The commit immediately prior to this one increases the window of opportunity for that from a short period during the calculation of a relative timeout, to the entire duration of the wait.) I believe that I've added this functionality in a way that it doesn't break ABI compatibility, but that has made it more verbose and less type safe. I believe that it would be better to maintain the timeout as an instance of the correct clock type all the way down to a single _M_futex_wait_until function with an overload for each clock. The current scheme of separating out the seconds and nanoseconds early risks accidentally calling the wait function for the wrong clock. Unfortunately, doing this would break code that compiled against the old header. --- libstdc++-v3/include/bits/atomic_futex.h | 67 +++++++++++++++++++++++++++++++- libstdc++-v3/src/c++11/futex.cc | 33 ++++++++++++++++ 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/include/bits/atomic_futex.h b/libstdc++-v3/include/bits/atomic_futex.h index ad9437da4e2..78f39fb4048 100644 --- a/libstdc++-v3/include/bits/atomic_futex.h +++ b/libstdc++-v3/include/bits/atomic_futex.h @@ -52,11 +52,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1 struct __atomic_futex_unsigned_base { - // Returns false iff a timeout occurred. + // __s and __ns are measured against CLOCK_REALTIME. Returns false + // iff a timeout occurred. bool _M_futex_wait_until(unsigned *__addr, unsigned __val, bool __has_timeout, chrono::seconds __s, chrono::nanoseconds __ns); + // __s and __ns are measured against CLOCK_MONOTONIC. Returns + // false iff a timeout occurred. + bool + _M_futex_wait_until_steady(unsigned *__addr, unsigned __val, bool __has_timeout, + chrono::seconds __s, chrono::nanoseconds __ns); + // This can be executed after the object has been destroyed. static void _M_futex_notify_all(unsigned* __addr); }; @@ -86,6 +93,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // value if equal is false. // The assumed value is the caller's assumption about the current value // when making the call. + // __s and __ns are measured against CLOCK_REALTIME. unsigned _M_load_and_test_until(unsigned __assumed, unsigned __operand, bool __equal, memory_order __mo, bool __has_timeout, @@ -110,6 +118,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } + // If a timeout occurs, returns a current value after the timeout; + // otherwise, returns the operand's value if equal is true or a different + // value if equal is false. + // The assumed value is the caller's assumption about the current value + // when making the call. + // __s and __ns are measured against CLOCK_MONOTONIC. + unsigned + _M_load_and_test_until_steady(unsigned __assumed, unsigned __operand, + bool __equal, memory_order __mo, bool __has_timeout, + chrono::seconds __s, chrono::nanoseconds __ns) + { + for (;;) + { + // Don't bother checking the value again because we expect the caller + // to have done it recently. + // memory_order_relaxed is sufficient because we can rely on just the + // modification order (store_notify uses an atomic RMW operation too), + // and the futex syscalls synchronize between themselves. + _M_data.fetch_or(_Waiter_bit, memory_order_relaxed); + bool __ret = _M_futex_wait_until_steady((unsigned*)(void*)&_M_data, + __assumed | _Waiter_bit, + __has_timeout, __s, __ns); + // Fetch the current value after waiting (clears _Waiter_bit). + __assumed = _M_load(__mo); + if (!__ret || ((__operand == __assumed) == __equal)) + return __assumed; + // TODO adapt wait time + } + } + // Returns the operand's value if equal is true or a different value if // equal is false. // The assumed value is the caller's assumption about the current value @@ -140,6 +178,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION true, __s.time_since_epoch(), __ns); } + template + unsigned + _M_load_and_test_until_impl(unsigned __assumed, unsigned __operand, + bool __equal, memory_order __mo, + const chrono::time_point& __atime) + { + auto __s = chrono::time_point_cast(__atime); + auto __ns = chrono::duration_cast(__atime - __s); + // XXX correct? + return _M_load_and_test_until_steady(__assumed, __operand, __equal, __mo, + true, __s.time_since_epoch(), __ns); + } + public: _GLIBCXX_ALWAYS_INLINE unsigned @@ -200,6 +251,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return (__i & ~_Waiter_bit) == __val; } + // Returns false iff a timeout occurred. + template + _GLIBCXX_ALWAYS_INLINE bool + _M_load_when_equal_until(unsigned __val, memory_order __mo, + const chrono::time_point& __atime) + { + unsigned __i = _M_load(__mo); + if ((__i & ~_Waiter_bit) == __val) + return true; + // TODO Spin-wait first. Ignore effect on timeout. + __i = _M_load_and_test_until_impl(__i, __val, true, __mo, __atime); + return (__i & ~_Waiter_bit) == __val; + } + _GLIBCXX_ALWAYS_INLINE void _M_store_notify_all(unsigned __val, memory_order __mo) { diff --git a/libstdc++-v3/src/c++11/futex.cc b/libstdc++-v3/src/c++11/futex.cc index 40ec7f9b0f7..8ade1fffefe 100644 --- a/libstdc++-v3/src/c++11/futex.cc +++ b/libstdc++-v3/src/c++11/futex.cc @@ -36,6 +36,7 @@ // Constants for the wait/wake futex syscall operations const unsigned futex_wait_op = 0; const unsigned futex_wait_bitset_op = 9; +const unsigned futex_clock_monotonic_flag = 0; const unsigned futex_clock_realtime_flag = 256; const unsigned futex_bitset_match_any = ~0; const unsigned futex_wake_op = 1; @@ -75,6 +76,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } + bool + __atomic_futex_unsigned_base::_M_futex_wait_until_steady(unsigned *__addr, + unsigned __val, + bool __has_timeout, chrono::seconds __s, chrono::nanoseconds __ns) + { + if (!__has_timeout) + { + // Ignore whether we actually succeeded to block because at worst, + // we will fall back to spin-waiting. The only thing we could do + // here on errors is abort. + int ret __attribute__((unused)); + ret = syscall (SYS_futex, __addr, futex_wait_op, __val, nullptr); + _GLIBCXX_DEBUG_ASSERT(ret == 0 || errno == EINTR || errno == EAGAIN); + return true; + } + else + { + struct timespec rt; + rt.tv_sec = __s.count(); + rt.tv_nsec = __ns.count(); + + if (syscall (SYS_futex, __addr, futex_wait_bitset_op | futex_clock_monotonic_flag, __val, &rt, nullptr, futex_bitset_match_any) == -1) + { + _GLIBCXX_DEBUG_ASSERT(errno == EINTR || errno == EAGAIN + || errno == ETIMEDOUT); + if (errno == ETIMEDOUT) + return false; + } + return true; + } + } + void __atomic_futex_unsigned_base::_M_futex_notify_all(unsigned* __addr) { From patchwork Sun Jan 7 20:55:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Crowe X-Patchwork-Id: 856615 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-470342-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="ODO988ZD"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zF9gk2SPvz9ryT for ; Mon, 8 Jan 2018 07:56:50 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; q=dns; s= default; b=b/i2cF3AR9aR/dy8yuQvBxKedtueuyM7D492AmXeBlJeBLGtjTllq LvaneMOHkkNsRfTXYmRNX/5IkaMmZpIirizYPS+5QncxJtH09r2wEsmXc46MRC0u h6JMOmVly629+EeqgaFB9LcKfVtKNVfkD9gUDxVFLZrNiZlUmduqjw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; s= default; bh=cBhHax9xegkcYRcyfQD6LR+5ZHw=; b=ODO988ZDlB52Cbn+UOUT WEn7nB/yAQFjhd67+nyi/LRrjXYPMswp+3V01EEmfYXWre/076yw1LIkDO5Fz56g 3wP5bBWWSxCsj4uEBEr8B89mfwpTg2fUCYUs/HTOcZYbVN39N+SGbGjQ3FMyAAfV VZxaY7tHYnI9TwG1JW60G0Q= Received: (qmail 15602 invoked by alias); 7 Jan 2018 20:55:53 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 15411 invoked by uid 89); 7 Jan 2018 20:55:53 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-27.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=risks X-Spam-User: qpsmtpd, 2 recipients X-HELO: relay.appriver.com Received: from relay101a.appriver.com (HELO relay.appriver.com) (207.97.230.14) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 07 Jan 2018 20:55:51 +0000 X-Note: This Email was scanned by AppRiver SecureTide X-Note-AR-ScanTimeLocal: 01/07/2018 3:53:48 PM X-Note: SecureTide Build: 12/19/2017 1:37:44 PM UTC (2.6.27.2) X-Note: Filtered by 10.238.11.161 X-Note-AR-Scan: None - PIPE Received: by relay.appriver.com (CommuniGate Pro PIPE 6.1.7) with PIPE id 273613008; Sun, 07 Jan 2018 15:53:48 -0500 Received: from [213.210.30.29] (HELO elite.brightsign) by relay.appriver.com (CommuniGate Pro SMTP 6.1.7) with ESMTPS id 273612986; Sun, 07 Jan 2018 15:53:48 -0500 Received: from chuckie.brightsign ([fd44:d8b8:cab5:cb01::19] helo=chuckie) by elite.brightsign with esmtp (Exim 4.89) (envelope-from ) id 1eYHyr-0008uy-LO; Sun, 07 Jan 2018 20:55:45 +0000 Received: from mac by chuckie with local (Exim 4.89) (envelope-from ) id 1eYHyr-0003RK-Kn; Sun, 07 Jan 2018 20:55:45 +0000 From: Mike Crowe To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Cc: Mike Crowe Subject: [PATCH 4/5] libstdc++ atomic_futex: Use std::chrono::steady_clock as reference clock Date: Sun, 7 Jan 2018 20:55:31 +0000 Message-Id: <20180107205532.13138-5-mac@mcrowe.com> In-Reply-To: <20180107205532.13138-1-mac@mcrowe.com> References: <20180107205532.13138-1-mac@mcrowe.com> X-Note: This Email was scanned by AppRiver SecureTide X-Note-AR-ScanTimeLocal: 01/07/2018 3:53:48 PM X-Note: SecureTide Build: 12/19/2017 1:37:44 PM UTC (2.6.27.2) X-Note: Filtered by 10.238.11.161 X-Policy: brightsign.biz X-Primary: brightsign.biz@brightsign.biz X-Virus-Scan: V- X-Note: ICH-CT/SI:0-0/SG:1 1/1/0001 12:00:00 AM X-Note-SnifferID: 0 X-Note: TCH-CT/SI:0-43/SG:1 1/7/2018 3:53:04 PM X-GBUdb-Analysis: 0, 213.210.30.29, Ugly c=0.476605 p=-0.960784 Source Normal X-Signature-Violations: 0-0-0-6198-c X-Note: Spam Tests Failed: X-Country-Path: ->->United Kingdom->United States X-Note-Sending-IP: 213.210.30.29 X-Note-Reverse-DNS: elite.brightsigndigital.co.uk X-Note-Return-Path: mcrowe@brightsign.biz X-Note: User Rule Hits: X-Note: Global Rule Hits: G293 G294 G295 G296 G300 G301 G433 X-Note: Encrypt Rule Hits: X-Note: Mail Class: VALID The user-visible effect of this change is that std::future::wait_for now uses std::chrono::steady_clock to determine the timeout. This makes it immune to changes made to the system clock. It also means that anyone using their own clock types with std::future::wait_until will have the timeout converted to std::chrono::steady_clock rather than std::chrono::system_clock. Now that use of both std::chrono::steady_clock and std::chrono::system_clock are correctly supported for the wait timeout, I believe that std::chrono::steady_clock is a better choice for the reference clock that all other clocks are converted to since it is guaranteed to advance steadily. The previous behaviour of converting to std::chrono::system_clock risks timeouts changing dramatically when the system clock is changed. --- libstdc++-v3/include/bits/atomic_futex.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/include/bits/atomic_futex.h b/libstdc++-v3/include/bits/atomic_futex.h index 78f39fb4048..7dff848d8ad 100644 --- a/libstdc++-v3/include/bits/atomic_futex.h +++ b/libstdc++-v3/include/bits/atomic_futex.h @@ -71,7 +71,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template class __atomic_futex_unsigned : __atomic_futex_unsigned_base { - typedef chrono::system_clock __clock_t; + typedef chrono::steady_clock __clock_t; // This must be lock-free and at offset 0. atomic _M_data; @@ -169,7 +169,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION unsigned _M_load_and_test_until_impl(unsigned __assumed, unsigned __operand, bool __equal, memory_order __mo, - const chrono::time_point<__clock_t, _Dur>& __atime) + const chrono::time_point& __atime) { auto __s = chrono::time_point_cast(__atime); auto __ns = chrono::duration_cast(__atime - __s); @@ -229,7 +229,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_load_when_equal_until(unsigned __val, memory_order __mo, const chrono::time_point<_Clock, _Duration>& __atime) { - // DR 887 - Sync unknown clock to known clock. const typename _Clock::time_point __c_entry = _Clock::now(); const __clock_t::time_point __s_entry = __clock_t::now(); const auto __delta = __atime - __c_entry; @@ -241,7 +240,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template _GLIBCXX_ALWAYS_INLINE bool _M_load_when_equal_until(unsigned __val, memory_order __mo, - const chrono::time_point<__clock_t, _Duration>& __atime) + const chrono::time_point& __atime) { unsigned __i = _M_load(__mo); if ((__i & ~_Waiter_bit) == __val) From patchwork Sun Jan 7 20:55:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Crowe X-Patchwork-Id: 856616 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-470343-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="YR3ds9aB"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zF9gy1p7Qz9ryT for ; Mon, 8 Jan 2018 07:57:02 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; q=dns; s= default; b=qNk12zm3bIRUDg0BAi299dfw//VIHNPbSBePa9ps4M4Swm/Bd++Bh PNtGspNN6PFqbyRL+jYSFYUsKfGpIC/4DNqkMRzB2BaPKmkQj/kbTeKQat06urol ruUdldxvHTsyq1wQFAR6hR1cDZnfSjz2IcHWqXXfWOVkDa1FpIkr4E= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:in-reply-to:references; s= default; bh=kt8mmXvKv8Fdc7n/xHOqKQbFrqQ=; b=YR3ds9aBzKx2ePJ41ly8 VlZx8S1Q+QfdhWDwzmsvn9x1Hp8AGK4MAXaZGs9HB03i+goyunAnNZH7B3qF0q3U UP++NNtJZlvMpFl36aAdPsmAOOIQbhKTR8lWDTzWIhMTB3ueQnJNzjiSjyBwgJQf HUTicx0yulIjvTj2TQO3uH4= Received: (qmail 15841 invoked by alias); 7 Jan 2018 20:55:55 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 15766 invoked by uid 89); 7 Jan 2018 20:55:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-27.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=forth X-Spam-User: qpsmtpd, 2 recipients X-HELO: relay.appriver.com Received: from relay101b.appriver.com (HELO relay.appriver.com) (207.97.230.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 07 Jan 2018 20:55:52 +0000 X-Note: This Email was scanned by AppRiver SecureTide X-Note-AR-ScanTimeLocal: 01/07/2018 3:53:50 PM X-Note: SecureTide Build: 12/19/2017 1:37:44 PM UTC (2.6.27.2) X-Note: Filtered by 10.238.11.162 X-Note-AR-Scan: None - PIPE Received: by relay.appriver.com (CommuniGate Pro PIPE 6.1.7) with PIPE id 275441494; Sun, 07 Jan 2018 15:53:50 -0500 Received: from [213.210.30.29] (HELO elite.brightsign) by relay.appriver.com (CommuniGate Pro SMTP 6.1.7) with ESMTPS id 275441490; Sun, 07 Jan 2018 15:53:48 -0500 Received: from chuckie.brightsign ([fd44:d8b8:cab5:cb01::19] helo=chuckie) by elite.brightsign with esmtp (Exim 4.89) (envelope-from ) id 1eYHyr-0008v0-Lo; Sun, 07 Jan 2018 20:55:45 +0000 Received: from mac by chuckie with local (Exim 4.89) (envelope-from ) id 1eYHyr-0003RN-LD; Sun, 07 Jan 2018 20:55:45 +0000 From: Mike Crowe To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Cc: Mike Crowe Subject: [PATCH 5/5] Extra async tests, not for merging Date: Sun, 7 Jan 2018 20:55:32 +0000 Message-Id: <20180107205532.13138-6-mac@mcrowe.com> In-Reply-To: <20180107205532.13138-1-mac@mcrowe.com> References: <20180107205532.13138-1-mac@mcrowe.com> X-Note: This Email was scanned by AppRiver SecureTide X-Note-AR-ScanTimeLocal: 01/07/2018 3:53:48 PM X-Note: SecureTide Build: 12/19/2017 1:37:44 PM UTC (2.6.27.2) X-Note: Filtered by 10.238.11.162 X-Policy: brightsign.biz X-Primary: brightsign.biz@brightsign.biz X-Virus-Scan: V- X-Note: ICH-CT/SI:0-0/SG:1 1/1/0001 12:00:00 AM X-Note-SnifferID: 0 X-Note: TCH-CT/SI:0-43/SG:1 1/7/2018 3:53:21 PM X-GBUdb-Analysis: 0, 213.210.30.29, Ugly c=0.52364 p=-0.925466 Source Normal X-Signature-Violations: 0-0-0-6804-c X-Note: Spam Tests Failed: X-Country-Path: ->->United Kingdom->United States X-Note-Sending-IP: 213.210.30.29 X-Note-Reverse-DNS: elite.brightsigndigital.co.uk X-Note-Return-Path: mcrowe@brightsign.biz X-Note: User Rule Hits: X-Note: Global Rule Hits: G293 G294 G295 G296 G300 G301 G433 X-Note: Encrypt Rule Hits: X-Note: Mail Class: VALID These tests show that changing the system clock has an effect on std::future::wait_until when using std::chrono::system_clock but not when using std::chrono::steady_clock. Unfortunately these tests have a number of downsides: 1. Nothing that is attempting to keep the clock set correctly (ntpd, systemd-timesyncd) can be running at the same time. 2. The test process requires the CAP_SYS_TIME capability. 3. Other processes running concurrently may misbehave when the clock darts back and forth. 4. They are slow to run. As such, I don't think they are suitable for merging. I include them here because I wanted to document how I had tested the changes in the previous commits. --- libstdc++-v3/testsuite/30_threads/async/async.cc | 76 ++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/libstdc++-v3/testsuite/30_threads/async/async.cc b/libstdc++-v3/testsuite/30_threads/async/async.cc index 7326c5f7cd6..5bd7e999401 100644 --- a/libstdc++-v3/testsuite/30_threads/async/async.cc +++ b/libstdc++-v3/testsuite/30_threads/async/async.cc @@ -25,6 +25,7 @@ #include #include +#include using namespace std; @@ -94,11 +95,86 @@ void test03() VERIFY( elapsed < std::chrono::seconds(20) ); } +void perturb_system_clock(const std::chrono::seconds &seconds) +{ + struct timeval tv; + if (gettimeofday(&tv, NULL)) + abort(); + + tv.tv_sec += seconds.count(); + if (settimeofday(&tv, NULL)) + abort(); +} + +void work04() +{ + std::this_thread::sleep_for(std::chrono::seconds(10)); +} + +// Ensure that advancing CLOCK_REALTIME doesn't make any difference +// when we're waiting on std::chrono::steady_clock. +void test04() +{ + auto const start = chrono::steady_clock::now(); + future f1 = async(launch::async, &work04); + + perturb_system_clock(chrono::seconds(20)); + + std::future_status status; + status = f1.wait_for(std::chrono::seconds(4)); + VERIFY( status == std::future_status::timeout ); + + status = f1.wait_until(start + std::chrono::seconds(6)); + VERIFY( status == std::future_status::timeout ); + + status = f1.wait_until(start + std::chrono::seconds(12)); + VERIFY( status == std::future_status::ready ); + + auto const elapsed = chrono::steady_clock::now() - start; + VERIFY( elapsed >= std::chrono::seconds(10) ); + VERIFY( elapsed < std::chrono::seconds(15) ); + + perturb_system_clock(chrono::seconds(-20)); +} + +void work05() +{ + std::this_thread::sleep_for(std::chrono::seconds(5)); + perturb_system_clock(chrono::seconds(60)); + std::this_thread::sleep_for(std::chrono::seconds(5)); +} + +// Ensure that advancing CLOCK_REALTIME does make a difference when +// we're waiting on std::chrono::system_clock. +void test05() +{ + auto const start = chrono::system_clock::now(); + auto const start_steady = chrono::steady_clock::now(); + + future f1 = async(launch::async, &work05); + future_status status; + status = f1.wait_until(start + std::chrono::seconds(60)); + VERIFY( status == std::future_status::timeout ); + + auto const elapsed_steady = chrono::steady_clock::now() - start_steady; + VERIFY( elapsed_steady >= std::chrono::seconds(5) ); + VERIFY( elapsed_steady < std::chrono::seconds(10) ); + + status = f1.wait_until(start + std::chrono::seconds(75)); + VERIFY( status == std::future_status::ready ); + + perturb_system_clock(chrono::seconds(-60)); +} + int main() { test01(); test02(); test03(); test03(); + if (geteuid() == 0) { + test04(); + test05(); + } return 0; }