From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 111728 invoked by alias); 9 Jan 2018 13:50:58 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 110780 invoked by uid 89); 9 Jan 2018 13:50:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_HELO_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=Hx-languages-length:2536 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 09 Jan 2018 13:50:56 +0000 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7381CA0362; Tue, 9 Jan 2018 13:50:55 +0000 (UTC) Received: from localhost (unknown [10.33.36.58]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0D7FE5E1C7; Tue, 9 Jan 2018 13:50:54 +0000 (UTC) Date: Tue, 09 Jan 2018 13:56:00 -0000 From: Jonathan Wakely To: Mike Crowe Cc: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: Re: [PATCH 2/5] libstdc++ futex: Use FUTEX_CLOCK_REALTIME for wait Message-ID: <20180109135053.GB5527@redhat.com> References: <20180107205532.13138-1-mac@mcrowe.com> <20180107205532.13138-3-mac@mcrowe.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline In-Reply-To: <20180107205532.13138-3-mac@mcrowe.com> X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.9.1 (2017-09-22) X-SW-Source: 2018-01/txt/msg00614.txt.bz2 On 07/01/18 20:55 +0000, Mike Crowe wrote: >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. I don't think we can require a specific kernel version just for this. What happens if you use those bits on an older kernel, will there be an ENOSYS error? Because that would allow us to try the new form, and fallback to the old. With that I think this change looks good. >--- > 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); >-- >2.11.0 > >