clock-0.2.0.0/0000755000000000000000000000000011502213224011120 5ustar0000000000000000clock-0.2.0.0/clock.cabal0000644000000000000000000000366011502213224013204 0ustar0000000000000000Name: clock Version: 0.2.0.0 License: BSD3 License-file: COPYING Copyright: (c) Cetin Sert 2009-2010, (c) Eugene Kirpichov 2010 Author: Cetin Sert , Eugene Kirpichov Maintainer: Cetin Sert Homepage: http://corsis.sourceforge.net/index.php/Haskell/Clock Category: System Synopsis: High-resolution clock and timer functions: realtime, monotonic, cputime, etc. Description: A package for convenient access to high-resolution clock and timer functions of different operating systems. . It is planned to consist of two layers. The lower layer will provide direct access to OS-specific clock and timer functions like clock_gettime of Posix or GetTickCount of Windows and its upper layer shall then provide a common API for all supported systems. Currently only the lower level is being developed. . . POSIX reference: IEEE Std 1003.1-2008 , . WINDOWS reference: ... . For more information, see: Stability: Experimental Build-type: Simple Build-depends: base >= 2 && < 5 Exposed-Modules: System.Posix.Clock Extensions: ForeignFunctionInterface C-sources: csec/clock.c Include-dirs: csec Install-includes: clock.h ghc-options: -O2 -Wall -fglasgow-exts clock-0.2.0.0/COPYING0000644000000000000000000000276411502213224012164 0ustar0000000000000000Copyright (c) 2010, Eugene Kirpichov Copyright (c) 2009-2010, Cetin Sert All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names of contributors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. clock-0.2.0.0/Setup.hs0000644000000000000000000000005611502213224012555 0ustar0000000000000000import Distribution.Simple main = defaultMain clock-0.2.0.0/csec/0000755000000000000000000000000011502213224012035 5ustar0000000000000000clock-0.2.0.0/csec/clock.c0000644000000000000000000000727711502213224013311 0ustar0000000000000000#include "clock.h" #ifdef _WIN32 // *********************** // ******** WIN32 ******** // *********************** #include #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) #define U64(x) x##Ui64 #else #define U64(x) x##ULL #endif #define DELTA_EPOCH_IN_100NS U64(116444736000000000) long ticks_to_nanos(LONGLONG subsecond_time, LONGLONG frequency) { return (long)((1e9 * subsecond_time) / frequency); } ULONGLONG to_quad_100ns(FILETIME ft) { ULARGE_INTEGER li; li.LowPart = ft.dwLowDateTime; li.HighPart = ft.dwHighDateTime; return li.QuadPart; } void to_timespec_from_100ns(ULONGLONG t_100ns, long *t) { t[0] = (long)(t_100ns / 10000000UL); t[1] = 100*(long)(t_100ns % 10000000UL); } void clock_readtime_monotonic(long* t) { LARGE_INTEGER time; LARGE_INTEGER frequency; QueryPerformanceCounter(&time); QueryPerformanceFrequency(&frequency); // seconds t[0] = time.QuadPart / frequency.QuadPart; // nanos = t[1] = ticks_to_nanos(time.QuadPart % frequency.QuadPart, frequency.QuadPart); } void clock_readtime_realtime(long* t) { FILETIME ft; ULONGLONG tmp; GetSystemTimeAsFileTime(&ft); tmp = to_quad_100ns(ft); tmp -= DELTA_EPOCH_IN_100NS; to_timespec_from_100ns(tmp, t); } void clock_readtime_processtime(long* t) { FILETIME creation_time, exit_time, kernel_time, user_time; ULONGLONG time; GetProcessTimes(GetCurrentProcess(), &creation_time, &exit_time, &kernel_time, &user_time); // Both kernel and user, acc. to http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_117 time = to_quad_100ns(user_time) + to_quad_100ns(kernel_time); to_timespec_from_100ns(time, t); } void clock_readtime_threadtime(long* t) { FILETIME creation_time, exit_time, kernel_time, user_time; ULONGLONG time; GetThreadTimes(GetCurrentThread(), &creation_time, &exit_time, &kernel_time, &user_time); // Both kernel and user, acc. to http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_117 time = to_quad_100ns(user_time) + to_quad_100ns(kernel_time); to_timespec_from_100ns(time, t); } void clock_readres_monotonic(long* t) { LARGE_INTEGER frequency; QueryPerformanceFrequency(&frequency); ULONGLONG resolution = U64(1000000000)/frequency.QuadPart; t[0] = resolution / U64(1000000000); t[1] = resolution % U64(1000000000); } void clock_readres_realtime(long* t) { t[0] = 0; t[1] = 100; } void clock_readres_processtime(long* t) { t[0] = 0; t[1] = 100; } void clock_readres_threadtime(long* t) { t[0] = 0; t[1] = 100; } #else // Not _WIN32 // *********************** // ******** POSIX ******** // *********************** #include void time_(clockid_t clock, long* t) { clock_gettime(clock, (struct timespec*)t); /* struct timespec a; clock_gettime(clock, &a); t[0] = a.tv_sec ; t[1] = a.tv_nsec;*/ } void clock_readtime_monotonic(long* t) { time_(CLOCK_MONOTONIC, t); } void clock_readtime_realtime(long* t) { time_(CLOCK_REALTIME, t); } void clock_readtime_processtime(long* t) { time_(CLOCK_PROCESS_CPUTIME_ID , t); } void clock_readtime_threadtime(long* t) { time_(CLOCK_THREAD_CPUTIME_ID , t); } void res_(clockid_t clock, long* t) { clock_getres(clock, (struct timespec*)t); /* struct timespec a; clock_getres(clock, &a); t[0] = a.tv_sec ; t[1] = a.tv_nsec;*/ } void clock_readres_monotonic(long* t) { res_(CLOCK_MONOTONIC, t); } void clock_readres_realtime(long* t) { res_(CLOCK_REALTIME, t); } void clock_readres_processtime(long* t) { res_(CLOCK_PROCESS_CPUTIME_ID , t); } void clock_readres_threadtime(long* t) { res_(CLOCK_THREAD_CPUTIME_ID , t); } #endif clock-0.2.0.0/csec/clock.h0000644000000000000000000000050111502213224013275 0ustar0000000000000000void clock_readtime_monotonic(long* t); void clock_readtime_realtime(long* t); void clock_readtime_processtime(long* t); void clock_readtime_threadtime(long* t); void clock_readres_monotonic(long* t); void clock_readres_realtime(long* t); void clock_readres_processtime(long* t); void clock_readres_threadtime(long* t); clock-0.2.0.0/System/0000755000000000000000000000000011502213224012404 5ustar0000000000000000clock-0.2.0.0/System/Posix/0000755000000000000000000000000011502213224013506 5ustar0000000000000000clock-0.2.0.0/System/Posix/Clock.hs0000644000000000000000000001124211502213224015075 0ustar0000000000000000-- | High-resolution, realtime clock and timer functions for Posix -- systems. This module is being developed according to IEEE Std -- 1003.1-2008: , -- module System.Posix.Clock ( Clock (Monotonic, Realtime, ProcessCPUTime, ThreadCPUTime), TimeSpec (TimeSpec), getTime, getRes, sec, nsec ) where import Foreign.Ptr --import System.IO.Unsafe import Foreign.Storable import Foreign.Marshal.Alloc -- | Clock types. -- A clock may be system-wide (that is, visible to all processes) -- or per-process (measuring time that is meaningful only within -- a process). All implementations shall support CLOCK_REALTIME. data Clock = Monotonic -- ^ The identifier for the system-wide monotonic clock, which is defined as a clock measuring real time, whose value cannot be set via clock_settime and which cannot have negative clock jumps. The maximum possible clock jump shall be implementation-defined. For this clock, the value returned by 'getTime' represents the amount of time (in seconds and nanoseconds) since an unspecified point in the past (for example, system start-up time, or the Epoch). This point does not change after system start-up time. Note that the absolute value of the monotonic clock is meaningless (because its origin is arbitrary), and thus there is no need to set it. Furthermore, realtime applications can rely on the fact that the value of this clock is never set. | Realtime -- ^ The identifier of the system-wide clock measuring real time. For this clock, the value returned by getTime represents the amount of time (in seconds and nanoseconds) since the Epoch. | ProcessCPUTime -- ^ The identifier of the CPU-time clock associated with the calling process. For this clock, the value returned by getTime represents the amount of execution time of the current process. | ThreadCPUTime -- ^ The identifier of the CPU-time clock associated with the calling OS thread. For this clock, the value returned by getTime represents the amount of execution time of the current OS thread. -- | TimeSpec structure data TimeSpec = TimeSpec { sec :: Int, -- ^ Seconds nsec :: Int -- ^ Nanoseconds } deriving (Show, Read, Eq) instance Storable TimeSpec where sizeOf _ = sizeOf (0 :: Int) * 2 alignment _ = 1 poke t v = do let i :: Ptr Int = castPtr t (i ≣← 0) $ sec v (i ≣← 1) $ nsec v peek t = do let i :: Ptr Int = castPtr t s ← (i ≣→ 0) n ← (i ≣→ 1) return $ TimeSpec s n instance Ord TimeSpec where compare (TimeSpec xs xn) (TimeSpec ys yn) = if xs > ys then GT else if xs < ys then LT else if xn > yn then GT else if xn < yn then LT else EQ -- | The 'getTime' function shall return the current value for the -- specified clock. getTime :: Clock → IO TimeSpec getTime = call . time -- | The 'getRes' function shall return the resolution of any clock. -- Clock resolutions are implementation-defined and cannot be set -- by a process. getRes :: Clock → IO TimeSpec getRes = call . res --------------------------------------------- -- Reader function type ReaderFunc = Ptr TimeSpec → IO () -- Readers foreign import ccall clock_readtime_monotonic :: ReaderFunc foreign import ccall clock_readtime_realtime :: ReaderFunc foreign import ccall clock_readtime_processtime :: ReaderFunc foreign import ccall clock_readtime_threadtime :: ReaderFunc foreign import ccall clock_readres_monotonic :: ReaderFunc foreign import ccall clock_readres_realtime :: ReaderFunc foreign import ccall clock_readres_processtime :: ReaderFunc foreign import ccall clock_readres_threadtime :: ReaderFunc -- Clock-to-time reading time :: Clock → ReaderFunc time Monotonic = clock_readtime_monotonic time Realtime = clock_readtime_realtime time ProcessCPUTime = clock_readtime_processtime time ThreadCPUTime = clock_readtime_threadtime -- Clock-to-res reading res :: Clock → ReaderFunc res Monotonic = clock_readres_monotonic res Realtime = clock_readres_realtime res ProcessCPUTime = clock_readres_processtime res ThreadCPUTime = clock_readres_threadtime -- Marshalling call :: ReaderFunc → IO TimeSpec call read_ = do x ← (↑) read_ x t ← (x ⋅) (x ⊠) return t -- Allocation and pointer operations (↑) :: Storable a ⇒ IO (Ptr a) (↑) = malloc (⋅) :: Storable a ⇒ Ptr a → IO a (⋅) = peek (≣→) :: Storable a ⇒ Ptr a → Int → IO a (≣→) = peekElemOff (≣←) :: Storable a ⇒ Ptr a → Int → a → IO () (≣←) = pokeElemOff (⊠) :: Ptr a → IO () (⊠) = Foreign.Marshal.Alloc.free