X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=System%2FTime.hsc;h=4db1d61efb6cf0ea20239069437759e517943020;hb=9fa9bc17072a58c0bae2cce4764d38677e96ac29;hp=b8d79b4260ac040d05509da04cdd8a7e3d9ae956;hpb=7f1f4e7a695c402ddd3a1dc2cc7114e649a78ebc;p=ghc-base.git diff --git a/System/Time.hsc b/System/Time.hsc index b8d79b4..4db1d61 100644 --- a/System/Time.hsc +++ b/System/Time.hsc @@ -1,8 +1,5 @@ -{-# OPTIONS -optc-DNON_POSIX_SOURCE #-} --- JRS 010117: we had to say NON_POSIX_SOURCE to get the resulting .hc --- to compile on sparc-solaris. Blargh. ----------------------------------------------------------------------------- --- +-- | -- Module : System.Time -- Copyright : (c) The University of Glasgow 2001 -- License : BSD-style (see the file libraries/core/LICENSE) @@ -11,7 +8,7 @@ -- Stability : provisional -- Portability : portable -- --- $Id: Time.hsc,v 1.1 2001/06/28 14:15:04 simonmar Exp $ +-- $Id: Time.hsc,v 1.12 2002/04/24 16:31:45 simonmar Exp $ -- -- The standard Time library. -- @@ -101,7 +98,7 @@ module System.Time ) where -#include "HsCore.h" +#include "HsBase.h" import Prelude @@ -208,9 +205,9 @@ noTimeDiff = TimeDiff 0 0 0 0 0 0 0 getClockTime = do allocaBytes (#const sizeof(struct timeval)) $ \ p_timeval -> do throwErrnoIfMinus1_ "getClockTime" $ gettimeofday p_timeval nullPtr - sec <- (#peek struct timeval,tv_sec) p_timeval :: IO CLong - usec <- (#peek struct timeval,tv_usec) p_timeval :: IO CLong - return (TOD (fromIntegral sec) ((fromIntegral usec) * 1000)) + sec <- (#peek struct timeval,tv_sec) p_timeval :: IO CTime + usec <- (#peek struct timeval,tv_usec) p_timeval :: IO CTime + return (TOD (fromIntegral sec) ((fromIntegral usec) * 1000000)) #elif HAVE_FTIME getClockTime = do @@ -218,7 +215,7 @@ getClockTime = do ftime p_timeb sec <- (#peek struct timeb,time) p_timeb :: IO CTime msec <- (#peek struct timeb,millitm) p_timeb :: IO CUShort - return (TOD (fromIntegral sec) (fromIntegral msec * 1000{-ToDo: correct???-})) + return (TOD (fromIntegral sec) (fromIntegral msec * 1000000000)) #else /* use POSIX time() */ getClockTime = do @@ -320,12 +317,11 @@ gmtoff x = (#peek struct tm,tm_gmtoff) x # define tzname _tzname # endif # ifndef mingw32_TARGET_OS -foreign label tzname :: Ptr (Ptr CChar) +foreign import ccall unsafe "&tzname" tzname :: Ptr (Ptr CChar) +foreign import ccall unsafe "timezone" timezone :: Ptr CLong # else -foreign import "ghcTimezone" unsafe timezone :: Ptr CLong -foreign import "ghcTzname" unsafe tzname :: Ptr (Ptr CChar) -# def inline long *ghcTimezone(void) { return &_timezone; } -# def inline char **ghcTzname(void) { return _tzname; } +foreign import ccall unsafe "__hscore_timezone" timezone :: Ptr CLong +foreign import ccall unsafe "__hscore_tzname" tzname :: Ptr (Ptr CChar) # endif zone x = do dst <- (#peek struct tm,tm_isdst) x @@ -336,13 +332,13 @@ zone x = do # endif /* ! HAVE_TZNAME */ -- Get the offset in secs from UTC, if (struct tm) doesn't supply it. */ -#if defined(mingw32_TARGET_OS) || defined(cygwin32_TARGET_OS) +#if defined(mingw32_TARGET_OS) #define timezone _timezone #endif # if HAVE_ALTZONE -foreign label altzone :: Ptr CTime -foreign label timezone :: Ptr CTime +foreign import ccall "&altzone" :: Ptr CTime +foreign import ccall "&timezone" :: Ptr CTime gmtoff x = do dst <- (#peek struct tm,tm_isdst) x tz <- if dst then peek altzone else peek timezone @@ -366,18 +362,40 @@ gmtoff x = do toCalendarTime :: ClockTime -> IO CalendarTime -toCalendarTime = clockToCalendarTime localtime False +#if HAVE_LOCALTIME_R +toCalendarTime = clockToCalendarTime_reentrant (throwAwayReturnPointer localtime_r) False +#else +toCalendarTime = clockToCalendarTime_static localtime False +#endif toUTCTime :: ClockTime -> CalendarTime -toUTCTime = unsafePerformIO . clockToCalendarTime gmtime True +#if HAVE_GMTIME_R +toUTCTime = unsafePerformIO . clockToCalendarTime_reentrant (throwAwayReturnPointer gmtime_r) True +#else +toUTCTime = unsafePerformIO . clockToCalendarTime_static gmtime True +#endif + +throwAwayReturnPointer :: (Ptr CTime -> Ptr CTm -> IO (Ptr CTm)) + -> (Ptr CTime -> Ptr CTm -> IO ( )) +throwAwayReturnPointer fun x y = fun x y >> return () --- ToDo: should be made thread safe, because localtime uses static storage, --- or use the localtime_r version. -clockToCalendarTime :: (Ptr CTime -> IO (Ptr CTm)) -> Bool -> ClockTime +clockToCalendarTime_static :: (Ptr CTime -> IO (Ptr CTm)) -> Bool -> ClockTime -> IO CalendarTime -clockToCalendarTime fun is_utc (TOD secs psec) = do +clockToCalendarTime_static fun is_utc (TOD secs psec) = do withObject (fromIntegral secs :: CTime) $ \ p_timer -> do p_tm <- fun p_timer -- can't fail, according to POSIX + clockToCalendarTime_aux is_utc p_tm psec + +clockToCalendarTime_reentrant :: (Ptr CTime -> Ptr CTm -> IO ()) -> Bool -> ClockTime + -> IO CalendarTime +clockToCalendarTime_reentrant fun is_utc (TOD secs psec) = do + withObject (fromIntegral secs :: CTime) $ \ p_timer -> do + allocaBytes (#const sizeof(struct tm)) $ \ p_tm -> do + fun p_timer p_tm + clockToCalendarTime_aux is_utc p_tm psec + +clockToCalendarTime_aux :: Bool -> Ptr CTm -> Integer -> IO CalendarTime +clockToCalendarTime_aux is_utc p_tm psec = do sec <- (#peek struct tm,tm_sec ) p_tm :: IO CInt min <- (#peek struct tm,tm_min ) p_tm :: IO CInt hour <- (#peek struct tm,tm_hour ) p_tm :: IO CInt @@ -451,7 +469,7 @@ toClockTime (CalendarTime year mon mday hour min sec psec -- gmtoff <- gmtoff p_tm let res = fromIntegral t - tz + fromIntegral gmtoff - return (TOD (fromIntegral res) 0) + return (TOD (fromIntegral res) psec) -- ----------------------------------------------------------------------------- -- Converting time values to strings. @@ -599,21 +617,29 @@ formatTimeDiff l fmt td@(TimeDiff year month day hour min sec _) type CTm = () -- struct tm -foreign import unsafe localtime :: Ptr CTime -> IO (Ptr CTm) -foreign import unsafe gmtime :: Ptr CTime -> IO (Ptr CTm) -foreign import unsafe mktime :: Ptr CTm -> IO CTime -foreign import unsafe time :: Ptr CTime -> IO CTime +#if HAVE_LOCALTIME_R +foreign import ccall unsafe localtime_r :: Ptr CTime -> Ptr CTm -> IO (Ptr CTm) +#else +foreign import ccall unsafe localtime :: Ptr CTime -> IO (Ptr CTm) +#endif +#if HAVE_GMTIME_R +foreign import ccall unsafe gmtime_r :: Ptr CTime -> Ptr CTm -> IO (Ptr CTm) +#else +foreign import ccall unsafe gmtime :: Ptr CTime -> IO (Ptr CTm) +#endif +foreign import ccall unsafe mktime :: Ptr CTm -> IO CTime +foreign import ccall unsafe time :: Ptr CTime -> IO CTime #if HAVE_GETTIMEOFDAY type CTimeVal = () -foreign import unsafe gettimeofday :: Ptr CTimeVal -> Ptr () -> IO CInt +foreign import ccall unsafe gettimeofday :: Ptr CTimeVal -> Ptr () -> IO CInt #endif #if HAVE_FTIME type CTimeB = () #ifndef mingw32_TARGET_OS -foreign import unsafe ftime :: Ptr CTimeB -> IO CInt +foreign import ccall unsafe ftime :: Ptr CTimeB -> IO CInt #else -foreign import unsafe ftime :: Ptr CTimeB -> IO () +foreign import ccall unsafe ftime :: Ptr CTimeB -> IO () #endif #endif