Skip to content

Commit 0544cd0

Browse files
committed
Replace the unsafe getmodtime with the one from the posix package
We don't need the 2X faster but unsafe getmodtime anymore since GetModificationTime is not called O(N) anymore, but only O(FOI) times, where N is the number of known targets and FOI is the number of files of interest
1 parent ef0e9fd commit 0544cd0

File tree

3 files changed

+14
-37
lines changed

3 files changed

+14
-37
lines changed

ghcide/ghcide.cabal

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,6 @@ library
108108
else
109109
build-depends:
110110
unix
111-
c-sources:
112-
cbits/getmodtime.c
113111

114112
default-extensions:
115113
ApplicativeDo

ghcide/src/Development/IDE/Core/FileStore.hs

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,17 @@ import Data.Maybe
3737
import qualified Data.Rope.UTF16 as Rope
3838
import qualified Data.Text as T
3939
import Data.Time
40+
import Data.Time.Clock.POSIX
4041
import Development.IDE.Core.OfInterest (OfInterestVar (..),
4142
getFilesOfInterest)
4243
import Development.IDE.Core.RuleTypes
4344
import Development.IDE.Core.Shake
4445
import Development.IDE.GHC.Orphans ()
46+
import Development.IDE.Graph
4547
import Development.IDE.Import.DependencyInformation
4648
import Development.IDE.Types.Diagnostics
4749
import Development.IDE.Types.Location
4850
import Development.IDE.Types.Options
49-
import Development.IDE.Graph
5051
import HieDb.Create (deleteMissingRealFiles)
5152
import Ide.Plugin.Config (CheckParents (..))
5253
import System.IO.Error
@@ -62,6 +63,7 @@ import Foreign.Marshal (alloca)
6263
import Foreign.Ptr
6364
import Foreign.Storable
6465
import qualified System.Posix.Error as Posix
66+
import System.Posix.Files (getFileStatus, modificationTimeHiRes)
6567
#endif
6668

6769
import qualified Development.IDE.Types.Logger as L
@@ -126,7 +128,7 @@ getModificationTimeImpl :: VFSHandle
126128
(Maybe BS.ByteString, ([FileDiagnostic], Maybe FileVersion))
127129
getModificationTimeImpl vfs isWatched missingFileDiags file = do
128130
let file' = fromNormalizedFilePath file
129-
let wrap time@(l,s) = (Just $ LBS.toStrict $ B.encode time, ([], Just $ ModificationTime l s))
131+
let wrap time = (Just $ LBS.toStrict $ B.encode $ toRational time, ([], Just $ ModificationTime time))
130132
mbVirtual <- liftIO $ getVirtualFile vfs $ filePathToUri' file
131133
case mbVirtual of
132134
Just (virtualFileVersion -> ver) -> do
@@ -192,38 +194,17 @@ resetFileStore ideState changes = mask $ \_ ->
192194
-- We might also want to try speeding this up on Windows at some point.
193195
-- TODO leverage DidChangeWatchedFile lsp notifications on clients that
194196
-- support them, as done for GetFileExists
195-
getModTime :: FilePath -> IO (Int64, Int64)
197+
getModTime :: FilePath -> IO POSIXTime
196198
getModTime f =
197199
#ifdef mingw32_HOST_OS
198-
do time <- Dir.getModificationTime f
199-
let !day = fromInteger $ toModifiedJulianDay $ utctDay time
200-
!dayTime = fromInteger $ diffTimeToPicoseconds $ utctDayTime time
201-
pure (day, dayTime)
200+
Dir.getModificationTime f
202201
#else
203-
withCString f $ \f' ->
204-
alloca $ \secPtr ->
205-
alloca $ \nsecPtr -> do
206-
Posix.throwErrnoPathIfMinus1Retry_ "getmodtime" f $ c_getModTime f' secPtr nsecPtr
207-
CTime sec <- peek secPtr
208-
CLong nsec <- peek nsecPtr
209-
pure (sec, nsec)
210-
211-
-- Sadly even unix’s getFileStatus + modificationTimeHiRes is still about twice as slow
212-
-- as doing the FFI call ourselves :(.
213-
foreign import ccall "getmodtime" c_getModTime :: CString -> Ptr CTime -> Ptr CLong -> IO Int
202+
modificationTimeHiRes <$> getFileStatus f
214203
#endif
215204

216205
modificationTime :: FileVersion -> Maybe UTCTime
217-
modificationTime VFSVersion{} = Nothing
218-
modificationTime (ModificationTime large small) = Just $ internalTimeToUTCTime large small
219-
220-
internalTimeToUTCTime :: Int64 -> Int64 -> UTCTime
221-
internalTimeToUTCTime large small =
222-
#ifdef mingw32_HOST_OS
223-
UTCTime (ModifiedJulianDay $ fromIntegral large) (picosecondsToDiffTime $ fromIntegral small)
224-
#else
225-
systemToUTCTime $ MkSystemTime large (fromIntegral small)
226-
#endif
206+
modificationTime VFSVersion{} = Nothing
207+
modificationTime (ModificationTime posix) = Just $ posixSecondsToUTCTime posix
227208

228209
getFileContentsRule :: VFSHandle -> Rules ()
229210
getFileContentsRule vfs = define $ \GetFileContents file -> getFileContentsImpl vfs file
@@ -260,8 +241,8 @@ getFileContents f = do
260241
liftIO $ case foi of
261242
IsFOI Modified{} -> getCurrentTime
262243
_ -> do
263-
(large,small) <- getModTime $ fromNormalizedFilePath f
264-
pure $ internalTimeToUTCTime large small
244+
posix <- getModTime $ fromNormalizedFilePath f
245+
pure $ posixSecondsToUTCTime posix
265246
return (modTime, txt)
266247

267248
fileStoreRules :: VFSHandle -> (NormalizedFilePath -> Action Bool) -> Rules ()

ghcide/src/Development/IDE/Core/RuleTypes.hs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,15 @@ import Data.Aeson.Types (Value)
2121
import Data.Binary
2222
import Data.Hashable
2323
import qualified Data.Map as M
24+
import Data.Time.Clock.POSIX
2425
import Data.Typeable
2526
import Development.IDE.GHC.Compat hiding
2627
(HieFileResult)
2728
import Development.IDE.GHC.Util
29+
import Development.IDE.Graph
2830
import Development.IDE.Import.DependencyInformation
2931
import Development.IDE.Types.HscEnvEq (HscEnvEq)
3032
import Development.IDE.Types.KnownTargets
31-
import Development.IDE.Graph
3233
import GHC.Generics (Generic)
3334

3435
import HscTypes (HomeModInfo,
@@ -39,7 +40,6 @@ import HscTypes (HomeModInfo,
3940
import qualified Data.Binary as B
4041
import Data.ByteString (ByteString)
4142
import qualified Data.ByteString.Lazy as LBS
42-
import Data.Int (Int64)
4343
import Data.Text (Text)
4444
import Data.Time
4545
import Development.IDE.Import.FindImports (ArtifactsLocation)
@@ -295,9 +295,7 @@ type instance RuleResult GetModificationTime = FileVersion
295295

296296
data FileVersion
297297
= VFSVersion !Int
298-
| ModificationTime
299-
!Int64 -- ^ Large unit (platform dependent, do not make assumptions)
300-
!Int64 -- ^ Small unit (platform dependent, do not make assumptions)
298+
| ModificationTime !POSIXTime
301299
deriving (Show, Generic)
302300

303301
instance NFData FileVersion

0 commit comments

Comments
 (0)