commit 60b5c5cadb73ef563b76b0f381ffa37325563498
parent 145dc1da06092efe55c70104c6441d7ff324255e
Author: Drew DeVault <sir@cmpwn.com>
Date: Sun, 14 Mar 2021 10:41:29 -0400
time: new module
Diffstat:
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 = ∈
+
+ 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;