diff options
Diffstat (limited to 'rts')
-rw-r--r-- | rts/FileLock.c (renamed from rts/posix/FileLock.c) | 11 | ||||
-rw-r--r-- | rts/FileLock.h (renamed from rts/posix/FileLock.h) | 0 | ||||
-rw-r--r-- | rts/GetTime.h | 3 | ||||
-rw-r--r-- | rts/Linker.c | 5 | ||||
-rw-r--r-- | rts/RtsStartup.c | 9 | ||||
-rw-r--r-- | rts/posix/GetTime.c | 36 | ||||
-rw-r--r-- | rts/win32/GetTime.c | 74 |
7 files changed, 86 insertions, 52 deletions
diff --git a/rts/posix/FileLock.c b/rts/FileLock.c index cb36366070..44ff67140c 100644 --- a/rts/posix/FileLock.c +++ b/rts/FileLock.c @@ -14,13 +14,12 @@ #include "RtsUtils.h" #include <sys/types.h> -#include <sys/stat.h> #include <unistd.h> #include <errno.h> typedef struct { - dev_t device; - ino_t inode; + StgWord64 device; + StgWord64 inode; int readers; // >0 : readers, <0 : writers } Lock; @@ -45,8 +44,8 @@ static int cmpLocks(StgWord w1, StgWord w2) static int hashLock(HashTable *table, StgWord w) { Lock *l = (Lock *)w; - // Just xor the dev_t with the ino_t, hope this is good enough. - return hashWord(table, (StgWord)l->inode ^ (StgWord)l->device); + // Just xor all 32-bit words of inode and device, hope this is good enough. + return hashWord(table, l->inode ^ (l->inode >> 32) ^ l->device ^ (l->device >> 32)); } void @@ -76,7 +75,7 @@ freeFileLocking(void) } int -lockFile(int fd, dev_t dev, ino_t ino, int for_writing) +lockFile(int fd, StgWord64 dev, StgWord64 ino, int for_writing) { Lock key, *lock; diff --git a/rts/posix/FileLock.h b/rts/FileLock.h index 72ab170437..72ab170437 100644 --- a/rts/posix/FileLock.h +++ b/rts/FileLock.h diff --git a/rts/GetTime.h b/rts/GetTime.h index 86c5511df9..45804aa3a9 100644 --- a/rts/GetTime.h +++ b/rts/GetTime.h @@ -11,6 +11,9 @@ #include "BeginPrivate.h" +void initializeTimer (void); +StgWord64 getMonotonicNSec (void); + Time getProcessCPUTime (void); Time getThreadCPUTime (void); Time getProcessElapsedTime (void); diff --git a/rts/Linker.c b/rts/Linker.c index df5ab5c44a..15e61badc6 100644 --- a/rts/Linker.c +++ b/rts/Linker.c @@ -304,8 +304,6 @@ typedef struct _RtsSymbolVal { SymI_HasProto(__hscore_get_saved_termios) \ SymI_HasProto(__hscore_set_saved_termios) \ SymI_HasProto(shutdownHaskellAndSignal) \ - SymI_HasProto(lockFile) \ - SymI_HasProto(unlockFile) \ SymI_HasProto(signal_handlers) \ SymI_HasProto(stg_sig_install) \ SymI_HasProto(rtsTimerSignal) \ @@ -1283,6 +1281,9 @@ typedef struct _RtsSymbolVal { SymI_HasProto(n_capabilities) \ SymI_HasProto(stg_traceCcszh) \ SymI_HasProto(stg_traceEventzh) \ + SymI_HasProto(getMonotonicNSec) \ + SymI_HasProto(lockFile) \ + SymI_HasProto(unlockFile) \ RTS_USER_SIGNALS_SYMBOLS \ RTS_INTCHAR_SYMBOLS diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c index 307a691352..f5c29f4a70 100644 --- a/rts/RtsStartup.c +++ b/rts/RtsStartup.c @@ -35,6 +35,7 @@ #include "Profiling.h" #include "Timer.h" #include "Globals.h" +#include "FileLock.h" void exitLinker( void ); // there is no Linker.h file to include #if defined(RTS_GTK_FRONTPANEL) @@ -52,7 +53,6 @@ void exitLinker( void ); // there is no Linker.h file to include #if !defined(mingw32_HOST_OS) #include "posix/TTY.h" -#include "posix/FileLock.h" #endif #ifdef HAVE_UNISTD_H @@ -128,6 +128,9 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config) /* Initialise the stats department, phase 0 */ initStats0(); + /* Initialize system timer before starting to collect stats */ + initializeTimer(); + /* Next we do is grab the start time...just in case we're * collecting timing statistics. */ @@ -212,9 +215,7 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config) initGlobalStore(); /* initialise file locking, if necessary */ -#if !defined(mingw32_HOST_OS) initFileLocking(); -#endif #if defined(DEBUG) /* initialise thread label table (tso->char*) */ @@ -373,9 +374,7 @@ hs_exit_(rtsBool wait_foreign) exitLinker(); /* free file locking tables, if necessary */ -#if !defined(mingw32_HOST_OS) freeFileLocking(); -#endif /* free the stable pointer table */ exitStablePtrTable(); diff --git a/rts/posix/GetTime.c b/rts/posix/GetTime.c index 549b3b0878..da8d0fa629 100644 --- a/rts/posix/GetTime.c +++ b/rts/posix/GetTime.c @@ -33,6 +33,19 @@ // we'll implement getProcessCPUTime() and getProcessElapsedTime() // separately, using getrusage() and gettimeofday() respectively +#ifdef darwin_HOST_OS +static double timer_scaling_factor_ns = 0.0; +#endif + +void initializeTimer() +{ +#ifdef darwin_HOST_OS + mach_timebase_info_data_t info; + (void) mach_timebase_info(&info); + timer_scaling_factor_ns = (double)info.numer / (double)info.denom * 1e9; +#endif +} + Time getProcessCPUTime(void) { #if !defined(BE_CONSERVATIVE) && defined(HAVE_CLOCK_GETTIME) && defined (_SC_CPUTIME) && defined(CLOCK_PROCESS_CPUTIME_ID) && defined(HAVE_SYSCONF) @@ -64,32 +77,31 @@ Time getProcessCPUTime(void) } } -Time getProcessElapsedTime(void) +StgWord64 getMonotonicNSec(void) { #ifdef HAVE_CLOCK_GETTIME struct timespec ts; clock_gettime(CLOCK_ID, &ts); - return SecondsToTime(ts.tv_sec) + NSToTime(ts.tv_nsec); + return (StgWord64)ts.tv_sec * 1000000000 + + (StgWord64)ts.tv_nsec; #elif defined(darwin_HOST_OS) uint64_t time = mach_absolute_time(); - static double scaling_factor = 0.0; - - if (scaling_factor == 0.0) { - mach_timebase_info_data_t info; - (void) mach_timebase_info(&info); - scaling_factor = (double)info.numer / (double)info.denom; - } - - return (Time)((double)time * scaling_factor); + return (double)time * timer_scaling_factor_ns; #else struct timeval tv; gettimeofday(&tv, (struct timezone *) NULL); - return SecondsToTime(tv.tv_sec) + USToTime(tv.tv_usec); + return (StgWord64)tv.tv_sec * 1000000000 + + (StgWord64)tv.tv_usec * 1000; #endif } +Time getProcessElapsedTime(void) +{ + return NSToTime(getMonotonicNSec()); +} + void getProcessTimes(Time *user, Time *elapsed) { *user = getProcessCPUTime(); diff --git a/rts/win32/GetTime.c b/rts/win32/GetTime.c index 9a322bf0a5..ec506fe4d0 100644 --- a/rts/win32/GetTime.c +++ b/rts/win32/GetTime.c @@ -47,37 +47,57 @@ getProcessCPUTime(void) return fileTimeToRtsTime(userTime); } -// getProcessElapsedTime relies on QueryPerformanceFrequency -// which should be available on any Windows computer thay you -// would want to run Haskell on. Satnam Singh, 5 July 2010. +// Number of ticks per second used by the QueryPerformanceFrequency +// implementaiton, represented by a 64-bit union type. +static LARGE_INTEGER qpc_frequency = {.QuadPart = 0}; + +// Initialize qpc_frequency. This function should be called before any call to +// getMonotonicNSec. If QPC is not supported on this system, qpc_frequency is +// set to 0. +void initializeTimer() +{ + BOOL qpc_supported = QueryPerformanceFrequency(&qpc_frequency); + if (!qpc_supported) + { + qpc_frequency.QuadPart = 0; + } +} + +HsWord64 +getMonotonicNSec() +{ + if (qpc_frequency.QuadPart) + { + // system_time is a 64-bit union type used to represent the + // tick count returned by QueryPerformanceCounter + LARGE_INTEGER system_time; + + // get the tick count. + QueryPerformanceCounter(&system_time); + + // compute elapsed seconds as double + double secs = (double)system_time.QuadPart / + (double)qpc_frequency.QuadPart; + + // return elapsed time in nanoseconds + return (HsWord64)(secs * 1e9); + } + else // fallback to GetTickCount + { + // NOTE: GetTickCount is a 32-bit millisecond value, so it wraps around + // every 49 days. + DWORD count = GetTickCount(); + + // getTickCount is in milliseconds, so multiply it by 1000000 to get + // nanoseconds. + return (HsWord64)count * 1000000; + } +} Time getProcessElapsedTime(void) { - // frequency represents the number of ticks per second - // used by the QueryPerformanceFrequency implementaiton - // and is represented by a 64-bit union type initially set to 0 - // and updated just once (hence use of static). - static LARGE_INTEGER frequency = {.QuadPart = 0} ; - - // system_time is a 64-bit union type used to represent the - // tick count returned by QueryPerformanceCounter - LARGE_INTEGER system_time ; - - // If this is the first time we are calling getProcessElapsedTime - // then record the ticks per second used by QueryPerformanceCounter - if (frequency.QuadPart == 0) { - QueryPerformanceFrequency(&frequency); - } - - // Get the tick count. - QueryPerformanceCounter(&system_time) ; - - // Return the tick count as a Time value. - // Using double to compute the intermediate value, because a 64-bit - // int would overflow when multiplied by TICK_RESOLUTION in about 81 days. - return fsecondsToTime((double)system_time.QuadPart / - (double)frequency.QuadPart) ; + return NSToTime(getMonotonicNSec()); } Time |