Improve the time-related hypercalls so that's it's possible to
sleep until an absolute time on the host's monotonic clock (should something like that be supported).
This commit is contained in:
parent
e0ab611267
commit
a53a2a5357
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rumpuser.c,v 1.35 2013/04/28 10:43:45 pooka Exp $ */
|
||||
/* $NetBSD: rumpuser.c,v 1.36 2013/04/28 13:17:25 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2010 Antti Kantee. All Rights Reserved.
|
||||
@ -28,7 +28,7 @@
|
||||
#include "rumpuser_port.h"
|
||||
|
||||
#if !defined(lint)
|
||||
__RCSID("$NetBSD: rumpuser.c,v 1.35 2013/04/28 10:43:45 pooka Exp $");
|
||||
__RCSID("$NetBSD: rumpuser.c,v 1.36 2013/04/28 13:17:25 pooka Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
@ -218,27 +218,6 @@ rumpuser_getfileinfo(const char *path, uint64_t *sizep, int *ftp, int *error)
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
rumpuser_nanosleep(uint64_t *sec, uint64_t *nsec, int *error)
|
||||
{
|
||||
struct timespec rqt, rmt;
|
||||
int rv;
|
||||
|
||||
/*LINTED*/
|
||||
rqt.tv_sec = *sec;
|
||||
/*LINTED*/
|
||||
rqt.tv_nsec = *nsec;
|
||||
|
||||
KLOCK_WRAP(rv = nanosleep(&rqt, &rmt));
|
||||
if (rv == -1)
|
||||
seterror(errno);
|
||||
|
||||
*sec = rmt.tv_sec;
|
||||
*nsec = rmt.tv_nsec;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void *
|
||||
rumpuser_malloc(size_t howmuch, int alignment)
|
||||
{
|
||||
@ -536,23 +515,96 @@ rumpuser_writev(int fd, const struct rumpuser_iovec *riov, int iovcnt,
|
||||
}
|
||||
|
||||
int
|
||||
rumpuser_gettime(uint64_t *sec, uint64_t *nsec, int *error)
|
||||
rumpuser_clock_gettime(uint64_t *sec, uint64_t *nsec, enum rumpclock rclk)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timespec ts;
|
||||
clockid_t clk;
|
||||
int rv;
|
||||
|
||||
rv = gettimeofday(&tv, NULL);
|
||||
if (rv == -1) {
|
||||
seterror(errno);
|
||||
return rv;
|
||||
switch (rclk) {
|
||||
case RUMPUSER_CLOCK_RELWALL:
|
||||
clk = CLOCK_REALTIME;
|
||||
break;
|
||||
case RUMPUSER_CLOCK_ABSMONO:
|
||||
#ifdef HAVE_CLOCK_NANOSLEEP
|
||||
clk = CLOCK_MONOTONIC;
|
||||
#else
|
||||
clk = CLOCK_REALTIME;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
*sec = tv.tv_sec;
|
||||
*nsec = tv.tv_usec * 1000;
|
||||
rv = clock_gettime(clk, &ts);
|
||||
if (rv == -1) {
|
||||
return errno;
|
||||
}
|
||||
*sec = ts.tv_sec;
|
||||
*nsec = ts.tv_nsec;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rumpuser_clock_sleep(uint64_t sec, uint64_t nsec, enum rumpclock clk)
|
||||
{
|
||||
struct timespec rqt, rmt;
|
||||
int nlocks;
|
||||
int rv;
|
||||
|
||||
rumpuser__unschedule(0, &nlocks, NULL);
|
||||
|
||||
/*LINTED*/
|
||||
rqt.tv_sec = sec;
|
||||
/*LINTED*/
|
||||
rqt.tv_nsec = nsec;
|
||||
|
||||
switch (clk) {
|
||||
case RUMPUSER_CLOCK_RELWALL:
|
||||
do {
|
||||
rv = nanosleep(&rqt, &rmt);
|
||||
rqt = rmt;
|
||||
} while (rv == -1 && errno == EINTR);
|
||||
if (rv == -1) {
|
||||
rv = errno;
|
||||
}
|
||||
break;
|
||||
case RUMPUSER_CLOCK_ABSMONO:
|
||||
do {
|
||||
#ifdef HAVE_CLOCK_NANOSLEEP
|
||||
rv = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME,
|
||||
&rqt, NULL);
|
||||
#else
|
||||
/* le/la/der/die/das sigh. timevalspec tailspin */
|
||||
struct timespec ts, tsr;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
if (ts.tv_sec == rqt.tv_sec ?
|
||||
ts.tv_nsec > rqt.tv_nsec : ts.tv_sec > rqt.tv_sec) {
|
||||
rv = 0;
|
||||
} else {
|
||||
tsr.tv_sec = rqt.tv_sec - ts.tv_sec;
|
||||
tsr.tv_nsec = rqt.tv_nsec - ts.tv_nsec;
|
||||
if (tsr.tv_nsec < 0) {
|
||||
tsr.tv_sec--;
|
||||
tsr.tv_nsec += 1000*1000*1000;
|
||||
}
|
||||
rv = nanosleep(&tsr, NULL);
|
||||
}
|
||||
#endif
|
||||
} while (rv == -1 && errno == EINTR);
|
||||
if (rv == -1) {
|
||||
rv = errno;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
rumpuser__reschedule(nlocks, NULL);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
rumpuser_getenv(const char *name, char *buf, size_t blen, int *error)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rumpuser_port.h,v 1.17 2013/04/27 16:56:29 pooka Exp $ */
|
||||
/* $NetBSD: rumpuser_port.h,v 1.18 2013/04/28 13:17:26 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Portability header for non-NetBSD platforms.
|
||||
@ -31,11 +31,20 @@
|
||||
#define PLATFORM_HAS_NBQUOTA
|
||||
#endif
|
||||
|
||||
#if __NetBSD_Prereq__(6,99,16)
|
||||
#define HAVE_CLOCK_NANOSLEEP
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This includes also statvfs1() and fstatvfs1(). They could be
|
||||
* reasonably easily emulated on other platforms.
|
||||
*/
|
||||
#define PLATFORM_HAS_NBVFSSTAT
|
||||
#endif /* __NetBSD__ */
|
||||
|
||||
/* might not be 100% accurate, maybe need to revisit later */
|
||||
#if defined(__linux__) || defined(__sun__)
|
||||
#define HAVE_CLOCK_NANOSLEEP
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: rumpuser.h,v 1.87 2013/04/28 10:43:45 pooka Exp $ */
|
||||
/* $NetBSD: rumpuser.h,v 1.88 2013/04/28 13:17:24 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2011 Antti Kantee. All Rights Reserved.
|
||||
* Copyright (c) 2007-2013 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -52,7 +52,6 @@ int rumpuser_getfileinfo(const char *, uint64_t *, int *, int *);
|
||||
#define RUMPUSER_FT_REG 2
|
||||
#define RUMPUSER_FT_BLK 3
|
||||
#define RUMPUSER_FT_CHR 4
|
||||
int rumpuser_nanosleep(uint64_t *, uint64_t *, int *);
|
||||
|
||||
void *rumpuser_malloc(size_t, int);
|
||||
void rumpuser_free(void *, size_t);
|
||||
@ -99,7 +98,10 @@ struct rumpuser_iovec {
|
||||
ssize_t rumpuser_readv(int, const struct rumpuser_iovec *, int, int *);
|
||||
ssize_t rumpuser_writev(int, const struct rumpuser_iovec *, int, int *);
|
||||
|
||||
int rumpuser_gettime(uint64_t *, uint64_t *, int *);
|
||||
enum rumpclock { RUMPUSER_CLOCK_RELWALL, RUMPUSER_CLOCK_ABSMONO };
|
||||
int rumpuser_clock_gettime(uint64_t *, uint64_t *, enum rumpclock);
|
||||
int rumpuser_clock_sleep(uint64_t, uint64_t, enum rumpclock);
|
||||
|
||||
int rumpuser_getenv(const char *, char *, size_t, int *);
|
||||
|
||||
int rumpuser_gethostname(char *, size_t, int *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: emul.c,v 1.155 2013/03/18 13:36:23 para Exp $ */
|
||||
/* $NetBSD: emul.c,v 1.156 2013/04/28 13:17:24 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2011 Antti Kantee. All Rights Reserved.
|
||||
@ -26,7 +26,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: emul.c,v 1.155 2013/03/18 13:36:23 para Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: emul.c,v 1.156 2013/04/28 13:17:24 pooka Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/null.h>
|
||||
@ -144,7 +144,7 @@ int
|
||||
kpause(const char *wmesg, bool intr, int timeo, kmutex_t *mtx)
|
||||
{
|
||||
extern int hz;
|
||||
int rv, error;
|
||||
int rv;
|
||||
uint64_t sec, nsec;
|
||||
|
||||
if (mtx)
|
||||
@ -152,14 +152,12 @@ kpause(const char *wmesg, bool intr, int timeo, kmutex_t *mtx)
|
||||
|
||||
sec = timeo / hz;
|
||||
nsec = (timeo % hz) * (1000000000 / hz);
|
||||
rv = rumpuser_nanosleep(&sec, &nsec, &error);
|
||||
|
||||
rv = rumpuser_clock_sleep(sec, nsec, RUMPUSER_CLOCK_RELWALL);
|
||||
KASSERT(rv == 0);
|
||||
|
||||
if (mtx)
|
||||
mutex_enter(mtx);
|
||||
|
||||
if (rv)
|
||||
return error;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -225,7 +223,6 @@ static void
|
||||
rump_delay(unsigned int us)
|
||||
{
|
||||
uint64_t sec, nsec;
|
||||
int error;
|
||||
|
||||
sec = us / 1000000;
|
||||
nsec = (us % 1000000) * 1000;
|
||||
@ -233,7 +230,7 @@ rump_delay(unsigned int us)
|
||||
if (__predict_false(sec != 0))
|
||||
printf("WARNING: over 1s delay\n");
|
||||
|
||||
rumpuser_nanosleep(&sec, &nsec, &error);
|
||||
rumpuser_clock_sleep(sec, nsec, RUMPUSER_CLOCK_RELWALL);
|
||||
}
|
||||
void (*delay_func)(unsigned int) = rump_delay;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: intr.c,v 1.37 2013/04/27 16:32:57 pooka Exp $ */
|
||||
/* $NetBSD: intr.c,v 1.38 2013/04/28 13:17:24 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008-2010 Antti Kantee. All Rights Reserved.
|
||||
@ -26,7 +26,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.37 2013/04/27 16:32:57 pooka Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.38 2013/04/28 13:17:24 pooka Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/atomic.h>
|
||||
@ -99,38 +99,27 @@ static struct timecounter rumptc = {
|
||||
static void
|
||||
doclock(void *noarg)
|
||||
{
|
||||
struct timespec clockbase, clockup;
|
||||
struct timespec thetick, curtime;
|
||||
struct rumpuser_cv *clockcv;
|
||||
struct rumpuser_mtx *clockmtx;
|
||||
struct timespec thetick, curclock;
|
||||
uint64_t sec, nsec;
|
||||
int error;
|
||||
extern int hz;
|
||||
|
||||
memset(&clockup, 0, sizeof(clockup));
|
||||
rumpuser_gettime(&sec, &nsec, &error);
|
||||
clockbase.tv_sec = sec;
|
||||
clockbase.tv_nsec = nsec;
|
||||
curtime = clockbase;
|
||||
error = rumpuser_clock_gettime(&sec, &nsec, RUMPUSER_CLOCK_ABSMONO);
|
||||
if (error)
|
||||
panic("clock: cannot get monotonic time");
|
||||
|
||||
curclock.tv_sec = sec;
|
||||
curclock.tv_nsec = nsec;
|
||||
thetick.tv_sec = 0;
|
||||
thetick.tv_nsec = 1000000000/hz;
|
||||
|
||||
/* XXX: dummies */
|
||||
rumpuser_cv_init(&clockcv);
|
||||
rumpuser_mutex_init(&clockmtx, RUMPUSER_MTX_SPIN);
|
||||
|
||||
rumpuser_mutex_enter_nowrap(clockmtx);
|
||||
for (;;) {
|
||||
callout_hardclock();
|
||||
|
||||
/* wait until the next tick. XXX: what if the clock changes? */
|
||||
while (rumpuser_cv_timedwait(clockcv, clockmtx,
|
||||
curtime.tv_sec, curtime.tv_nsec) == 0)
|
||||
continue;
|
||||
|
||||
/* XXX: sync with a) virtual clock b) host clock */
|
||||
timespecadd(&clockup, &clockbase, &curtime);
|
||||
timespecadd(&clockup, &thetick, &clockup);
|
||||
error = rumpuser_clock_sleep(curclock.tv_sec, curclock.tv_nsec,
|
||||
RUMPUSER_CLOCK_ABSMONO);
|
||||
KASSERT(!error);
|
||||
timespecadd(&curclock, &thetick, &curclock);
|
||||
|
||||
#if 0
|
||||
/* CPU_IS_PRIMARY is MD and hence unreliably correct here */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rump.c,v 1.261 2013/04/27 16:32:57 pooka Exp $ */
|
||||
/* $NetBSD: rump.c,v 1.262 2013/04/28 13:17:25 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2011 Antti Kantee. All Rights Reserved.
|
||||
@ -26,7 +26,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.261 2013/04/27 16:32:57 pooka Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.262 2013/04/28 13:17:25 pooka Exp $");
|
||||
|
||||
#include <sys/systm.h>
|
||||
#define ELFSIZE ARCH_ELFSIZE
|
||||
@ -274,7 +274,7 @@ rump_init(void)
|
||||
rump_thread_init();
|
||||
rump_cpus_bootstrap(&numcpu);
|
||||
|
||||
rumpuser_gettime(&sec, &nsec, &error);
|
||||
rumpuser_clock_gettime(&sec, &nsec, RUMPUSER_CLOCK_RELWALL);
|
||||
boottime.tv_sec = sec;
|
||||
boottime.tv_nsec = nsec;
|
||||
|
||||
@ -352,9 +352,7 @@ rump_init(void)
|
||||
inittimecounter();
|
||||
ntp_init();
|
||||
|
||||
rumpuser_gettime(&sec, &nsec, &error);
|
||||
ts.tv_sec = sec;
|
||||
ts.tv_nsec = nsec;
|
||||
ts = boottime;
|
||||
tc_setclock(&ts);
|
||||
|
||||
/* we are mostly go. do per-cpu subsystem init */
|
||||
@ -568,10 +566,7 @@ cpu_reboot(int howto, char *bootstr)
|
||||
printf("rump kernel halted\n");
|
||||
rumpuser_sp_fini(finiarg);
|
||||
for (;;) {
|
||||
uint64_t sec = 5, nsec = 0;
|
||||
int error;
|
||||
|
||||
rumpuser_nanosleep(&sec, &nsec, &error);
|
||||
rumpuser_clock_sleep(10, 0, RUMPUSER_CLOCK_RELWALL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vm.c,v 1.138 2013/04/27 15:34:53 pooka Exp $ */
|
||||
/* $NetBSD: vm.c,v 1.139 2013/04/28 13:17:25 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2011 Antti Kantee. All Rights Reserved.
|
||||
@ -41,7 +41,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.138 2013/04/27 15:34:53 pooka Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: vm.c,v 1.139 2013/04/28 13:17:25 pooka Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/atomic.h>
|
||||
@ -1078,11 +1078,7 @@ uvm_pageout(void *arg)
|
||||
* the game soon.
|
||||
*/
|
||||
if (cleaned == 0 && lockrunning) {
|
||||
uint64_t sec, nsec;
|
||||
|
||||
sec = 0;
|
||||
nsec = 1;
|
||||
rumpuser_nanosleep(&sec, &nsec, NULL);
|
||||
rumpuser_clock_sleep(0, 1, RUMPUSER_CLOCK_RELWALL);
|
||||
|
||||
lockrunning = false;
|
||||
skip = 0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_shmem.c,v 1.49 2013/04/28 10:53:21 pooka Exp $ */
|
||||
/* $NetBSD: if_shmem.c,v 1.50 2013/04/28 13:17:25 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 Antti Kantee. All Rights Reserved.
|
||||
@ -28,7 +28,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_shmem.c,v 1.49 2013/04/28 10:53:21 pooka Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_shmem.c,v 1.50 2013/04/28 13:17:25 pooka Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/atomic.h>
|
||||
@ -122,12 +122,9 @@ shmif_lockbus(struct shmif_mem *busmem)
|
||||
while (__predict_false(atomic_cas_32(&busmem->shm_lock,
|
||||
LOCK_UNLOCKED, LOCK_LOCKED) == LOCK_LOCKED)) {
|
||||
if (__predict_false(++i > LOCK_COOLDOWN)) {
|
||||
uint64_t sec, nsec;
|
||||
int error;
|
||||
|
||||
sec = 0;
|
||||
nsec = 1000*1000; /* 1ms */
|
||||
rumpuser_nanosleep(&sec, &nsec, &error);
|
||||
/* wait 1ms */
|
||||
rumpuser_clock_sleep(0, 1000*1000,
|
||||
RUMPUSER_CLOCK_RELWALL);
|
||||
i = 0;
|
||||
}
|
||||
continue;
|
||||
|
Loading…
Reference in New Issue
Block a user