Ticket #6061: 6061.patch

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

    From 2d0997e69c2b11fce783358ef2cbb5e61fe4e4e3 Mon Sep 17 00:00:00 2001
    From: Paolo Capriotti <p.capriotti@gmail.com>
    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