From patchwork Tue Feb 1 21:12:00 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janne Blomqvist X-Patchwork-Id: 81377 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id E8374B70EC for ; Wed, 2 Feb 2011 08:12:13 +1100 (EST) Received: (qmail 17803 invoked by alias); 1 Feb 2011 21:12:10 -0000 Received: (qmail 17779 invoked by uid 22791); 1 Feb 2011 21:12:09 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, TW_BG, TW_LR X-Spam-Check-By: sourceware.org Received: from mail-iw0-f175.google.com (HELO mail-iw0-f175.google.com) (209.85.214.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 01 Feb 2011 21:12:02 +0000 Received: by iwn8 with SMTP id 8so7323004iwn.20 for ; Tue, 01 Feb 2011 13:12:00 -0800 (PST) MIME-Version: 1.0 Received: by 10.231.10.197 with SMTP id q5mr8902846ibq.197.1296594720258; Tue, 01 Feb 2011 13:12:00 -0800 (PST) Received: by 10.231.160.68 with HTTP; Tue, 1 Feb 2011 13:12:00 -0800 (PST) Date: Tue, 1 Feb 2011 23:12:00 +0200 Message-ID: Subject: [Patch, libfortran] PR 47571 Fix static linking regression From: Janne Blomqvist To: Fortran List , GCC Patches 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 Hi, my recent patch to use clock_gettime() made static linking break on Linux, since the driver didn't link in librt. It was also pointed out that always requiring librt in libgfortran might in principle reduce performance for non-threaded programs as librt pulls in libpthread and thus the weakrefed IO locking stuff becomes real locks. The attached patch fixes this by not linking in librt (and this libpthread) in libgfortran.so, and instead calls clock_gettime() through a weak reference, falling back to gettimeofday()/other fallbacks in case librt is not explicitly linked in (or implicitly e.g. via -fopenmp). For platforms that provide clock_gettime() in libc, clock_gettime() ought to always be used, although I'm not able to test this. Regtested on x86_64-unknown-linux-gnu, tested a simple program to ensure usage of clock_gettime() or gettimeofday() depending on whether librt is linked. Ok for trunk? 2011-02-01 Janne Blomqvist PR libfortran/47571 * configure: Regenerated. * configure.ac: Don't add librt to LIBS. * intrinsics/time_1.h (weak_gettime): Weakref trickery for clock_gettime(). (gf_gettime): Use weak_gettime() instead of clock_gettime(). diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac index ed1e2cc..8161659 100644 --- a/libgfortran/configure.ac +++ b/libgfortran/configure.ac @@ -486,11 +486,11 @@ AC_CHECK_LIB([m],[feenableexcept],[have_feenableexcept=yes AC_DEFINE([HAVE_FEENA # At least for glibc, clock_gettime is in librt. But don't pull that # in if it still doesn't give us the function we want. -# This test is copied from libgomp. +# This test is copied from libgomp, and modified to not link in -lrt +# as libgfortran calls clock_gettime via a weak reference. if test $ac_cv_func_clock_gettime = no; then AC_CHECK_LIB(rt, clock_gettime, - [LIBS="-lrt $LIBS" - AC_DEFINE(HAVE_CLOCK_GETTIME, 1, + [AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Define to 1 if you have the `clock_gettime' function.])]) fi diff --git a/libgfortran/intrinsics/time_1.h b/libgfortran/intrinsics/time_1.h index 58c51af..86e4331 100644 --- a/libgfortran/intrinsics/time_1.h +++ b/libgfortran/intrinsics/time_1.h @@ -189,6 +189,22 @@ gf_cputime (long *user_sec, long *user_usec, long *system_sec, long *system_usec #define GF_CLOCK_MONOTONIC GF_CLOCK_REALTIME #endif +/* Weakref trickery for clock_gettime(). On Glibc, clock_gettime() + requires us to link in librt, which also pulls in libpthread. In + order to avoid this by default, only call clock_gettime() through a + weak reference. */ +#ifdef HAVE_CLOCK_GETTIME +#ifdef SUPPORTS_WEAK +static int weak_gettime (clockid_t, struct timespec *) + __attribute__((__weakref__("clock_gettime"))); +#else +static inline int weak_gettime (clockid_t clk_id, struct timespec *res) +{ + return clock_gettime (clk_id, res); +} +#endif +#endif + /* Arguments: clock_id - INPUT, must be either GF_CLOCK_REALTIME or GF_CLOCK_MONOTONIC secs - OUTPUT, seconds @@ -208,14 +224,18 @@ gf_gettime (int clock_id __attribute__((unused)), time_t * secs, long * nanosecs) { #ifdef HAVE_CLOCK_GETTIME - struct timespec ts; - int err; - err = clock_gettime (clock_id, &ts); - *secs = ts.tv_sec; - if (nanosecs) - *nanosecs = ts.tv_nsec; - return err; -#elif HAVE_GETTIMEOFDAY + if (weak_gettime) + { + struct timespec ts; + int err; + err = weak_gettime (clock_id, &ts); + *secs = ts.tv_sec; + if (nanosecs) + *nanosecs = ts.tv_nsec; + return err; + } +#endif +#ifdef HAVE_GETTIMEOFDAY struct timeval tv; int err; err = gettimeofday (&tv, NULL);