From patchwork Sat Sep 28 08:44:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Crowe X-Patchwork-Id: 1168815 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-509756-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mcrowe.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="Dp+QjhUJ"; 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 46gMhL68FRz9sN1 for ; Sat, 28 Sep 2019 18:46:10 +1000 (AEST) 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 :mime-version:content-transfer-encoding; q=dns; s=default; b=bcl CqLKZfeJWO2QeYiI+6HStXewptkBsvcuAq781NZqE1+EV7PcGZ6F2PkIw1YAYtd8 NWPDJt6qgH2zJHcIJhEAffhe4uEQ5DFtQ08weWu5NgO9KRvh+lpqbGbn7+WsxiTX MPhzojo5nYH6MmdZUEXGypE9yU6zurbVVxxOx5Po= 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 :mime-version:content-transfer-encoding; s=default; bh=0oiNTBgDm lQcIyqwq6V6xRg8zZ0=; b=Dp+QjhUJqceS8JPxlGc8mKmsMhc/JsoeyC4weBi8v zhdJSu0RL2KBaKhqcWnCLRAwxg4tG3fqd8ng3u9WfXr9VDsd4dbSplGrIh841zvv Fn0YmOjhhWFdlPeCgmEAQ7UeQsT6QMkg0kBgGUUrH8cEHtomCArWn2TaQoJLBEzg 7o= Received: (qmail 59975 invoked by alias); 28 Sep 2019 08:45:44 -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 55811 invoked by uid 89); 28 Sep 2019 08:45:37 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-23.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 spammy=HContent-Transfer-Encoding:8bit X-HELO: avasout03.plus.net Received: from avasout03.plus.net (HELO avasout03.plus.net) (84.93.230.244) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 28 Sep 2019 08:45:27 +0000 Received: from deneb ([80.229.24.9]) by smtp with ESMTP id E8Lpi2fjDtvkXE8LqiRMmC; Sat, 28 Sep 2019 09:45:19 +0100 X-Clacks-Overhead: "GNU Terry Pratchett" X-CM-Score: 0.00 Received: from mac by deneb with local (Exim 4.92) (envelope-from ) id 1iE8Lg-0006Sk-4Q; Sat, 28 Sep 2019 09:45:04 +0100 From: Mike Crowe To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Cc: Mike Crowe Subject: [PATCH 07/11] PR libstdc++/91906 Fix timed_mutex::try_lock_until on arbitrary clock Date: Sat, 28 Sep 2019 09:44:46 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 A non-standard clock may tick more slowly than std::chrono::steady_clock. This means that we risk returning false early when the specified timeout may not have expired. This can be avoided by looping until the timeout time as reported by the non-standard clock has been reached. Unfortunately, we have no way to tell whether the non-standard clock ticks more quickly that std::chrono::steady_clock. If it does then we risk returning later than would be expected, but that is unavoidable and permitted by the standard. * include/std/mutex (_M_try_lock_until): Loop until the absolute timeout time is reached as measured against the appropriate clock. * testsuite/30_threads/timed_mutex/try_lock_until/3.cc: Also run test using slow_clock to test above fix. * testsuite/30_threads/recursive_timed_mutex/try_lock_until/3.cc: Likewise. --- libstdc++-v3/include/std/mutex | 13 +++++++++++-- libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/3.cc | 2 ++ libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/3.cc | 2 ++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex index e06d286..bb3a41b 100644 --- a/libstdc++-v3/include/std/mutex +++ b/libstdc++-v3/include/std/mutex @@ -189,8 +189,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool _M_try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime) { - auto __rtime = __atime - _Clock::now(); - return _M_try_lock_for(__rtime); + // The user-supplied clock may not tick at the same rate as + // steady_clock, so we must loop in order to guarantee that + // the timeout has expired before returning false. + auto __now = _Clock::now(); + while (__atime > __now) { + auto __rtime = __atime - __now; + if (_M_try_lock_for(__rtime)) + return true; + __now = _Clock::now(); + } + return false; } }; diff --git a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/3.cc b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/3.cc index 4f0b0b5..a845cbf 100644 --- a/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/3.cc +++ b/libstdc++-v3/testsuite/30_threads/recursive_timed_mutex/try_lock_until/3.cc @@ -26,6 +26,7 @@ #include #include #include +#include template void test() @@ -71,4 +72,5 @@ int main() { test(); test(); + test(); } diff --git a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/3.cc b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/3.cc index 69d1ea5..9f34644 100644 --- a/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/3.cc +++ b/libstdc++-v3/testsuite/30_threads/timed_mutex/try_lock_until/3.cc @@ -26,6 +26,7 @@ #include #include #include +#include template void test() @@ -71,4 +72,5 @@ int main() { test(); test(); + test(); }