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 };