Skip to content

Commit

Permalink
Add Thread.sleep(Time::Span) (#14715)
Browse files Browse the repository at this point in the history
Blocks the current thread for the given duration.
  • Loading branch information
ysbaddaden committed Jun 16, 2024
1 parent 6a2097d commit bcb5aeb
Show file tree
Hide file tree
Showing 20 changed files with 52 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/crystal/system/thread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ module Crystal::System::Thread

# def self.current_thread=(thread : ::Thread)

# def self.sleep(time : ::Time::Span) : Nil

# private def system_join : Exception?

# private def system_close
Expand Down Expand Up @@ -99,6 +101,12 @@ class Thread
end
end

# Blocks the current thread for the duration of *time*. Clock precision is
# dependent on the operating system and hardware.
def self.sleep(time : Time::Span) : Nil
Crystal::System::Thread.sleep(time)
end

# Returns the Thread object associated to the running system thread.
def self.current : Thread
Crystal::System::Thread.current_thread
Expand Down
12 changes: 12 additions & 0 deletions src/crystal/system/unix/pthread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,18 @@ module Crystal::System::Thread
end
{% end %}

def self.sleep(time : ::Time::Span) : Nil
req = uninitialized LibC::Timespec
req.tv_sec = typeof(req.tv_sec).new(time.seconds)
req.tv_nsec = typeof(req.tv_nsec).new(time.nanoseconds)

loop do
return if LibC.nanosleep(pointerof(req), out rem) == 0
raise RuntimeError.from_errno("nanosleep() failed") unless Errno.value == Errno::EINTR
req = rem
end
end

private def system_join : Exception?
ret = GC.pthread_join(@system_handle)
RuntimeError.from_os_error("pthread_join", Errno.new(ret)) unless ret == 0
Expand Down
12 changes: 12 additions & 0 deletions src/crystal/system/wasi/thread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ module Crystal::System::Thread

class_property current_thread : ::Thread { ::Thread.new }

def self.sleep(time : ::Time::Span) : Nil
req = uninitialized LibC::Timespec
req.tv_sec = typeof(req.tv_sec).new(time.seconds)
req.tv_nsec = typeof(req.tv_nsec).new(time.nanoseconds)

loop do
return if LibC.nanosleep(pointerof(req), out rem) == 0
raise RuntimeError.from_errno("nanosleep() failed") unless Errno.value == Errno::EINTR
req = rem
end
end

private def system_join : Exception?
NotImplementedError.new("Crystal::System::Thread#system_join")
end
Expand Down
4 changes: 4 additions & 0 deletions src/crystal/system/win32/thread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ module Crystal::System::Thread
@@current_thread
end

def self.sleep(time : ::Time::Span) : Nil
LibC.Sleep(time.total_milliseconds.to_i.clamp(1..))
end

private def system_join : Exception?
if LibC.WaitForSingleObject(@system_handle, LibC::INFINITE) != LibC::WAIT_OBJECT_0
return RuntimeError.from_winerror("WaitForSingleObject")
Expand Down
1 change: 1 addition & 0 deletions src/lib_c/aarch64-android/c/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ lib LibC
fun gmtime_r(__t : TimeT*, __tm : Tm*) : Tm*
fun localtime_r(__t : TimeT*, __tm : Tm*) : Tm*
fun mktime(__tm : Tm*) : TimeT
fun nanosleep(__req : Timespec*, __rem : Timespec*) : Int
fun tzset : Void
fun timegm(__tm : Tm*) : TimeT

Expand Down
1 change: 1 addition & 0 deletions src/lib_c/aarch64-darwin/c/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ lib LibC
fun gmtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun localtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun mktime(x0 : Tm*) : TimeT
fun nanosleep(x0 : Timespec*, x1 : Timespec*) : Int
fun tzset : Void
fun timegm(x0 : Tm*) : TimeT

Expand Down
1 change: 1 addition & 0 deletions src/lib_c/aarch64-linux-gnu/c/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ lib LibC
fun gmtime_r(timer : TimeT*, tp : Tm*) : Tm*
fun localtime_r(timer : TimeT*, tp : Tm*) : Tm*
fun mktime(tp : Tm*) : TimeT
fun nanosleep(req : Timespec*, rem : Timespec*) : Int
fun tzset : Void
fun timegm(tp : Tm*) : TimeT

Expand Down
1 change: 1 addition & 0 deletions src/lib_c/aarch64-linux-musl/c/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ lib LibC
fun gmtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun localtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun mktime(x0 : Tm*) : TimeT
fun nanosleep(x0 : Timespec*, x1 : Timespec*) : Int
fun tzset : Void
fun timegm(x0 : Tm*) : TimeT

Expand Down
1 change: 1 addition & 0 deletions src/lib_c/arm-linux-gnueabihf/c/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ lib LibC
fun gmtime_r(timer : TimeT*, tp : Tm*) : Tm*
fun localtime_r(timer : TimeT*, tp : Tm*) : Tm*
fun mktime(tp : Tm*) : TimeT
fun nanosleep(req : Timespec*, rem : Timespec*) : Int
fun tzset : Void
fun timegm(tp : Tm*) : TimeT

Expand Down
1 change: 1 addition & 0 deletions src/lib_c/i386-linux-gnu/c/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ lib LibC
fun gmtime_r(timer : TimeT*, tp : Tm*) : Tm*
fun localtime_r(timer : TimeT*, tp : Tm*) : Tm*
fun mktime(tp : Tm*) : TimeT
fun nanosleep(req : Timespec*, rem : Timespec*) : Int
fun tzset : Void
fun timegm(tp : Tm*) : TimeT

Expand Down
1 change: 1 addition & 0 deletions src/lib_c/i386-linux-musl/c/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ lib LibC
fun gmtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun localtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun mktime(x0 : Tm*) : TimeT
fun nanosleep(x0 : Timespec*, x1 : Timespec*) : Int
fun tzset : Void
fun timegm(x0 : Tm*) : TimeT

Expand Down
1 change: 1 addition & 0 deletions src/lib_c/wasm32-wasi/c/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ lib LibC
fun gmtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun localtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun mktime(x0 : Tm*) : TimeT
fun nanosleep(x0 : Timespec*, x1 : Timespec*) : Int
fun timegm(x0 : Tm*) : TimeT
fun futimes(fd : Int, times : Timeval[2]) : Int
end
1 change: 1 addition & 0 deletions src/lib_c/x86_64-darwin/c/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ lib LibC
fun gmtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun localtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun mktime(x0 : Tm*) : TimeT
fun nanosleep(x0 : Timespec*, x1 : Timespec*) : Int
fun tzset : Void
fun timegm(x0 : Tm*) : TimeT

Expand Down
1 change: 1 addition & 0 deletions src/lib_c/x86_64-dragonfly/c/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ lib LibC
fun gmtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun localtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun mktime(x0 : Tm*) : TimeT
fun nanosleep(x0 : Timespec*, x1 : Timespec*) : Int
fun tzset : Void
fun timegm(x0 : Tm*) : TimeT

Expand Down
1 change: 1 addition & 0 deletions src/lib_c/x86_64-freebsd/c/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ lib LibC
fun gmtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun localtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun mktime(x0 : Tm*) : TimeT
fun nanosleep(x0 : Timespec*, x1 : Timespec*) : Int
fun tzset : Void
fun timegm(x0 : Tm*) : TimeT

Expand Down
1 change: 1 addition & 0 deletions src/lib_c/x86_64-linux-gnu/c/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ lib LibC
fun gmtime_r(timer : TimeT*, tp : Tm*) : Tm*
fun localtime_r(timer : TimeT*, tp : Tm*) : Tm*
fun mktime(tp : Tm*) : TimeT
fun nanosleep(req : Timespec*, rem : Timespec*) : Int
fun tzset : Void
fun timegm(tp : Tm*) : TimeT

Expand Down
1 change: 1 addition & 0 deletions src/lib_c/x86_64-linux-musl/c/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ lib LibC
fun gmtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun localtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun mktime(x0 : Tm*) : TimeT
fun nanosleep(x0 : Timespec*, x1 : Timespec*) : Int
fun tzset : Void
fun timegm(x0 : Tm*) : TimeT

Expand Down
1 change: 1 addition & 0 deletions src/lib_c/x86_64-netbsd/c/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ lib LibC
fun gmtime_r = __gmtime_r50(x0 : TimeT*, x1 : Tm*) : Tm*
fun localtime_r = __localtime_r50(x0 : TimeT*, x1 : Tm*) : Tm*
fun mktime = __mktime50(x0 : Tm*) : TimeT
fun nanosleep = __nanosleep50(x0 : Timespec*, x1 : Timespec*) : Int
fun tzset : Void
fun timegm = __timegm50(x0 : Tm*) : TimeT

Expand Down
1 change: 1 addition & 0 deletions src/lib_c/x86_64-openbsd/c/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ lib LibC
fun gmtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun localtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun mktime(x0 : Tm*) : TimeT
fun nanosleep(x0 : Timespec*, x1 : Timespec*) : Int
fun tzset : Void
fun timegm(x0 : Tm*) : TimeT

Expand Down
1 change: 1 addition & 0 deletions src/lib_c/x86_64-solaris/c/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ lib LibC
fun gmtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun localtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
fun mktime(x0 : Tm*) : TimeT
fun nanosleep(x0 : Timespec*, x1 : Timespec*) : Int
fun tzset : Void
fun timegm(x0 : Tm*) : TimeT

Expand Down

0 comments on commit bcb5aeb

Please sign in to comment.