mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 12:32:56 +01:00
136 lines
2.7 KiB
C++
136 lines
2.7 KiB
C++
/*
|
|
* \brief C-library back end
|
|
* \author Christian Prochaska
|
|
* \author Norman Feske
|
|
* \date 2010-05-19
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2010-2018 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU Affero General Public License version 3.
|
|
*/
|
|
|
|
/* Genode includes */
|
|
#include <base/log.h>
|
|
#include <vfs/vfs_handle.h>
|
|
|
|
/* libc includes */
|
|
#include <sys/time.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
|
|
/* libc-internal includes */
|
|
#include <internal/errno.h>
|
|
#include <internal/init.h>
|
|
#include <internal/current_time.h>
|
|
#include <internal/watch.h>
|
|
|
|
static Libc::Current_time *_current_time_ptr;
|
|
static Libc::Current_real_time *_current_real_time_ptr;
|
|
|
|
|
|
void Libc::init_time(Current_time ¤t_time,
|
|
Current_real_time ¤t_real_time)
|
|
{
|
|
_current_time_ptr = ¤t_time;
|
|
_current_real_time_ptr = ¤t_real_time;
|
|
}
|
|
|
|
|
|
using namespace Libc;
|
|
|
|
|
|
extern "C" __attribute__((weak))
|
|
int clock_gettime(clockid_t clk_id, struct timespec *ts)
|
|
{
|
|
using uint64_t = Libc::uint64_t;
|
|
|
|
if (!ts) return Errno(EFAULT);
|
|
|
|
struct Missing_call_of_init_time : Exception { };
|
|
|
|
auto current_time = [&] ()
|
|
{
|
|
if (!_current_time_ptr)
|
|
throw Missing_call_of_init_time();
|
|
|
|
return _current_time_ptr->current_time();
|
|
};
|
|
|
|
|
|
/* initialize timespec just in case users do not check for errors */
|
|
ts->tv_sec = 0;
|
|
ts->tv_nsec = 0;
|
|
|
|
switch (clk_id) {
|
|
|
|
/* IRL wall-time */
|
|
case CLOCK_REALTIME:
|
|
case CLOCK_SECOND: /* FreeBSD specific */
|
|
{
|
|
if (!_current_real_time_ptr)
|
|
throw Missing_call_of_init_time();
|
|
|
|
if (!_current_real_time_ptr->has_real_time()) {
|
|
warning("clock_gettime(): missing real-time clock");
|
|
return Errno(EINVAL);
|
|
}
|
|
|
|
*ts = _current_real_time_ptr->current_real_time();
|
|
break;
|
|
}
|
|
|
|
/* component uptime */
|
|
case CLOCK_MONOTONIC:
|
|
case CLOCK_UPTIME:
|
|
{
|
|
uint64_t us = current_time().trunc_to_plain_us().value;
|
|
|
|
ts->tv_sec = us / (1000*1000);
|
|
ts->tv_nsec = (us % (1000*1000)) * 1000;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
return Errno(EINVAL);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
extern "C" __attribute__((weak, alias("clock_gettime")))
|
|
int __sys_clock_gettime(clockid_t clk_id, struct timespec *ts);
|
|
|
|
|
|
extern "C" __attribute__((weak))
|
|
int gettimeofday(struct timeval *tv, struct timezone *)
|
|
{
|
|
if (!tv) return 0;
|
|
|
|
struct timespec ts;
|
|
|
|
if (int ret = clock_gettime(CLOCK_REALTIME, &ts))
|
|
return ret;
|
|
|
|
tv->tv_sec = ts.tv_sec;
|
|
tv->tv_usec = ts.tv_nsec / 1000;
|
|
return 0;
|
|
}
|
|
|
|
|
|
extern "C" __attribute__((weak, alias("gettimeofday")))
|
|
int __sys_gettimeofday(struct timeval *tv, struct timezone *);
|
|
|
|
|
|
extern "C"
|
|
clock_t clock()
|
|
{
|
|
error(__func__, " not implemented, use 'clock_gettime' instead");
|
|
return -1;
|
|
}
|