mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-04 17:53:07 +00:00
parent
316f9e4df3
commit
9cf5da85ef
@ -25,8 +25,8 @@ install_config {
|
|||||||
<start name="test-libc">
|
<start name="test-libc">
|
||||||
<resource name="RAM" quantum="400M"/>
|
<resource name="RAM" quantum="400M"/>
|
||||||
<config>
|
<config>
|
||||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
<vfs> <dir name="dev"> <log/> <inline name="rtc">2019-08-20 15:01</inline> </dir> </vfs>
|
||||||
<libc stdout="/dev/log" stderr="/dev/log"/>
|
<libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc"/>
|
||||||
</config>
|
</config>
|
||||||
</start>
|
</start>
|
||||||
</config>
|
</config>
|
||||||
|
@ -26,47 +26,82 @@
|
|||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
|
#include <vfs/vfs_handle.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Libc {
|
namespace Libc {
|
||||||
extern char const *config_rtc();
|
extern char const *config_rtc();
|
||||||
time_t read_rtc();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
time_t Libc::read_rtc()
|
struct Rtc : Vfs::Watch_response_handler
|
||||||
{
|
{
|
||||||
time_t rtc = 0;
|
Vfs::Vfs_watch_handle *_watch_handle { nullptr };
|
||||||
|
char const *_file { nullptr };
|
||||||
|
bool _read_file { true };
|
||||||
|
time_t _rtc_value { 0 };
|
||||||
|
|
||||||
if (!Genode::strcmp(Libc::config_rtc(), "")) {
|
Rtc(char const *rtc_file)
|
||||||
Genode::warning("rtc not configured, returning ", rtc);
|
: _file(rtc_file)
|
||||||
return rtc;
|
{
|
||||||
|
if (!Genode::strcmp(_file, "")) {
|
||||||
|
Genode::warning("rtc not configured, returning ", _rtc_value);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd = open(Libc::config_rtc(), O_RDONLY);
|
_watch_handle = Libc::watch(_file);
|
||||||
|
if (_watch_handle) {
|
||||||
|
_watch_handle->handler(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************
|
||||||
|
** Vfs::Watch_reponse_handler interface **
|
||||||
|
******************************************/
|
||||||
|
|
||||||
|
void watch_response() override
|
||||||
|
{
|
||||||
|
_read_file = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t read()
|
||||||
|
{
|
||||||
|
if (!_file) { return 0; }
|
||||||
|
|
||||||
|
/* return old value */
|
||||||
|
if (!_read_file) { return _rtc_value; }
|
||||||
|
|
||||||
|
_read_file = false;
|
||||||
|
|
||||||
|
int fd = open(_file, O_RDONLY);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
Genode::warning(Genode::Cstring(Libc::config_rtc()), " not readable, returning ", rtc);
|
Genode::warning(Genode::Cstring(Libc::config_rtc()), " not readable, returning ", _rtc_value);
|
||||||
return rtc;
|
return _rtc_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
char buf[32];
|
char buf[32];
|
||||||
ssize_t n = read(fd, buf, sizeof(buf));
|
ssize_t n = ::read(fd, buf, sizeof(buf));
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
buf[n - 1] = '\0';
|
buf[n - 1] = '\0';
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
Genode::memset(&tm, 0, sizeof(tm));
|
Genode::memset(&tm, 0, sizeof(tm));
|
||||||
|
|
||||||
if (strptime(buf, "%Y-%m-%d %R", &tm)) {
|
if (strptime(buf, "%Y-%m-%d %R", &tm)) {
|
||||||
rtc = mktime(&tm);
|
_rtc_value = mktime(&tm);
|
||||||
if (rtc == (time_t)-1)
|
if (_rtc_value == (time_t)-1)
|
||||||
rtc = 0;
|
_rtc_value = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
return rtc;
|
uint64_t const ts_value =
|
||||||
|
Libc::current_time().trunc_to_plain_ms().value;
|
||||||
|
_rtc_value += (time_t)ts_value / 1000;
|
||||||
|
|
||||||
|
return _rtc_value;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
extern "C" __attribute__((weak))
|
extern "C" __attribute__((weak))
|
||||||
@ -84,24 +119,14 @@ int clock_gettime(clockid_t clk_id, struct timespec *ts)
|
|||||||
case CLOCK_REALTIME:
|
case CLOCK_REALTIME:
|
||||||
case CLOCK_SECOND: /* FreeBSD specific */
|
case CLOCK_SECOND: /* FreeBSD specific */
|
||||||
{
|
{
|
||||||
static bool initial_rtc_requested = false;
|
static Rtc rtc(Libc::config_rtc());
|
||||||
static time_t initial_rtc = 0;
|
|
||||||
static Genode::uint64_t t0_ms = 0;
|
|
||||||
|
|
||||||
/* try to read rtc once */
|
time_t const rtc_value = rtc.read();
|
||||||
if (!initial_rtc_requested) {
|
if (!rtc_value) return Libc::Errno(EINVAL);
|
||||||
initial_rtc_requested = true;
|
|
||||||
initial_rtc = Libc::read_rtc();
|
|
||||||
if (initial_rtc) {
|
|
||||||
t0_ms = Libc::current_time().trunc_to_plain_ms().value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!initial_rtc) return Libc::Errno(EINVAL);
|
Genode::uint64_t const time = Libc::current_time().trunc_to_plain_ms().value;
|
||||||
|
|
||||||
Genode::uint64_t time = Libc::current_time().trunc_to_plain_ms().value - t0_ms;
|
ts->tv_sec = rtc_value + time/1000;
|
||||||
|
|
||||||
ts->tv_sec = initial_rtc + time/1000;
|
|
||||||
ts->tv_nsec = (time % 1000) * (1000*1000);
|
ts->tv_nsec = (time % 1000) * (1000*1000);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -159,9 +159,13 @@ int main(int argc, char **argv)
|
|||||||
sleep(1);
|
sleep(1);
|
||||||
ts.tv_sec = ts.tv_nsec = 0;
|
ts.tv_sec = ts.tv_nsec = 0;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
printf("sleep/gettime: %.09f\n", ts.tv_sec + ts.tv_nsec / 1000000000.0);
|
printf("sleep/gettime(CLOCK_MONOTONIC): %.09f\n", ts.tv_sec + ts.tv_nsec / 1000000000.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ts.tv_sec = ts.tv_nsec = 0;
|
||||||
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
printf("sleep/gettime(CLOCK_REALTIME): %.09f\n", ts.tv_sec + ts.tv_nsec / 1000000000.0);
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned long long buf = 0;
|
unsigned long long buf = 0;
|
||||||
getrandom(&buf, sizeof(buf), 0);
|
getrandom(&buf, sizeof(buf), 0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user