From af27ab5c3bb6e0ef5d4f618a4f1b99e72060b424 Mon Sep 17 00:00:00 2001 From: ken Date: Tue, 24 Jul 2001 04:39:32 +0000 Subject: [PATCH] [project @ 2001-07-24 04:39:31 by ken] Make the Time module thread-safe by calling the reentrant functions gmtime_r and localtime_r instead of gmtime and localtime wherever they are available. (This is necessary to make Time work at all on our Alpha machine -- perhaps GHC tickles the reentrancy of the C library or something?) --- configure.in | 2 +- ghc/lib/std/Time.hsc | 54 ++++++++++++++++++++++++++++++++++++++++---------- mk/config.h.in | 6 ++++++ mk/config.mk.in | 4 ++-- 4 files changed, 52 insertions(+), 14 deletions(-) diff --git a/configure.in b/configure.in index a35ad4a..cafba55 100644 --- a/configure.in +++ b/configure.in @@ -836,7 +836,7 @@ AC_CHECK_FUNCS(pclose _pclose ) dnl ** check for specific library functions that we are interested in -AC_CHECK_FUNCS(access ftime getclock getpagesize getrusage gettimeofday mktime mprotect readlink setitimer stat symlink sysconf timelocal times vadvise vfork) +AC_CHECK_FUNCS(access ftime getclock getpagesize getrusage gettimeofday mktime mprotect readlink setitimer stat symlink sysconf timelocal times vadvise vfork localtime_r gmtime_r) dnl ** check whether this machine has gmp3 installed AC_CHECK_LIB(gmp, __gmpz_fdiv_qr, HaveLibGmp=YES; LibGmp=gmp, diff --git a/ghc/lib/std/Time.hsc b/ghc/lib/std/Time.hsc index 0e77f37..2cbf318 100644 --- a/ghc/lib/std/Time.hsc +++ b/ghc/lib/std/Time.hsc @@ -3,7 +3,7 @@ -- to compile on sparc-solaris. Blargh. -- ----------------------------------------------------------------------------- --- $Id: Time.hsc,v 1.17 2001/07/24 04:35:36 ken Exp $ +-- $Id: Time.hsc,v 1.18 2001/07/24 04:39:31 ken Exp $ -- -- (c) The University of Glasgow, 1995-2001 -- @@ -367,18 +367,42 @@ 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 --- 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 +throwAwayReturnPointer :: (Ptr CTime -> Ptr CTm -> IO (Ptr CTm)) + -> (Ptr CTime -> Ptr CTm -> IO ( )) +throwAwayReturnPointer fun x y = fun x y >> return () + +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 + putStrLn ("clockToCalendarTime: TOD " ++ show secs ++ " " ++ show psec) withObject (fromIntegral secs :: CTime) $ \ p_timer -> do + case p_timer of Ptr addr -> putStrLn ("const time_t * = " ++ show (I## (addr2Int## addr))) 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 @@ -593,10 +617,18 @@ 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 unsafe localtime_r :: Ptr CTime -> Ptr CTm -> IO (Ptr CTm) +#else +foreign import unsafe localtime :: Ptr CTime -> IO (Ptr CTm) +#endif +#if HAVE_GMTIME_R +foreign import unsafe gmtime_r :: Ptr CTime -> Ptr CTm -> IO (Ptr CTm) +#else +foreign import unsafe gmtime :: Ptr CTime -> IO (Ptr CTm) +#endif +foreign import unsafe mktime :: Ptr CTm -> IO CTime +foreign import unsafe time :: Ptr CTime -> IO CTime #if HAVE_GETTIMEOFDAY type CTimeVal = () diff --git a/mk/config.h.in b/mk/config.h.in index d81ca78..f6567d8 100644 --- a/mk/config.h.in +++ b/mk/config.h.in @@ -665,6 +665,12 @@ /* Define if you have the gettimeofday function. */ #undef HAVE_GETTIMEOFDAY +/* Define if you have the gmtime_r function. */ +#undef HAVE_GMTIME_R + +/* Define if you have the localtime_r function. */ +#undef HAVE_LOCALTIME_R + /* Define if you have the macsystem function. */ #undef HAVE_MACSYSTEM diff --git a/mk/config.mk.in b/mk/config.mk.in index 40f5fd1..a0eb257 100644 --- a/mk/config.mk.in +++ b/mk/config.mk.in @@ -185,8 +185,8 @@ GhcUnregisterised=NO # (as well as a C backend) # # Target platforms supported: -# i386, alpha & sparc -ifneq "$(findstring $(HostArch_CPP), i386 alpha sparc)" "" +# i386 & sparc +ifneq "$(findstring $(HostArch_CPP), i386 sparc)" "" GhcWithNativeCodeGen=YES else GhcWithNativeCodeGen=NO -- 1.7.10.4