Module Name: src Committed By: pooka Date: Sun Apr 28 13:17:26 UTC 2013
Modified Files: src/lib/librumpuser: rumpuser.c rumpuser_port.h src/sys/rump/include/rump: rumpuser.h src/sys/rump/librump/rumpkern: emul.c intr.c rump.c vm.c src/sys/rump/net/lib/libshmif: if_shmem.c Log Message: 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). To generate a diff of this commit: cvs rdiff -u -r1.35 -r1.36 src/lib/librumpuser/rumpuser.c cvs rdiff -u -r1.17 -r1.18 src/lib/librumpuser/rumpuser_port.h cvs rdiff -u -r1.87 -r1.88 src/sys/rump/include/rump/rumpuser.h cvs rdiff -u -r1.155 -r1.156 src/sys/rump/librump/rumpkern/emul.c cvs rdiff -u -r1.37 -r1.38 src/sys/rump/librump/rumpkern/intr.c cvs rdiff -u -r1.261 -r1.262 src/sys/rump/librump/rumpkern/rump.c cvs rdiff -u -r1.138 -r1.139 src/sys/rump/librump/rumpkern/vm.c cvs rdiff -u -r1.49 -r1.50 src/sys/rump/net/lib/libshmif/if_shmem.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/librumpuser/rumpuser.c diff -u src/lib/librumpuser/rumpuser.c:1.35 src/lib/librumpuser/rumpuser.c:1.36 --- src/lib/librumpuser/rumpuser.c:1.35 Sun Apr 28 10:43:45 2013 +++ src/lib/librumpuser/rumpuser.c Sun Apr 28 13:17:25 2013 @@ -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, u 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,24 +515,97 @@ rumpuser_writev(int fd, const struct rum } 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) { Index: src/lib/librumpuser/rumpuser_port.h diff -u src/lib/librumpuser/rumpuser_port.h:1.17 src/lib/librumpuser/rumpuser_port.h:1.18 --- src/lib/librumpuser/rumpuser_port.h:1.17 Sat Apr 27 16:56:29 2013 +++ src/lib/librumpuser/rumpuser_port.h Sun Apr 28 13:17:26 2013 @@ -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__ Index: src/sys/rump/include/rump/rumpuser.h diff -u src/sys/rump/include/rump/rumpuser.h:1.87 src/sys/rump/include/rump/rumpuser.h:1.88 --- src/sys/rump/include/rump/rumpuser.h:1.87 Sun Apr 28 10:43:45 2013 +++ src/sys/rump/include/rump/rumpuser.h Sun Apr 28 13:17:24 2013 @@ -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 *, u #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 *); Index: src/sys/rump/librump/rumpkern/emul.c diff -u src/sys/rump/librump/rumpkern/emul.c:1.155 src/sys/rump/librump/rumpkern/emul.c:1.156 --- src/sys/rump/librump/rumpkern/emul.c:1.155 Mon Mar 18 13:36:23 2013 +++ src/sys/rump/librump/rumpkern/emul.c Sun Apr 28 13:17:24 2013 @@ -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 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; Index: src/sys/rump/librump/rumpkern/intr.c diff -u src/sys/rump/librump/rumpkern/intr.c:1.37 src/sys/rump/librump/rumpkern/intr.c:1.38 --- src/sys/rump/librump/rumpkern/intr.c:1.37 Sat Apr 27 16:32:57 2013 +++ src/sys/rump/librump/rumpkern/intr.c Sun Apr 28 13:17:24 2013 @@ -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 */ Index: src/sys/rump/librump/rumpkern/rump.c diff -u src/sys/rump/librump/rumpkern/rump.c:1.261 src/sys/rump/librump/rumpkern/rump.c:1.262 --- src/sys/rump/librump/rumpkern/rump.c:1.261 Sat Apr 27 16:32:57 2013 +++ src/sys/rump/librump/rumpkern/rump.c Sun Apr 28 13:17:25 2013 @@ -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); } } Index: src/sys/rump/librump/rumpkern/vm.c diff -u src/sys/rump/librump/rumpkern/vm.c:1.138 src/sys/rump/librump/rumpkern/vm.c:1.139 --- src/sys/rump/librump/rumpkern/vm.c:1.138 Sat Apr 27 15:34:53 2013 +++ src/sys/rump/librump/rumpkern/vm.c Sun Apr 28 13:17:25 2013 @@ -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; Index: src/sys/rump/net/lib/libshmif/if_shmem.c diff -u src/sys/rump/net/lib/libshmif/if_shmem.c:1.49 src/sys/rump/net/lib/libshmif/if_shmem.c:1.50 --- src/sys/rump/net/lib/libshmif/if_shmem.c:1.49 Sun Apr 28 10:53:21 2013 +++ src/sys/rump/net/lib/libshmif/if_shmem.c Sun Apr 28 13:17:25 2013 @@ -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;