hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 60b5c5cadb73ef563b76b0f381ffa37325563498
parent 145dc1da06092efe55c70104c6441d7ff324255e
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun, 14 Mar 2021 10:41:29 -0400

time: new module

Diffstat:
Mgen-stdlib | 9+++++++++
Mrt/+linux/syscalls.ha | 6++++++
Mstdlib.mk | 28++++++++++++++++++++++++++++
Atime/+linux.ha | 26++++++++++++++++++++++++++
Atime/types.ha | 10++++++++++
5 files changed, 79 insertions(+), 0 deletions(-)

diff --git a/gen-stdlib b/gen-stdlib @@ -453,6 +453,14 @@ strio() { gen_ssa strio io strings encoding::utf8 } +time() { + printf '# time\n' + gen_srcs time \ + '$(PLATFORM).ha' \ + types.ha + gen_ssa time +} + temp() { printf '# temp\n' gen_srcs temp \ @@ -502,6 +510,7 @@ strconv strings strio temp +time types" stdlib() { rt diff --git a/rt/+linux/syscalls.ha b/rt/+linux/syscalls.ha @@ -288,6 +288,12 @@ export fn clock_gettime(clock_id: int, tp: *timespec) (void | errno) = { return; }; +export fn nanosleep(req: *const timespec, rem: *timespec) (void | errno) = { + wrap_return(syscall2(SYS_nanosleep, + req: uintptr: u64, rem: uintptr: u64))?; + return; +}; + export fn uname(uts: *utsname) (void | errno) = { wrap_return(syscall1(SYS_uname, uts: uintptr: u64))?; return; diff --git a/stdlib.mk b/stdlib.mk @@ -161,6 +161,9 @@ hare_stdlib_deps+=$(stdlib_strio) stdlib_temp=$(HARECACHE)/temp/temp.o hare_stdlib_deps+=$(stdlib_temp) +stdlib_time=$(HARECACHE)/time/time.o +hare_stdlib_deps+=$(stdlib_time) + stdlib_types=$(HARECACHE)/types/types.o hare_stdlib_deps+=$(stdlib_types) @@ -536,6 +539,17 @@ $(HARECACHE)/temp/temp.ssa: $(stdlib_temp_srcs) $(stdlib_rt) $(stdlib_crypto_ran @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ntemp \ -t$(HARECACHE)/temp/temp.td $(stdlib_temp_srcs) +# time +stdlib_time_srcs= \ + $(STDLIB)/time/$(PLATFORM).ha \ + $(STDLIB)/time/types.ha + +$(HARECACHE)/time/time.ssa: $(stdlib_time_srcs) $(stdlib_rt) + @printf 'HAREC \t$@\n' + @mkdir -p $(HARECACHE)/time + @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ntime \ + -t$(HARECACHE)/time/time.td $(stdlib_time_srcs) + # types stdlib_types_srcs= \ $(STDLIB)/types/limits.ha \ @@ -711,6 +725,9 @@ hare_testlib_deps+=$(testlib_strio) testlib_temp=$(TESTCACHE)/temp/temp.o hare_testlib_deps+=$(testlib_temp) +testlib_time=$(TESTCACHE)/time/time.o +hare_testlib_deps+=$(testlib_time) + testlib_types=$(TESTCACHE)/types/types.o hare_testlib_deps+=$(testlib_types) @@ -1096,6 +1113,17 @@ $(TESTCACHE)/temp/temp.ssa: $(testlib_temp_srcs) $(testlib_rt) $(testlib_crypto_ @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ntemp \ -t$(TESTCACHE)/temp/temp.td $(testlib_temp_srcs) +# time +testlib_time_srcs= \ + $(STDLIB)/time/$(PLATFORM).ha \ + $(STDLIB)/time/types.ha + +$(TESTCACHE)/time/time.ssa: $(testlib_time_srcs) $(testlib_rt) + @printf 'HAREC \t$@\n' + @mkdir -p $(TESTCACHE)/time + @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ntime \ + -t$(TESTCACHE)/time/time.td $(testlib_time_srcs) + # types testlib_types_srcs= \ $(STDLIB)/types/limits.ha \ diff --git a/time/+linux.ha b/time/+linux.ha @@ -0,0 +1,26 @@ +use rt; + +fn duration_to_timespec(n: duration, ts: *rt::timespec) void = { + ts.tv_sec = n / SECOND; + ts.tv_nsec = n % SECOND; +}; + +// Yields the process to the kernel and returns after the requested duration. +export fn sleep(n: duration) void = { + let in = rt::timespec { ... }; + duration_to_timespec(n, &in); + let req = &in; + + for (true) { + let res = rt::timespec { ... }; + match (rt::nanosleep(req, &res)) { + void => return, + err: rt::errno => switch (err) { + rt::EINTR => { + req = &res; + }, + * => abort("Unexpected error from nanosleep"), + }, + }; + }; +}; diff --git a/time/types.ha b/time/types.ha @@ -0,0 +1,10 @@ +// The elapsed time between two instants, in nanoseconds. The largest +// representable duration is about 290 years. +export type duration = i64; + +export def NANOSECOND: duration = 1; +export def MICROSECOND: duration = 1000 * NANOSECOND; +export def MILLISECOND: duration = 1000 * MICROSECOND; +export def SECOND: duration = 1000 * MILLISECOND; +export def MINUTE: duration = 60 * SECOND; +export def HOUR: duration = 60 * MINUTE;