on master help sign in
Reduce usage of -Wno-orphans
commit68cfc3f9be91d15457aed0a9b42f53cbddeb73ef authorHarendra Kumar <harendra@composewell.com> dateSun 28 Jun 2020, 22:50 (6 years ago) parent70fb992
7 files changed+174−133
src/Streamly.hs−4 src/Streamly/Internal/Data/Time/Clock.hsc+2−55 src/Streamly/Internal/Data/Time/TimeSpec.hsc+156 src/Streamly/Internal/Data/Time/Units.hs+4−70 src/Streamly/Internal/Data/Time/config-clock.h+11 src/Streamly/Prelude.hs−4 streamly.cabal+1
src/Streamly.hs−4
@@ -55,10 +55,6 @@
5555{-# LANGUAGE FlexibleContexts #-}
5656{-# LANGUAGE MultiParamTypeClasses #-}
5757
58−#if __GLASGOW_HASKELL__ >= 800
59−{-# OPTIONS_GHC -Wno-orphans #-}
60−#endif
61−
6258#include "inline.hs"
6359
6460module Streamly
src/Streamly/Internal/Data/Time/Clock.hsc+2−55
@@ -5,7 +5,6 @@
55
66#if __GLASGOW_HASKELL__ >= 800
77{-# OPTIONS_GHC -Wno-identities #-}
8−{-# OPTIONS_GHC -Wno-orphans #-}
98{-# OPTIONS_GHC -fno-warn-unused-imports #-}
109#endif
1110
@@ -13,6 +12,8 @@
1312#include "config.h"
1413#endif
1514
15+#include "config-clock.h"
16+
1617-- |
1718-- Module : Streamly.Internal.Data.Time.Clock
1819-- Copyright : (c) 2019 Harendra Kumar
@@ -25,18 +26,6 @@
2526
2627-- A majority of the code below has been stolen from the "clock" package.
2728
28−#if __GHCJS__
29−#define HS_CLOCK_GHCJS 1
30−#elif defined(_WIN32)
31−#define HS_CLOCK_WINDOWS 1
32−#elif (defined (HAVE_TIME_H) && defined(HAVE_CLOCK_GETTIME))
33−#define HS_CLOCK_POSIX 1
34−#elif __APPLE__
35−#define HS_CLOCK_OSX 1
36−#else
37−#error "Time/Clock functionality not implemented for this system"
38−#endif
39−
4029module Streamly.Internal.Data.Time.Clock
4130 (
4231 -- * get time from the system clock
@@ -215,48 +204,6 @@ clockToJSClockId Realtime = 0
215204-- Clock time
216205-------------------------------------------------------------------------------
217206
218−#if __GLASGOW_HASKELL__ < 800
219−#let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__)
220−#endif
221−
222−#ifdef HS_CLOCK_GHCJS
223−instance Storable TimeSpec where
224− sizeOf _ = 8
225− alignment _ = 4
226− peek p = do
227− CTime s <- peekByteOff p 0
228− CLong ns <- peekByteOff p 4
229− return (TimeSpec (fromIntegral s) (fromIntegral ns))
230− poke p (TimeSpec s ns) = do
231− pokeByteOff p 0 ((fromIntegral s) :: CTime)
232− pokeByteOff p 4 ((fromIntegral ns) :: CLong)
233−
234−#elif HS_CLOCK_WINDOWS
235−instance Storable TimeSpec where
236− sizeOf _ = sizeOf (undefined :: Int64) * 2
237− alignment _ = alignment (undefined :: Int64)
238− peek ptr = do
239− s <- peekByteOff ptr 0
240− ns <- peekByteOff ptr (sizeOf (undefined :: Int64))
241− return (TimeSpec s ns)
242− poke ptr ts = do
243− pokeByteOff ptr 0 (sec ts)
244− pokeByteOff ptr (sizeOf (undefined :: Int64)) (nsec ts)
245−#else
246−instance Storable TimeSpec where
247− sizeOf _ = #{size struct timespec}
248− alignment _ = #{alignment struct timespec}
249− peek ptr = do
250− s :: #{type time_t} <- #{peek struct timespec, tv_sec} ptr
251− ns :: #{type long} <- #{peek struct timespec, tv_nsec} ptr
252− return $ TimeSpec (fromIntegral s) (fromIntegral ns)
253− poke ptr ts = do
254− let s :: #{type time_t} = fromIntegral $ sec ts
255− ns :: #{type long} = fromIntegral $ nsec ts
256− #{poke struct timespec, tv_sec} ptr (s)
257− #{poke struct timespec, tv_nsec} ptr (ns)
258−#endif
259−
260207{-# INLINE getTimeWith #-}
261208getTimeWith :: (Ptr TimeSpec -> IO ()) -> IO AbsTime
262209getTimeWith f = do
src/Streamly/Internal/Data/Time/TimeSpec.hscnew file+156
@@ -0,0 +1,156 @@
1+{-# LANGUAGE CPP #-}
2+{-# LANGUAGE ScopedTypeVariables #-}
3+
4+#if __GLASGOW_HASKELL__ >= 800
5+{-# OPTIONS_GHC -Wno-identities #-}
6+#endif
7+
8+#ifndef __GHCJS__
9+#include "config.h"
10+#endif
11+
12+#include "config-clock.h"
13+
14+-- |
15+-- Module : Streamly.Internal.Data.Time.TimeSpec
16+-- Copyright : (c) 2019 Composewell Technologies
17+-- License : BSD3
18+-- Maintainer : streamly@composewell.com
19+-- Stability : experimental
20+-- Portability : GHC
21+
22+module Streamly.Internal.Data.Time.TimeSpec
23+ (
24+ TimeSpec(..)
25+ )
26+where
27+
28+import Data.Int (Int64)
29+import Foreign.Storable (Storable(..), peek)
30+
31+#ifdef HS_CLOCK_GHCJS
32+import Foreign.C (CTime(..), CLong(..))
33+#endif
34+
35+-------------------------------------------------------------------------------
36+-- Some constants
37+-------------------------------------------------------------------------------
38+
39+{-# INLINE tenPower9 #-}
40+tenPower9 :: Int64
41+tenPower9 = 1000000000
42+
43+-------------------------------------------------------------------------------
44+-- TimeSpec representation
45+-------------------------------------------------------------------------------
46+
47+-- A structure storing seconds and nanoseconds as 'Int64' is the simplest and
48+-- fastest way to store practically large quantities of time with efficient
49+-- arithmetic operations. If we store nanoseconds using 'Integer' it can store
50+-- practically unbounded quantities but it may not be as efficient to
51+-- manipulate in performance critical applications. XXX need to measure the
52+-- performance.
53+--
54+-- | Data type to represent practically large quantities of time efficiently.
55+-- It can represent time up to ~292 billion years at nanosecond resolution.
56+data TimeSpec = TimeSpec
57+ { sec :: {-# UNPACK #-} !Int64 -- ^ seconds
58+ , nsec :: {-# UNPACK #-} !Int64 -- ^ nanoseconds
59+ } deriving (Eq, Read, Show)
60+
61+-- We assume that nsec is always less than 10^9. When TimeSpec is negative then
62+-- both sec and nsec are negative.
63+instance Ord TimeSpec where
64+ compare (TimeSpec s1 ns1) (TimeSpec s2 ns2) =
65+ if s1 == s2
66+ then compare ns1 ns2
67+ else compare s1 s2
68+
69+-- make sure nsec is less than 10^9
70+{-# INLINE addWithOverflow #-}
71+addWithOverflow :: TimeSpec -> TimeSpec -> TimeSpec
72+addWithOverflow (TimeSpec s1 ns1) (TimeSpec s2 ns2) =
73+ let nsum = ns1 + ns2
74+ (s', ns) = if nsum > tenPower9 || nsum < negate tenPower9
75+ then nsum `divMod` tenPower9
76+ else (0, nsum)
77+ in TimeSpec (s1 + s2 + s') ns
78+
79+-- make sure both sec and nsec have the same sign
80+{-# INLINE adjustSign #-}
81+adjustSign :: TimeSpec -> TimeSpec
82+adjustSign t@(TimeSpec s ns)
83+ | s > 0 && ns < 0 = TimeSpec (s - 1) (ns + tenPower9)
84+ | s < 0 && ns > 0 = TimeSpec (s + 1) (ns - tenPower9)
85+ | otherwise = t
86+
87+{-# INLINE timeSpecToInteger #-}
88+timeSpecToInteger :: TimeSpec -> Integer
89+timeSpecToInteger (TimeSpec s ns) = toInteger $ s * tenPower9 + ns
90+
91+instance Num TimeSpec where
92+ {-# INLINE (+) #-}
93+ t1 + t2 = adjustSign (addWithOverflow t1 t2)
94+
95+ -- XXX will this be more optimal if imlemented without "negate"?
96+ {-# INLINE (-) #-}
97+ t1 - t2 = t1 + negate t2
98+ t1 * t2 = fromInteger $ timeSpecToInteger t1 * timeSpecToInteger t2
99+
100+ {-# INLINE negate #-}
101+ negate (TimeSpec s ns) = TimeSpec (negate s) (negate ns)
102+ {-# INLINE abs #-}
103+ abs (TimeSpec s ns) = TimeSpec (abs s) (abs ns)
104+ {-# INLINE signum #-}
105+ signum (TimeSpec s ns) | s == 0 = TimeSpec (signum ns) 0
106+ | otherwise = TimeSpec (signum s) 0
107+ -- This is fromNanoSecond64 Integer
108+ {-# INLINE fromInteger #-}
109+ fromInteger nanosec = TimeSpec (fromInteger s) (fromInteger ns)
110+ where (s, ns) = nanosec `divMod` toInteger tenPower9
111+
112+#if HS_CLOCK_POSIX
113+#include <time.h>
114+#endif
115+
116+#if __GLASGOW_HASKELL__ < 800
117+#let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__)
118+#endif
119+
120+#ifdef HS_CLOCK_GHCJS
121+instance Storable TimeSpec where
122+ sizeOf _ = 8
123+ alignment _ = 4
124+ peek p = do
125+ CTime s <- peekByteOff p 0
126+ CLong ns <- peekByteOff p 4
127+ return (TimeSpec (fromIntegral s) (fromIntegral ns))
128+ poke p (TimeSpec s ns) = do
129+ pokeByteOff p 0 ((fromIntegral s) :: CTime)
130+ pokeByteOff p 4 ((fromIntegral ns) :: CLong)
131+
132+#elif HS_CLOCK_WINDOWS
133+instance Storable TimeSpec where
134+ sizeOf _ = sizeOf (undefined :: Int64) * 2
135+ alignment _ = alignment (undefined :: Int64)
136+ peek ptr = do
137+ s <- peekByteOff ptr 0
138+ ns <- peekByteOff ptr (sizeOf (undefined :: Int64))
139+ return (TimeSpec s ns)
140+ poke ptr ts = do
141+ pokeByteOff ptr 0 (sec ts)
142+ pokeByteOff ptr (sizeOf (undefined :: Int64)) (nsec ts)
143+#else
144+instance Storable TimeSpec where
145+ sizeOf _ = #{size struct timespec}
146+ alignment _ = #{alignment struct timespec}
147+ peek ptr = do
148+ s :: #{type time_t} <- #{peek struct timespec, tv_sec} ptr
149+ ns :: #{type long} <- #{peek struct timespec, tv_nsec} ptr
150+ return $ TimeSpec (fromIntegral s) (fromIntegral ns)
151+ poke ptr ts = do
152+ let s :: #{type time_t} = fromIntegral $ sec ts
153+ ns :: #{type long} = fromIntegral $ nsec ts
154+ #{poke struct timespec, tv_sec} ptr (s)
155+ #{poke struct timespec, tv_nsec} ptr (ns)
156+#endif
src/Streamly/Internal/Data/Time/Units.hs+4−70
@@ -49,9 +49,11 @@ module Streamly.Internal.Data.Time.Units
4949 )
5050where
5151
52−import Data.Int
5352import Text.Printf (printf)
5453
54+import Data.Int
55+import Streamly.Internal.Data.Time.TimeSpec
56+
5557-------------------------------------------------------------------------------
5658-- Some constants
5759-------------------------------------------------------------------------------
@@ -68,6 +70,7 @@ tenPower6 = 1000000
6870tenPower9 :: Int64
6971tenPower9 = 1000000000
7072
73+
7174-------------------------------------------------------------------------------
7275-- Time Unit Representations
7376-------------------------------------------------------------------------------
@@ -137,75 +140,6 @@ newtype MilliSecond64 = MilliSecond64 Int64
137140-- Fractional Units
138141-------------------------------------------------------------------------------
139142
140−-------------------------------------------------------------------------------
141−-- TimeSpec representation
142−-------------------------------------------------------------------------------
143−
144−-- A structure storing seconds and nanoseconds as 'Int64' is the simplest and
145−-- fastest way to store practically large quantities of time with efficient
146−-- arithmetic operations. If we store nanoseconds using 'Integer' it can store
147−-- practically unbounded quantities but it may not be as efficient to
148−-- manipulate in performance critical applications. XXX need to measure the
149−-- performance.
150−--
151−-- | Data type to represent practically large quantities of time efficiently.
152−-- It can represent time up to ~292 billion years at nanosecond resolution.
153−data TimeSpec = TimeSpec
154− { sec :: {-# UNPACK #-} !Int64 -- ^ seconds
155− , nsec :: {-# UNPACK #-} !Int64 -- ^ nanoseconds
156− } deriving (Eq, Read, Show)
157−
158−-- We assume that nsec is always less than 10^9. When TimeSpec is negative then
159−-- both sec and nsec are negative.
160−instance Ord TimeSpec where
161− compare (TimeSpec s1 ns1) (TimeSpec s2 ns2) =
162− if s1 == s2
163− then compare ns1 ns2
164− else compare s1 s2
165−
166−-- make sure nsec is less than 10^9
167−{-# INLINE addWithOverflow #-}
168−addWithOverflow :: TimeSpec -> TimeSpec -> TimeSpec
169−addWithOverflow (TimeSpec s1 ns1) (TimeSpec s2 ns2) =
170− let nsum = ns1 + ns2
171− (s', ns) = if nsum > tenPower9 || nsum < negate tenPower9
172− then nsum `divMod` tenPower9
173− else (0, nsum)
174− in TimeSpec (s1 + s2 + s') ns
175−
176−-- make sure both sec and nsec have the same sign
177−{-# INLINE adjustSign #-}
178−adjustSign :: TimeSpec -> TimeSpec
179−adjustSign t@(TimeSpec s ns)
180− | s > 0 && ns < 0 = TimeSpec (s - 1) (ns + tenPower9)
181− | s < 0 && ns > 0 = TimeSpec (s + 1) (ns - tenPower9)
182− | otherwise = t
183−
184−{-# INLINE timeSpecToInteger #-}
185−timeSpecToInteger :: TimeSpec -> Integer
186−timeSpecToInteger (TimeSpec s ns) = toInteger $ s * tenPower9 + ns
187−
188−instance Num TimeSpec where
189− {-# INLINE (+) #-}
190− t1 + t2 = adjustSign (addWithOverflow t1 t2)
191−
192− -- XXX will this be more optimal if imlemented without "negate"?
193− {-# INLINE (-) #-}
194− t1 - t2 = t1 + negate t2
195− t1 * t2 = fromInteger $ timeSpecToInteger t1 * timeSpecToInteger t2
196−
197− {-# INLINE negate #-}
198− negate (TimeSpec s ns) = TimeSpec (negate s) (negate ns)
199− {-# INLINE abs #-}
200− abs (TimeSpec s ns) = TimeSpec (abs s) (abs ns)
201− {-# INLINE signum #-}
202− signum (TimeSpec s ns) | s == 0 = TimeSpec (signum ns) 0
203− | otherwise = TimeSpec (signum s) 0
204− -- This is fromNanoSecond64 Integer
205− {-# INLINE fromInteger #-}
206− fromInteger nanosec = TimeSpec (fromInteger s) (fromInteger ns)
207− where (s, ns) = nanosec `divMod` toInteger tenPower9
208−
209143-------------------------------------------------------------------------------
210144-- Time unit conversions
211145-------------------------------------------------------------------------------
src/Streamly/Internal/Data/Time/config-clock.hnew file+11
@@ -0,0 +1,11 @@
1+#if __GHCJS__
2+#define HS_CLOCK_GHCJS 1
3+#elif defined(_WIN32)
4+#define HS_CLOCK_WINDOWS 1
5+#elif (defined (HAVE_TIME_H) && defined(HAVE_CLOCK_GETTIME))
6+#define HS_CLOCK_POSIX 1
7+#elif __APPLE__
8+#define HS_CLOCK_OSX 1
9+#else
10+#error "Time/Clock functionality not implemented for this system"
11+#endif
src/Streamly/Prelude.hs−4
@@ -2,10 +2,6 @@
22{-# LANGUAGE RankNTypes #-}
33{-# LANGUAGE FlexibleContexts #-}
44
5−#if __GLASGOW_HASKELL__ >= 800
6−{-# OPTIONS_GHC -Wno-orphans #-}
7−#endif
8−
95#include "inline.hs"
106
117-- |
streamly.cabal+1
@@ -328,6 +328,7 @@ library
328328 , Streamly.Internal.Data.Strict
329329 , Streamly.Internal.Data.Atomics
330330 , Streamly.Internal.Data.Time
331+ , Streamly.Internal.Data.Time.TimeSpec
331332 , Streamly.Internal.Data.Time.Units
332333 , Streamly.Internal.Data.Time.Clock
333334 , Streamly.Internal.Data.SVar