1- use crate :: cmp:: Ordering ;
21use crate :: time:: Duration ;
32
4- use core:: hash:: { Hash , Hasher } ;
5-
63pub use self :: inner:: { Instant , SystemTime , UNIX_EPOCH } ;
74use crate :: convert:: TryInto ;
85
96const NSEC_PER_SEC : u64 = 1_000_000_000 ;
107
11- #[ derive( Copy , Clone ) ]
8+ #[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
129pub ( in crate :: sys:: unix) struct Timespec {
13- pub t : libc:: timespec ,
10+ tv_sec : i64 ,
11+ tv_nsec : i64 ,
1412}
1513
1614impl Timespec {
1715 const fn zero ( ) -> Timespec {
18- Timespec { t : libc:: timespec { tv_sec : 0 , tv_nsec : 0 } }
16+ Timespec { tv_sec : 0 , tv_nsec : 0 }
17+ }
18+
19+ fn new ( tv_sec : i64 , tv_nsec : i64 ) -> Timespec {
20+ Timespec { tv_sec, tv_nsec }
1921 }
2022
2123 pub fn sub_timespec ( & self , other : & Timespec ) -> Result < Duration , Duration > {
2224 if self >= other {
2325 // NOTE(eddyb) two aspects of this `if`-`else` are required for LLVM
2426 // to optimize it into a branchless form (see also #75545):
2527 //
26- // 1. `self.t. tv_sec - other.t .tv_sec` shows up as a common expression
28+ // 1. `self.tv_sec - other.tv_sec` shows up as a common expression
2729 // in both branches, i.e. the `else` must have its `- 1`
2830 // subtraction after the common one, not interleaved with it
29- // (it used to be `self.t. tv_sec - 1 - other.t .tv_sec`)
31+ // (it used to be `self.tv_sec - 1 - other.tv_sec`)
3032 //
3133 // 2. the `Duration::new` call (or any other additional complexity)
3234 // is outside of the `if`-`else`, not duplicated in both branches
3335 //
3436 // Ideally this code could be rearranged such that it more
3537 // directly expresses the lower-cost behavior we want from it.
36- let ( secs, nsec) = if self . t . tv_nsec >= other. t . tv_nsec {
37- ( ( self . t . tv_sec - other. t . tv_sec ) as u64 , ( self . t . tv_nsec - other. t . tv_nsec ) as u32 )
38+ let ( secs, nsec) = if self . tv_nsec >= other. tv_nsec {
39+ ( ( self . tv_sec - other. tv_sec ) as u64 , ( self . tv_nsec - other. tv_nsec ) as u32 )
3840 } else {
3941 (
40- ( self . t . tv_sec - other. t . tv_sec - 1 ) as u64 ,
41- self . t . tv_nsec as u32 + ( NSEC_PER_SEC as u32 ) - other. t . tv_nsec as u32 ,
42+ ( self . tv_sec - other. tv_sec - 1 ) as u64 ,
43+ self . tv_nsec as u32 + ( NSEC_PER_SEC as u32 ) - other. tv_nsec as u32 ,
4244 )
4345 } ;
4446
@@ -54,63 +56,34 @@ impl Timespec {
5456 pub fn checked_add_duration ( & self , other : & Duration ) -> Option < Timespec > {
5557 let mut secs = other
5658 . as_secs ( )
57- . try_into ( ) // <- target type would be `libc::time_t `
59+ . try_into ( ) // <- target type would be `i64 `
5860 . ok ( )
59- . and_then ( |secs| self . t . tv_sec . checked_add ( secs) ) ?;
61+ . and_then ( |secs| self . tv_sec . checked_add ( secs) ) ?;
6062
6163 // Nano calculations can't overflow because nanos are <1B which fit
6264 // in a u32.
63- let mut nsec = other. subsec_nanos ( ) + self . t . tv_nsec as u32 ;
65+ let mut nsec = other. subsec_nanos ( ) + self . tv_nsec as u32 ;
6466 if nsec >= NSEC_PER_SEC as u32 {
6567 nsec -= NSEC_PER_SEC as u32 ;
6668 secs = secs. checked_add ( 1 ) ?;
6769 }
68- Some ( Timespec { t : libc :: timespec { tv_sec : secs, tv_nsec : nsec as _ } } )
70+ Some ( Timespec :: new ( secs, nsec as i64 ) )
6971 }
7072
7173 pub fn checked_sub_duration ( & self , other : & Duration ) -> Option < Timespec > {
7274 let mut secs = other
7375 . as_secs ( )
74- . try_into ( ) // <- target type would be `libc::time_t `
76+ . try_into ( ) // <- target type would be `i64 `
7577 . ok ( )
76- . and_then ( |secs| self . t . tv_sec . checked_sub ( secs) ) ?;
78+ . and_then ( |secs| self . tv_sec . checked_sub ( secs) ) ?;
7779
7880 // Similar to above, nanos can't overflow.
79- let mut nsec = self . t . tv_nsec as i32 - other. subsec_nanos ( ) as i32 ;
81+ let mut nsec = self . tv_nsec as i32 - other. subsec_nanos ( ) as i32 ;
8082 if nsec < 0 {
8183 nsec += NSEC_PER_SEC as i32 ;
8284 secs = secs. checked_sub ( 1 ) ?;
8385 }
84- Some ( Timespec { t : libc:: timespec { tv_sec : secs, tv_nsec : nsec as _ } } )
85- }
86- }
87-
88- impl PartialEq for Timespec {
89- fn eq ( & self , other : & Timespec ) -> bool {
90- self . t . tv_sec == other. t . tv_sec && self . t . tv_nsec == other. t . tv_nsec
91- }
92- }
93-
94- impl Eq for Timespec { }
95-
96- impl PartialOrd for Timespec {
97- fn partial_cmp ( & self , other : & Timespec ) -> Option < Ordering > {
98- Some ( self . cmp ( other) )
99- }
100- }
101-
102- impl Ord for Timespec {
103- fn cmp ( & self , other : & Timespec ) -> Ordering {
104- let me = ( self . t . tv_sec , self . t . tv_nsec ) ;
105- let other = ( other. t . tv_sec , other. t . tv_nsec ) ;
106- me. cmp ( & other)
107- }
108- }
109-
110- impl Hash for Timespec {
111- fn hash < H : Hasher > ( & self , state : & mut H ) {
112- self . t . tv_sec . hash ( state) ;
113- self . t . tv_nsec . hash ( state) ;
86+ Some ( Timespec :: new ( secs, nsec as i64 ) )
11487 }
11588}
11689
@@ -192,26 +165,35 @@ mod inner {
192165 }
193166 }
194167
168+ impl From < libc:: timeval > for Timespec {
169+ fn from ( t : libc:: timeval ) -> Timespec {
170+ Timespec :: new ( t. tv_sec as i64 , 1000 * t. tv_usec as i64 )
171+ }
172+ }
173+
195174 impl From < libc:: timeval > for SystemTime {
196175 fn from ( t : libc:: timeval ) -> SystemTime {
197- SystemTime :: from ( libc:: timespec {
198- tv_sec : t. tv_sec ,
199- tv_nsec : ( t. tv_usec * 1000 ) as libc:: c_long ,
200- } )
176+ SystemTime { t : Timespec :: from ( t) }
177+ }
178+ }
179+
180+ impl From < libc:: timespec > for Timespec {
181+ fn from ( t : libc:: timespec ) -> Timespec {
182+ Timespec :: new ( t. tv_sec as i64 , t. tv_nsec as i64 )
201183 }
202184 }
203185
204186 impl From < libc:: timespec > for SystemTime {
205187 fn from ( t : libc:: timespec ) -> SystemTime {
206- SystemTime { t : Timespec { t } }
188+ SystemTime { t : Timespec :: from ( t ) }
207189 }
208190 }
209191
210192 impl fmt:: Debug for SystemTime {
211193 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
212194 f. debug_struct ( "SystemTime" )
213- . field ( "tv_sec" , & self . t . t . tv_sec )
214- . field ( "tv_nsec" , & self . t . t . tv_nsec )
195+ . field ( "tv_sec" , & self . t . tv_sec )
196+ . field ( "tv_nsec" , & self . t . tv_nsec )
215197 . finish ( )
216198 }
217199 }
@@ -305,8 +287,8 @@ mod inner {
305287 impl fmt:: Debug for Instant {
306288 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
307289 f. debug_struct ( "Instant" )
308- . field ( "tv_sec" , & self . t . t . tv_sec )
309- . field ( "tv_nsec" , & self . t . t . tv_nsec )
290+ . field ( "tv_sec" , & self . t . tv_sec )
291+ . field ( "tv_nsec" , & self . t . tv_nsec )
310292 . finish ( )
311293 }
312294 }
@@ -329,17 +311,23 @@ mod inner {
329311 }
330312 }
331313
314+ impl From < libc:: timespec > for Timespec {
315+ fn from ( t : libc:: timespec ) -> Timespec {
316+ Timespec :: new ( t. tv_sec as i64 , t. tv_nsec as i64 )
317+ }
318+ }
319+
332320 impl From < libc:: timespec > for SystemTime {
333321 fn from ( t : libc:: timespec ) -> SystemTime {
334- SystemTime { t : Timespec { t } }
322+ SystemTime { t : Timespec :: from ( t ) }
335323 }
336324 }
337325
338326 impl fmt:: Debug for SystemTime {
339327 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
340328 f. debug_struct ( "SystemTime" )
341- . field ( "tv_sec" , & self . t . t . tv_sec )
342- . field ( "tv_nsec" , & self . t . t . tv_nsec )
329+ . field ( "tv_sec" , & self . t . tv_sec )
330+ . field ( "tv_nsec" , & self . t . tv_nsec )
343331 . finish ( )
344332 }
345333 }
@@ -353,7 +341,15 @@ mod inner {
353341 pub fn now ( clock : clock_t ) -> Timespec {
354342 let mut t = MaybeUninit :: uninit ( ) ;
355343 cvt ( unsafe { libc:: clock_gettime ( clock, t. as_mut_ptr ( ) ) } ) . unwrap ( ) ;
356- Timespec { t : unsafe { t. assume_init ( ) } }
344+ Timespec :: from ( unsafe { t. assume_init ( ) } )
345+ }
346+
347+ pub fn to_timespec ( & self ) -> Option < libc:: timespec > {
348+ use crate :: convert:: TryInto ;
349+ Some ( libc:: timespec {
350+ tv_sec : self . tv_sec . try_into ( ) . ok ( ) ?,
351+ tv_nsec : self . tv_nsec . try_into ( ) . ok ( ) ?,
352+ } )
357353 }
358354 }
359355}
0 commit comments