Skip to content

Commit

Permalink
std/time: reimplement the Sleep function
Browse files Browse the repository at this point in the history
  • Loading branch information
mertcandav committed Oct 21, 2024
1 parent 7cd8768 commit c931a33
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 52 deletions.
22 changes: 22 additions & 0 deletions std/internal/zbits/fits.jule
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2024 The Jule Programming Language.
// Use of this source code is governed by a BSD 3-Clause
// license that can be found in the LICENSE file.

// Reports whether n fits in bits.
fn Fits(n: i64, bits: uint): bool {
const MaxBits = 64
if bits < MaxBits {
if n < 0 {
limit := i64(-1) << (bits - 1)
if n < limit {
ret false
}
} else {
limit := i64(1)<<(bits-1) - 1
if n > limit {
ret false
}
}
}
ret true
}
8 changes: 8 additions & 0 deletions std/runtime/sleep.jule
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright 2024 The Jule Programming Language.
// Use of this source code is governed by a BSD 3-Clause
// license that can be found in the LICENSE file.

type sleepDuration: i64

// See documentation of the `time::Sleep` function.
fn sleep(dur: sleepDuration) { _sleep(dur) }
29 changes: 29 additions & 0 deletions std/runtime/sleep_unix.jule
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2024 The Jule Programming Language.
// Use of this source code is governed by a BSD 3-Clause
// license that can be found in the LICENSE file.

use "std/internal/zbits"
use "std/mem"

cpp unsafe fn nanosleep(*cpp.timespec, *cpp.timespec): int

// See documentation of the sleep function.
fn _sleep(dur: sleepDuration) {
mut sec := dur / _Second
nsec := dur % _Second // always fits in timespec.tv_nsec

mut req := cpp.timespec{}
secBits := mem::SizeOf(req.tv_sec) * 8
limit := i64(1)<<(secBits-1) - 1
for ; sec -= limit {
if sec <= limit {
req.tv_sec = sec
req.tv_nsec = nsec
unsafe { cpp.nanosleep(&req, nil) }
break
} else {
req.tv_sec = limit
unsafe { cpp.nanosleep(&req, nil) }
}
}
}
29 changes: 29 additions & 0 deletions std/runtime/sleep_windows.jule
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2024 The Jule Programming Language.
// Use of this source code is governed by a BSD 3-Clause
// license that can be found in the LICENSE file.

use "std/internal/zbits"

type _DWORD: u32

cpp fn Sleep(_DWORD)

// See documentation of the sleep function.
fn _sleep(dur: sleepDuration) {
mut ms := dur / _Millisecond
if ms == 0 {
// Less than a millisecond, Windows's Sleep function have no precision <1ms.
// To make guaranteed at least given duration is elapsed, sleep for a millisecond.
ms = 1
}
const dwordBits = 32
limit := i64(1) << (dwordBits)
for ; ms -= limit {
if ms <= limit {
cpp.Sleep(unsafe { _DWORD(ms) })
break
} else {
cpp.Sleep(unsafe { _DWORD(limit) })
}
}
}
26 changes: 26 additions & 0 deletions std/runtime/time.jule
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2024 The Jule Programming Language.
// Use of this source code is governed by a BSD 3-Clause
// license that can be found in the LICENSE file.

// A nanosecond.
const _Nanosecond = 1

// Nanoseconds in microsecond.
// How many nanoseconds are in microsecond.
const _Microsecond = 1000 * _Nanosecond

// Nanoseconds in millisecond.
// How many nanoseconds are in millisecond.
const _Millisecond = 1000 * _Microsecond

// Nanoseconds in second.
// How many nanoseconds are in second.
const _Second = 1000 * _Millisecond

// Nanoseconds in minute.
// How many nanoseconds are in minute.
const _Minute = 60 * _Second

// Nanoseconds in hour.
// How many nanoseconds are in hour.
const _Hour = 60 * _Minute
10 changes: 10 additions & 0 deletions std/runtime/time_unix.jule
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright 2024 The Jule Programming Language.
// Use of this source code is governed by a BSD 3-Clause
// license that can be found in the LICENSE file.

cpp use "<time.h>"

cpp struct timespec {
tv_sec: i64
tv_nsec: i64
}
23 changes: 3 additions & 20 deletions std/sys/time.jule
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD 3-Clause
// license that can be found in the LICENSE file.

use "std/internal/zbits"
use "std/mem"

#typedef
Expand All @@ -13,33 +14,15 @@ cpp struct timeval {
// C's timeval structure.
type Timeval: cpp.timeval

fn checkBits(n: i64, bits: uint): bool {
const maxBits = 64
if bits < maxBits {
if n < 0 {
limit := i64(-1) << (bits - 1)
if n < limit {
ret false
}
} else {
limit := i64(1)<<(bits-1) - 1
if n > limit {
ret false
}
}
}
ret true
}

// Creates new Timeval by sec and usec.
// Sets fields of the out.
// Reports whether sec and usec have valid range.
// If sec or usec have invalid range, out will not be mutated.
fn NewTimeval(sec: i64, usec: i64, mut &out: Timeval): bool {
if !checkBits(sec, mem::SizeOf(out.tv_sec)*8) {
if !zbits::Fits(sec, mem::SizeOf(out.tv_sec)*8) {
ret false
}
if !checkBits(usec, mem::SizeOf(out.tv_usec)*8) {
if !zbits::Fits(usec, mem::SizeOf(out.tv_usec)*8) {
ret false
}
out.tv_sec = unsafe { (secType)(sec) }
Expand Down
26 changes: 19 additions & 7 deletions std/time/duration.jule
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,20 @@
// Use of this source code is governed by a BSD 3-Clause
// license that can be found in the LICENSE file.

use "std/runtime"

// Integer type of durations.
type DurInt: i64
type DurInt: runtime::sleepDuration

// Stops execution of the caller thread by stated duration.
// This function only affects execution of caller thread, not process.
// If duration is <=0, function will return immediately.
// It guarantees sleeping at least for the stated duration.
fn Sleep(mut dur: DurInt) {
if dur >= 0 {
runtime::sleep(dur)
}
}

// Duration is the time between two times.
struct Duration{}
Expand All @@ -13,27 +25,27 @@ impl Duration {
const max = DurInt.Max

// A nanosecond.
const Nanosecond: DurInt = 1
const Nanosecond: DurInt = runtime::_Nanosecond

// Nanoseconds in microsecond.
// How many nanoseconds are in microsecond.
const Microsecond: DurInt = 1000 * Duration.Nanosecond
const Microsecond: DurInt = runtime::_Microsecond

// Nanoseconds in millisecond.
// How many nanoseconds are in millisecond.
const Millisecond: DurInt = 1000 * Duration.Microsecond
const Millisecond: DurInt = runtime::_Millisecond

// Nanoseconds in second.
// How many nanoseconds are in second.
const Second: DurInt = 1000 * Duration.Millisecond
const Second: DurInt = runtime::_Second

// Nanoseconds in minute.
// How many nanoseconds are in minute.
const Minute: DurInt = 60 * Duration.Second
const Minute: DurInt = runtime::_Minute

// Nanoseconds in hour.
// How many nanoseconds are in hour.
const Hour: DurInt = 60 * Duration.Minute
const Hour: DurInt = runtime::_Hour

// Returns duration as nanoseconds.
static fn Nanoseconds(d: DurInt): DurInt {
Expand Down
25 changes: 0 additions & 25 deletions std/time/thread.jule

This file was deleted.

0 comments on commit c931a33

Please sign in to comment.