Ticket #6061: 6061.patch

File 6061.patch, 6.7 KB (added by pcapriotti, 3 years ago)
  • rts/GetTime.h

    From 2d0997e69c2b11fce783358ef2cbb5e61fe4e4e3 Mon Sep 17 00:00:00 2001
    From: Paolo Capriotti <[email protected]>
    Date: Wed, 2 May 2012 16:34:24 +0100
    Subject: [PATCH] Move getMonotonicUSec from base to the RTS.
    
    ---
     rts/GetTime.h       |    3 ++
     rts/Linker.c        |    1 +
     rts/RtsStartup.c    |    3 ++
     rts/posix/GetTime.c |   36 ++++++++++++++++--------
     rts/win32/GetTime.c |   74 ++++++++++++++++++++++++++++++++------------------
     5 files changed, 78 insertions(+), 39 deletions(-)
    
    diff --git a/rts/GetTime.h b/rts/GetTime.h
    index 86c5511..45804aa 100644
    a b  
    1111
    1212#include "BeginPrivate.h"
    1313
     14void initializeTimer       (void);
     15StgWord64 getMonotonicNSec (void);
     16
    1417Time getProcessCPUTime     (void);
    1518Time getThreadCPUTime      (void);
    1619Time getProcessElapsedTime (void);
  • rts/Linker.c

    diff --git a/rts/Linker.c b/rts/Linker.c
    index 48667b4..42c6117 100644
    a b typedef struct _RtsSymbolVal { 
    10931093      SymI_HasProto(n_capabilities)                     \
    10941094      SymI_HasProto(stg_traceCcszh)                     \
    10951095      SymI_HasProto(stg_traceEventzh)                   \
     1096      SymI_HasProto(getMonotonicNSec)                   \
    10961097      RTS_USER_SIGNALS_SYMBOLS                          \
    10971098      RTS_INTCHAR_SYMBOLS
    10981099
  • rts/RtsStartup.c

    diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c
    index 307a691..ed13915 100644
    a b hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config) 
    128128    /* Initialise the stats department, phase 0 */
    129129    initStats0();
    130130
     131    /* Initialize system timer before starting to collect stats */
     132    initializeTimer();
     133
    131134    /* Next we do is grab the start time...just in case we're
    132135     * collecting timing statistics.
    133136     */
  • rts/posix/GetTime.c

    diff --git a/rts/posix/GetTime.c b/rts/posix/GetTime.c
    index 549b3b0..da8d0fa 100644
    a b  
    3333// we'll implement getProcessCPUTime() and getProcessElapsedTime()
    3434// separately, using getrusage() and gettimeofday() respectively
    3535
     36#ifdef darwin_HOST_OS
     37static double timer_scaling_factor_ns = 0.0;
     38#endif
     39
     40void initializeTimer()
     41{
     42#ifdef darwin_HOST_OS
     43    mach_timebase_info_data_t info;
     44    (void) mach_timebase_info(&info);
     45    timer_scaling_factor_ns = (double)info.numer / (double)info.denom * 1e9;
     46#endif
     47}
     48
    3649Time getProcessCPUTime(void)
    3750{
    3851#if !defined(BE_CONSERVATIVE) && defined(HAVE_CLOCK_GETTIME) && defined (_SC_CPUTIME) && defined(CLOCK_PROCESS_CPUTIME_ID) && defined(HAVE_SYSCONF)
    Time getProcessCPUTime(void) 
    6477    }
    6578}
    6679
    67 Time getProcessElapsedTime(void)
     80StgWord64 getMonotonicNSec(void)
    6881{
    6982#ifdef HAVE_CLOCK_GETTIME
    7083    struct timespec ts;
    7184
    7285    clock_gettime(CLOCK_ID, &ts);
    73     return SecondsToTime(ts.tv_sec) + NSToTime(ts.tv_nsec);
     86    return (StgWord64)ts.tv_sec * 1000000000 +
     87           (StgWord64)ts.tv_nsec;
    7488#elif defined(darwin_HOST_OS)
    7589    uint64_t time = mach_absolute_time();
    76     static double scaling_factor = 0.0;
    77 
    78     if (scaling_factor == 0.0) {
    79         mach_timebase_info_data_t info;
    80         (void) mach_timebase_info(&info);
    81         scaling_factor = (double)info.numer / (double)info.denom;
    82     }
    83 
    84     return (Time)((double)time * scaling_factor);
     90    return (double)time * timer_scaling_factor_ns;
    8591#else
    8692    struct timeval tv;
    8793
    8894    gettimeofday(&tv, (struct timezone *) NULL);
    89     return SecondsToTime(tv.tv_sec) + USToTime(tv.tv_usec);
     95    return (StgWord64)tv.tv_sec * 1000000000 +
     96           (StgWord64)tv.tv_usec * 1000;
    9097#endif
    9198}
    9299
     100Time getProcessElapsedTime(void)
     101{
     102    return NSToTime(getMonotonicNSec());
     103}
     104
    93105void getProcessTimes(Time *user, Time *elapsed)
    94106{
    95107    *user    = getProcessCPUTime();
  • rts/win32/GetTime.c

    diff --git a/rts/win32/GetTime.c b/rts/win32/GetTime.c
    index 9a322bf..ec506fe 100644
    a b getProcessCPUTime(void) 
    4747    return fileTimeToRtsTime(userTime);
    4848}
    4949
    50 // getProcessElapsedTime relies on QueryPerformanceFrequency
    51 // which should be available on any Windows computer thay you
    52 // would want to run Haskell on. Satnam Singh, 5 July 2010.
     50// Number of ticks per second used by the QueryPerformanceFrequency
     51// implementaiton, represented by a 64-bit union type.
     52static LARGE_INTEGER qpc_frequency = {.QuadPart = 0};
     53
     54// Initialize qpc_frequency. This function should be called before any call to
     55// getMonotonicNSec.  If QPC is not supported on this system, qpc_frequency is
     56// set to 0.
     57void initializeTimer()
     58{
     59    BOOL qpc_supported = QueryPerformanceFrequency(&qpc_frequency);
     60    if (!qpc_supported)
     61    {
     62        qpc_frequency.QuadPart = 0;
     63    }
     64}
     65
     66HsWord64
     67getMonotonicNSec()
     68{
     69    if (qpc_frequency.QuadPart)
     70    {
     71        // system_time is a 64-bit union type used to represent the
     72        // tick count returned by QueryPerformanceCounter
     73        LARGE_INTEGER system_time;
     74
     75        // get the tick count.
     76        QueryPerformanceCounter(&system_time);
     77
     78        // compute elapsed seconds as double
     79        double secs = (double)system_time.QuadPart /
     80                      (double)qpc_frequency.QuadPart;
     81
     82        // return elapsed time in nanoseconds
     83        return (HsWord64)(secs * 1e9);
     84    }
     85    else // fallback to GetTickCount
     86    {
     87        // NOTE: GetTickCount is a 32-bit millisecond value, so it wraps around
     88        // every 49 days.
     89        DWORD count = GetTickCount();
     90
     91        // getTickCount is in milliseconds, so multiply it by 1000000 to get
     92        // nanoseconds.
     93        return (HsWord64)count * 1000000;
     94    }
     95}
    5396
    5497Time
    5598getProcessElapsedTime(void)
    5699{
    57     // frequency represents the number of ticks per second
    58     // used by the QueryPerformanceFrequency implementaiton
    59     // and is represented by a 64-bit union type initially set to 0
    60     // and updated just once (hence use of static).
    61     static LARGE_INTEGER frequency = {.QuadPart = 0} ; 
    62 
    63     // system_time is a 64-bit union type used to represent the
    64     // tick count returned by QueryPerformanceCounter
    65     LARGE_INTEGER system_time ;
    66 
    67     // If this is the first time we are calling getProcessElapsedTime
    68     // then record the ticks per second used by QueryPerformanceCounter
    69     if (frequency.QuadPart == 0) {
    70       QueryPerformanceFrequency(&frequency);
    71     }
    72    
    73     // Get the tick count.
    74     QueryPerformanceCounter(&system_time) ;
    75 
    76     // Return the tick count as a Time value.
    77     // Using double to compute the intermediate value, because a 64-bit
    78     // int would overflow when multiplied by TICK_RESOLUTION in about 81 days.
    79     return fsecondsToTime((double)system_time.QuadPart /
    80                           (double)frequency.QuadPart) ;
     100    return NSToTime(getMonotonicNSec());
    81101}
    82102
    83103Time