hare

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

functions.ha (2623B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use rt;
      5 
      6 // Converts a [[duration]] to an [[rt::timespec]]. This function is
      7 // non-portable.
      8 export fn duration_to_timespec(n: duration) rt::timespec = rt::timespec {
      9 	tv_sec = n / SECOND,
     10 	tv_nsec = n % SECOND,
     11 };
     12 
     13 // Converts a [[duration]] to an [[rt::timeval]]. This function is
     14 // non-portable.
     15 export fn duration_to_timeval(d: duration) rt::timeval = rt::timeval {
     16 	tv_sec = d / SECOND,
     17 	tv_usec = d % SECOND / 1000,
     18 };
     19 
     20 // Converts an [[instant]] to an [[rt::timespec]]. This function is
     21 // non-portable.
     22 export fn instant_to_timespec(t: instant) rt::timespec = rt::timespec {
     23 	tv_sec = t.sec,
     24 	tv_nsec = t.nsec,
     25 };
     26 
     27 // Converts a [[rt::timespec]] to an [[instant]]. This function is
     28 // non-portable.
     29 export fn timespec_to_instant(ts: rt::timespec) instant = instant {
     30 	sec = ts.tv_sec,
     31 	nsec = ts.tv_nsec,
     32 };
     33 
     34 // Yields the process to the kernel and returns after the requested duration.
     35 export fn sleep(d: duration) void = {
     36 	let req = duration_to_timespec(d);
     37 
     38 	for (true) {
     39 		let res = rt::timespec { ... };
     40 		match (rt::nanosleep(&req, &res)) {
     41 		case void =>
     42 			return;
     43 		case let err: rt::errno =>
     44 			switch (err) {
     45 			case rt::EINTR =>
     46 				req = res;
     47 			case =>
     48 				abort("Unexpected error from nanosleep");
     49 			};
     50 		};
     51 	};
     52 };
     53 
     54 // An enumeration of clocks available on this system. Different clocks represent
     55 // times from different epochs, and have different characteristics with regards
     56 // to leap seconds, NTP adjustments, and so on. All systems provide the REALTIME
     57 // and MONOTONIC clocks at least; use of other clocks is not guaranteed to be
     58 // portable.
     59 export type clock = enum {
     60 	// The current wall-clock time. This may jump forwards or backwards in
     61 	// time to account for leap seconds, NTP adjustments, etc.
     62 	REALTIME = 0,
     63 
     64 	// The current monotonic time. This clock measures from some undefined
     65 	// epoch and is not affected by leap seconds, NTP adjustments, and
     66 	// changes to the system time: it always increases by one second per
     67 	// second.
     68 	MONOTONIC = 4,
     69 
     70 	// TODO: Document these
     71 	VIRTUAL = 1,
     72 	PROF = 2,
     73 	UPTIME = 5,
     74 	UPTIME_PRECISE = 7,
     75 	UPTIME_FAST = 8,
     76 	REALTIME_PRECISE = 9,
     77 	REALTIME_FAST = 10,
     78 	MONOTONIC_PRECISE = 11,
     79 	MONOTONIC_FAST = 12,
     80 	SECOND = 13,
     81 	THREAD_CPUTIME_ID = 14,
     82 	PROCESS_CPUTIME_ID = 15,
     83 };
     84 
     85 // Returns the current time for a given clock.
     86 export fn now(clock: clock) instant = {
     87 	let tp = rt::timespec { ... };
     88 	match (rt::clock_gettime(clock, &tp)) {
     89 	case void =>
     90 		return timespec_to_instant(tp);
     91 	case let err: rt::errno =>
     92 		abort("Unexpected error from clock_gettime");
     93 	};
     94 };