File tree 3 files changed +50
-1
lines changed
3 files changed +50
-1
lines changed Original file line number Diff line number Diff line change @@ -287,10 +287,24 @@ pub fn sleep(dur: Duration) {
287
287
} ;
288
288
// If we're awoken with a signal then the return value will be -1 and
289
289
// nanosleep will fill in `ts` with the remaining time.
290
- while libc :: nanosleep ( & ts , & mut ts) == -1 {
290
+ while dosleep ( & mut ts) == -1 {
291
291
assert_eq ! ( os:: errno( ) , libc:: EINTR ) ;
292
292
}
293
293
}
294
+
295
+ #[ cfg( target_os = "linux" ) ]
296
+ unsafe fn dosleep ( ts : * mut libc:: timespec ) -> libc:: c_int {
297
+ extern {
298
+ fn clock_nanosleep ( clock_id : libc:: c_int , flags : libc:: c_int ,
299
+ request : * const libc:: timespec ,
300
+ remain : * mut libc:: timespec ) -> libc:: c_int ;
301
+ }
302
+ clock_nanosleep ( libc:: CLOCK_MONOTONIC , 0 , ts, ts)
303
+ }
304
+ #[ cfg( not( target_os = "linux" ) ) ]
305
+ unsafe fn dosleep ( ts : * mut libc:: timespec ) -> libc:: c_int {
306
+ libc:: nanosleep ( ts, ts)
307
+ }
294
308
}
295
309
296
310
// glibc >= 2.15 has a __pthread_get_minstack() function that returns
Original file line number Diff line number Diff line change @@ -20,6 +20,7 @@ use ptr;
20
20
use sys_common:: stack:: RED_ZONE ;
21
21
use sys_common:: thread:: * ;
22
22
use thunk:: Thunk ;
23
+ use time:: Duration ;
23
24
24
25
pub type rust_thread = HANDLE ;
25
26
@@ -82,6 +83,20 @@ pub unsafe fn yield_now() {
82
83
SwitchToThread ( ) ;
83
84
}
84
85
86
+ pub fn sleep ( dur : Duration ) {
87
+ unsafe {
88
+ if dur < Duration :: zero ( ) {
89
+ return yield_now ( )
90
+ }
91
+ let ms = dur. num_milliseconds ( ) ;
92
+ // if we have a fractional number of milliseconds then add an extra
93
+ // millisecond to sleep for
94
+ let extra = dur - Duration :: milliseconds ( ms) ;
95
+ let ms = ms + if extra. is_zero ( ) { 0 } else { 1 } ;
96
+ Sleep ( ms as DWORD ) ;
97
+ }
98
+ }
99
+
85
100
#[ allow( non_snake_case) ]
86
101
extern "system" {
87
102
fn CreateThread ( lpThreadAttributes : LPSECURITY_ATTRIBUTES ,
@@ -92,4 +107,5 @@ extern "system" {
92
107
lpThreadId : LPDWORD ) -> HANDLE ;
93
108
fn WaitForSingleObject ( hHandle : HANDLE , dwMilliseconds : DWORD ) -> DWORD ;
94
109
fn SwitchToThread ( ) -> BOOL ;
110
+ fn Sleep ( dwMilliseconds : DWORD ) ;
95
111
}
Original file line number Diff line number Diff line change @@ -379,6 +379,19 @@ pub fn panicking() -> bool {
379
379
unwind:: panicking ( )
380
380
}
381
381
382
+ /// Put the current thread to sleep for the specified amount of time.
383
+ ///
384
+ /// The thread may sleep longer than the duration specified due to scheduling
385
+ /// specifics or platform-dependent functionality. Note that on unix platforms
386
+ /// this function will not return early due to a signal being received or a
387
+ /// spurious wakeup.
388
+ #[ unstable( feature = "thread_sleep" ,
389
+ reason = "recently added, needs an RFC, and `Duration` itself is \
390
+ unstable") ]
391
+ pub fn sleep ( dur : Duration ) {
392
+ imp:: sleep ( dur)
393
+ }
394
+
382
395
/// Block unless or until the current thread's token is made available (may wake spuriously).
383
396
///
384
397
/// See the module doc for more detail.
@@ -935,6 +948,12 @@ mod test {
935
948
}
936
949
}
937
950
951
+ #[ test]
952
+ fn sleep_smoke ( ) {
953
+ thread:: sleep ( Duration :: milliseconds ( 2 ) ) ;
954
+ thread:: sleep ( Duration :: milliseconds ( -2 ) ) ;
955
+ }
956
+
938
957
// NOTE: the corresponding test for stderr is in run-pass/task-stderr, due
939
958
// to the test harness apparently interfering with stderr configuration.
940
959
}
You can’t perform that action at this time.
0 commit comments