From: Antti Kantee Date: Tue, 21 Apr 2015 12:34:59 +0000 (+0000) Subject: Rename librumprun_rumpuser to libbmk_rumpuser X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=5c57bf1ecae753845b3fed285675d6994ef35620;p=people%2Fliuw%2Frumprun.git Rename librumprun_rumpuser to libbmk_rumpuser Layeristically speaking, the common rumpuser bits run on top of bmk, so the renamed name now also reflects reality (and matches the header namespace). --- diff --git a/lib/libbmk_rumpuser/Makefile b/lib/libbmk_rumpuser/Makefile new file mode 100644 index 0000000..78da6ac --- /dev/null +++ b/lib/libbmk_rumpuser/Makefile @@ -0,0 +1,14 @@ +LIB= bmk_rumpuser +LIBISPRIVATE= # defined + +SRCS= rumpuser_base.c +SRCS+= rumpuser_clock.c +SRCS+= rumpuser_cons.c +SRCS+= rumpuser_mem.c +SRCS+= rumpuser_synch.c + +SRCS+= rumpuser_stubs.c + +CPPFLAGS+= -I${.CURDIR}/../../include + +.include diff --git a/lib/libbmk_rumpuser/rumpuser_base.c b/lib/libbmk_rumpuser/rumpuser_base.c new file mode 100644 index 0000000..1958e20 --- /dev/null +++ b/lib/libbmk_rumpuser/rumpuser_base.c @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include + +struct rumpuser_hyperup rumpuser__hyp; + +#define RUMPHYPER_MYVERSION 17 + +int +rumpuser_init(int version, const struct rumpuser_hyperup *hyp) +{ + + if (version != RUMPHYPER_MYVERSION) { + bmk_platform_halt("rump kernel hypercall revision mismatch\n"); + /* NOTREACHED */ + } + + rumpuser__hyp = *hyp; + + return rumprun_platform_rumpuser_init(); +} + +void +rumpuser_exit(int value) +{ + + bmk_platform_halt(value == 0 ? NULL : "rumpuser panic"); +} + +void +rumpuser_seterrno(int err) +{ + int *threrr = bmk_sched_geterrno(); + + *threrr = err; +} diff --git a/lib/libbmk_rumpuser/rumpuser_clock.c b/lib/libbmk_rumpuser/rumpuser_clock.c new file mode 100644 index 0000000..746bc68 --- /dev/null +++ b/lib/libbmk_rumpuser/rumpuser_clock.c @@ -0,0 +1,76 @@ +/*- + * Copyright (c) 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include +#include + +int +rumpuser_clock_gettime(int which, int64_t *sec, long *nsec) +{ + bmk_time_t time; + + time = bmk_clock_monotonic(); + + switch (which) { + case RUMPUSER_CLOCK_RELWALL: + time += bmk_clock_epochoffset(); + break; + case RUMPUSER_CLOCK_ABSMONO: + break; + } + + *sec = time / (1000*1000*1000ULL); + *nsec = time % (1000*1000*1000ULL); + + return 0; +} + +int +rumpuser_clock_sleep(int enum_rumpclock, int64_t sec, long nsec) +{ + enum rumpclock rclk = enum_rumpclock; + bmk_time_t totnsec; + int nlocks; + + rumpkern_unsched(&nlocks, NULL); + totnsec = sec * 1000*1000*1000 + nsec; + switch (rclk) { + case RUMPUSER_CLOCK_RELWALL: + bmk_sched_nanosleep(totnsec); + break; + case RUMPUSER_CLOCK_ABSMONO: + bmk_sched_nanosleep_abstime(totnsec); + break; + } + rumpkern_sched(nlocks, NULL); + + return 0; +} diff --git a/lib/libbmk_rumpuser/rumpuser_cons.c b/lib/libbmk_rumpuser/rumpuser_cons.c new file mode 100644 index 0000000..173c2af --- /dev/null +++ b/lib/libbmk_rumpuser/rumpuser_cons.c @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2015 Antti Kantee. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#define _BMK_PRINTF_VA + +#include + +#include +#include + +void +rumpuser_putchar(int c) +{ + + bmk_printf("%c", c); +} + +void +rumpuser_dprintf(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + bmk_vprintf(fmt, ap); + va_end(ap); +} diff --git a/lib/libbmk_rumpuser/rumpuser_mem.c b/lib/libbmk_rumpuser/rumpuser_mem.c new file mode 100644 index 0000000..4ac2ed4 --- /dev/null +++ b/lib/libbmk_rumpuser/rumpuser_mem.c @@ -0,0 +1,75 @@ +/*- + * Copyright (c) 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include +#include + +int +rumpuser_malloc(size_t len, int alignment, void **retval) +{ + + /* + * If we are allocating precisely a page-sized chunk + * (the common case), use the underlying page allocator directly. + * This avoids the malloc header overhead for this very + * common allocation, leading to 50% better memory use. + * We can't easily use the page allocator for larger chucks + * of memory, since those allocations might have stricter + * alignment restrictions, and therefore it's just + * easier to use memalloc() in those rare cases; it's not + * as wasteful for larger chunks anyway. + * + * XXX: how to make sure that rump kernel's and our + * page sizes are the same? Could be problematic especially + * for architectures which support multiple page sizes. + * Note that the code will continue to work, but the optimization + * will not trigger for the common case. + */ + if (len == bmk_pagesize) { + bmk_assert(alignment <= bmk_pagesize); + *retval = bmk_platform_allocpg2(0); + } else { + *retval = bmk_memalloc(len, alignment); + } + if (*retval) + return 0; + else + return BMK_ENOMEM; +} + +void +rumpuser_free(void *buf, size_t buflen) +{ + + if (buflen == bmk_pagesize) + bmk_platform_freepg2(buf, 0); + else + bmk_memfree(buf); +} diff --git a/lib/libbmk_rumpuser/rumpuser_stubs.c b/lib/libbmk_rumpuser/rumpuser_stubs.c new file mode 100644 index 0000000..f1c64a5 --- /dev/null +++ b/lib/libbmk_rumpuser/rumpuser_stubs.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2014 Antti Kantee. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Stub implementations for various rump kernel hypercalls that + * are not supported on these platforms. This file should go away + * with the next revision of the rump kernel hypercall interface. + */ + +#include + +int rumpuser_stub_nothing(void); +int rumpuser_stub_nothing(void) {return 0;} +#define NOTHING(name) \ +int name(void) __attribute__((alias("rumpuser_stub_nothing"))); + +int rumpuser_stub_enosys(void); +int rumpuser_stub_enosys(void) {return BMK_ENOSYS;} +#define NOSYS(name) \ +int name(void) __attribute__((alias("rumpuser_stub_enosys"))); + +NOTHING(rumpuser_dl_bootstrap); + +NOSYS(rumpuser_anonmmap); +NOSYS(rumpuser_unmap); + +NOSYS(rumpuser_kill); + +NOSYS(rumpuser_daemonize_begin); +NOSYS(rumpuser_daemonize_done); + +NOSYS(rumpuser_iovread); +NOSYS(rumpuser_iovwrite); diff --git a/lib/libbmk_rumpuser/rumpuser_synch.c b/lib/libbmk_rumpuser/rumpuser_synch.c new file mode 100644 index 0000000..8846efa --- /dev/null +++ b/lib/libbmk_rumpuser/rumpuser_synch.c @@ -0,0 +1,481 @@ +/* + * Copyright (c) 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * El-simplo threading/locking hypercalls for rump kernels, + * assumes one (1) CPU with non-preemptable scheduling. + * These are never used from interrupt context, so we don't need + * anything fancy. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define WAIT_NOTIMEOUT -1 + +TAILQ_HEAD(waithead, waiter); +struct waiter { + struct bmk_thread *who; + TAILQ_ENTRY(waiter) entries; + int onlist; +}; + +static int +wait(struct waithead *wh, bmk_time_t nsec) +{ + struct waiter w; + bmk_time_t wakeup; + + w.who = bmk_sched_current(); + TAILQ_INSERT_TAIL(wh, &w, entries); + w.onlist = 1; + if (nsec != WAIT_NOTIMEOUT) + wakeup = bmk_clock_monotonic() + nsec; + bmk_sched_block_timeout(w.who, wakeup); + bmk_sched(); + + /* woken up by timeout? */ + if (w.onlist) + TAILQ_REMOVE(wh, &w, entries); + + return w.onlist ? BMK_ETIMEDOUT : 0; +} + +static void +wakeup_one(struct waithead *wh) +{ + struct waiter *w; + + if ((w = TAILQ_FIRST(wh)) != NULL) { + TAILQ_REMOVE(wh, w, entries); + w->onlist = 0; + bmk_sched_wake(w->who); + } +} + +static void +wakeup_all(struct waithead *wh) +{ + struct waiter *w; + + while ((w = TAILQ_FIRST(wh)) != NULL) { + TAILQ_REMOVE(wh, w, entries); + w->onlist = 0; + bmk_sched_wake(w->who); + } +} + +int +rumpuser_thread_create(void *(*f)(void *), void *arg, const char *thrname, + int joinable, int pri, int cpuidx, void **tptr) +{ + struct bmk_thread *thr; + + thr = bmk_sched_create(thrname, NULL, joinable, + (void (*)(void *))f, arg, NULL, 0); + if (!thr) + return BMK_EINVAL; + + *tptr = thr; + return 0; +} + +void +rumpuser_thread_exit(void) +{ + + bmk_sched_exit(); +} + +int +rumpuser_thread_join(void *p) +{ + + bmk_sched_join(p); + return 0; +} + +struct rumpuser_mtx { + struct waithead waiters; + int v; + int flags; + struct lwp *o; +}; + +void +rumpuser_mutex_init(struct rumpuser_mtx **mtxp, int flags) +{ + struct rumpuser_mtx *mtx; + + mtx = bmk_memcalloc(1, sizeof(*mtx)); + mtx->flags = flags; + TAILQ_INIT(&mtx->waiters); + *mtxp = mtx; +} + +void +rumpuser_mutex_enter(struct rumpuser_mtx *mtx) +{ + int nlocks; + + if (rumpuser_mutex_tryenter(mtx) != 0) { + rumpkern_unsched(&nlocks, NULL); + while (rumpuser_mutex_tryenter(mtx) != 0) + wait(&mtx->waiters, WAIT_NOTIMEOUT); + rumpkern_sched(nlocks, NULL); + } +} + +void +rumpuser_mutex_enter_nowrap(struct rumpuser_mtx *mtx) +{ + int rv; + + rv = rumpuser_mutex_tryenter(mtx); + /* one VCPU supported, no preemption => must succeed */ + if (rv != 0) { + bmk_platform_halt("rumpuser mutex error"); + } +} + +int +rumpuser_mutex_tryenter(struct rumpuser_mtx *mtx) +{ + struct lwp *l = rumpuser_curlwp(); + + if (mtx->v && mtx->o != l) + return BMK_EBUSY; + + mtx->v++; + mtx->o = l; + + return 0; +} + +void +rumpuser_mutex_exit(struct rumpuser_mtx *mtx) +{ + + bmk_assert(mtx->v > 0); + if (--mtx->v == 0) { + mtx->o = NULL; + wakeup_one(&mtx->waiters); + } +} + +void +rumpuser_mutex_destroy(struct rumpuser_mtx *mtx) +{ + + bmk_assert(TAILQ_EMPTY(&mtx->waiters) && mtx->o == NULL); + bmk_memfree(mtx); +} + +void +rumpuser_mutex_owner(struct rumpuser_mtx *mtx, struct lwp **lp) +{ + + *lp = mtx->o; +} + +struct rumpuser_rw { + struct waithead rwait; + struct waithead wwait; + int v; + struct lwp *o; +}; + +void +rumpuser_rw_init(struct rumpuser_rw **rwp) +{ + struct rumpuser_rw *rw; + + rw = bmk_memcalloc(1, sizeof(*rw)); + TAILQ_INIT(&rw->rwait); + TAILQ_INIT(&rw->wwait); + + *rwp = rw; +} + +void +rumpuser_rw_enter(int enum_rumprwlock, struct rumpuser_rw *rw) +{ + enum rumprwlock lk = enum_rumprwlock; + struct waithead *w = NULL; + int nlocks; + + switch (lk) { + case RUMPUSER_RW_WRITER: + w = &rw->wwait; + break; + case RUMPUSER_RW_READER: + w = &rw->rwait; + break; + } + + if (rumpuser_rw_tryenter(enum_rumprwlock, rw) != 0) { + rumpkern_unsched(&nlocks, NULL); + while (rumpuser_rw_tryenter(enum_rumprwlock, rw) != 0) + wait(w, WAIT_NOTIMEOUT); + rumpkern_sched(nlocks, NULL); + } +} + +int +rumpuser_rw_tryenter(int enum_rumprwlock, struct rumpuser_rw *rw) +{ + enum rumprwlock lk = enum_rumprwlock; + int rv = -1; + + switch (lk) { + case RUMPUSER_RW_WRITER: + if (rw->o == NULL) { + rw->o = rumpuser_curlwp(); + rv = 0; + } else { + rv = BMK_EBUSY; + } + break; + case RUMPUSER_RW_READER: + if (rw->o == NULL && TAILQ_EMPTY(&rw->wwait)) { + rw->v++; + rv = 0; + } else { + rv = BMK_EBUSY; + } + break; + } + + return rv; +} + +void +rumpuser_rw_exit(struct rumpuser_rw *rw) +{ + + if (rw->o) { + rw->o = NULL; + } else { + rw->v--; + } + + /* standard procedure, don't let readers starve out writers */ + if (!TAILQ_EMPTY(&rw->wwait)) { + if (rw->o == NULL) + wakeup_one(&rw->wwait); + } else if (!TAILQ_EMPTY(&rw->rwait) && rw->o == NULL) { + wakeup_all(&rw->rwait); + } +} + +void +rumpuser_rw_destroy(struct rumpuser_rw *rw) +{ + + bmk_memfree(rw); +} + +void +rumpuser_rw_held(int enum_rumprwlock, struct rumpuser_rw *rw, int *rvp) +{ + enum rumprwlock lk = enum_rumprwlock; + + switch (lk) { + case RUMPUSER_RW_WRITER: + *rvp = rw->o == rumpuser_curlwp(); + break; + case RUMPUSER_RW_READER: + *rvp = rw->v > 0; + break; + } +} + +void +rumpuser_rw_downgrade(struct rumpuser_rw *rw) +{ + + bmk_assert(rw->o == rumpuser_curlwp()); + rw->v = -1; +} + +int +rumpuser_rw_tryupgrade(struct rumpuser_rw *rw) +{ + + if (rw->v == -1) { + rw->v = 1; + rw->o = rumpuser_curlwp(); + return 0; + } + + return BMK_EBUSY; +} + +struct rumpuser_cv { + struct waithead waiters; + int nwaiters; +}; + +void +rumpuser_cv_init(struct rumpuser_cv **cvp) +{ + struct rumpuser_cv *cv; + + cv = bmk_memcalloc(1, sizeof(*cv)); + TAILQ_INIT(&cv->waiters); + *cvp = cv; +} + +void +rumpuser_cv_destroy(struct rumpuser_cv *cv) +{ + + bmk_assert(cv->nwaiters == 0); + bmk_memfree(cv); +} + +static void +cv_unsched(struct rumpuser_mtx *mtx, int *nlocks) +{ + + rumpkern_unsched(nlocks, mtx); + rumpuser_mutex_exit(mtx); +} + +static void +cv_resched(struct rumpuser_mtx *mtx, int nlocks) +{ + + /* see rumpuser(3) */ + if ((mtx->flags & (RUMPUSER_MTX_KMUTEX | RUMPUSER_MTX_SPIN)) == + (RUMPUSER_MTX_KMUTEX | RUMPUSER_MTX_SPIN)) { + rumpkern_sched(nlocks, mtx); + rumpuser_mutex_enter_nowrap(mtx); + } else { + rumpuser_mutex_enter_nowrap(mtx); + rumpkern_sched(nlocks, mtx); + } +} + +void +rumpuser_cv_wait(struct rumpuser_cv *cv, struct rumpuser_mtx *mtx) +{ + int nlocks; + + cv->nwaiters++; + cv_unsched(mtx, &nlocks); + wait(&cv->waiters, WAIT_NOTIMEOUT); + cv_resched(mtx, nlocks); + cv->nwaiters--; +} + +void +rumpuser_cv_wait_nowrap(struct rumpuser_cv *cv, struct rumpuser_mtx *mtx) +{ + + cv->nwaiters++; + rumpuser_mutex_exit(mtx); + wait(&cv->waiters, WAIT_NOTIMEOUT); + rumpuser_mutex_enter_nowrap(mtx); + cv->nwaiters--; +} + +int +rumpuser_cv_timedwait(struct rumpuser_cv *cv, struct rumpuser_mtx *mtx, + int64_t sec, int64_t nsec) +{ + int nlocks; + int rv; + + cv->nwaiters++; + cv_unsched(mtx, &nlocks); + rv = wait(&cv->waiters, sec * 1000*1000*1000ULL + nsec); + cv_resched(mtx, nlocks); + cv->nwaiters--; + + return rv; +} + +void +rumpuser_cv_signal(struct rumpuser_cv *cv) +{ + + wakeup_one(&cv->waiters); +} + +void +rumpuser_cv_broadcast(struct rumpuser_cv *cv) +{ + + wakeup_all(&cv->waiters); +} + +void +rumpuser_cv_has_waiters(struct rumpuser_cv *cv, int *rvp) +{ + + *rvp = cv->nwaiters != 0; +} + +/* + * curlwp + */ + +void +rumpuser_curlwpop(int enum_rumplwpop, struct lwp *l) +{ + struct bmk_thread *thread; + enum rumplwpop op = enum_rumplwpop; + + switch (op) { + case RUMPUSER_LWP_CREATE: + case RUMPUSER_LWP_DESTROY: + break; + case RUMPUSER_LWP_SET: + bmk_assert(rumpuser_curlwp() == NULL); + thread = bmk_sched_current(); + bmk_sched_settls(thread, 0, l); + break; + case RUMPUSER_LWP_CLEAR: + bmk_assert(rumpuser_curlwp() == l); + thread = bmk_sched_current(); + bmk_sched_settls(thread, 0, NULL); + break; + } +} + +struct lwp * +rumpuser_curlwp(void) +{ + + return bmk_sched_gettls(bmk_sched_current(), 0); +} diff --git a/lib/librumprun_rumpuser/Makefile b/lib/librumprun_rumpuser/Makefile deleted file mode 100644 index 1e1651b..0000000 --- a/lib/librumprun_rumpuser/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -LIB= rumprun_rumpuser -LIBISPRIVATE= # defined - -SRCS= rumpuser_base.c -SRCS+= rumpuser_clock.c -SRCS+= rumpuser_cons.c -SRCS+= rumpuser_mem.c -SRCS+= rumpuser_synch.c - -SRCS+= rumpuser_stubs.c - -CPPFLAGS+= -I${.CURDIR}/../../include - -.include diff --git a/lib/librumprun_rumpuser/rumpuser_base.c b/lib/librumprun_rumpuser/rumpuser_base.c deleted file mode 100644 index 1958e20..0000000 --- a/lib/librumprun_rumpuser/rumpuser_base.c +++ /dev/null @@ -1,64 +0,0 @@ -/*- - * Copyright (c) 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 - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include - -#include -#include - -struct rumpuser_hyperup rumpuser__hyp; - -#define RUMPHYPER_MYVERSION 17 - -int -rumpuser_init(int version, const struct rumpuser_hyperup *hyp) -{ - - if (version != RUMPHYPER_MYVERSION) { - bmk_platform_halt("rump kernel hypercall revision mismatch\n"); - /* NOTREACHED */ - } - - rumpuser__hyp = *hyp; - - return rumprun_platform_rumpuser_init(); -} - -void -rumpuser_exit(int value) -{ - - bmk_platform_halt(value == 0 ? NULL : "rumpuser panic"); -} - -void -rumpuser_seterrno(int err) -{ - int *threrr = bmk_sched_geterrno(); - - *threrr = err; -} diff --git a/lib/librumprun_rumpuser/rumpuser_clock.c b/lib/librumprun_rumpuser/rumpuser_clock.c deleted file mode 100644 index 746bc68..0000000 --- a/lib/librumprun_rumpuser/rumpuser_clock.c +++ /dev/null @@ -1,76 +0,0 @@ -/*- - * Copyright (c) 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 - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include - -#include -#include - -int -rumpuser_clock_gettime(int which, int64_t *sec, long *nsec) -{ - bmk_time_t time; - - time = bmk_clock_monotonic(); - - switch (which) { - case RUMPUSER_CLOCK_RELWALL: - time += bmk_clock_epochoffset(); - break; - case RUMPUSER_CLOCK_ABSMONO: - break; - } - - *sec = time / (1000*1000*1000ULL); - *nsec = time % (1000*1000*1000ULL); - - return 0; -} - -int -rumpuser_clock_sleep(int enum_rumpclock, int64_t sec, long nsec) -{ - enum rumpclock rclk = enum_rumpclock; - bmk_time_t totnsec; - int nlocks; - - rumpkern_unsched(&nlocks, NULL); - totnsec = sec * 1000*1000*1000 + nsec; - switch (rclk) { - case RUMPUSER_CLOCK_RELWALL: - bmk_sched_nanosleep(totnsec); - break; - case RUMPUSER_CLOCK_ABSMONO: - bmk_sched_nanosleep_abstime(totnsec); - break; - } - rumpkern_sched(nlocks, NULL); - - return 0; -} diff --git a/lib/librumprun_rumpuser/rumpuser_cons.c b/lib/librumprun_rumpuser/rumpuser_cons.c deleted file mode 100644 index 173c2af..0000000 --- a/lib/librumprun_rumpuser/rumpuser_cons.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2015 Antti Kantee. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#define _BMK_PRINTF_VA - -#include - -#include -#include - -void -rumpuser_putchar(int c) -{ - - bmk_printf("%c", c); -} - -void -rumpuser_dprintf(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - bmk_vprintf(fmt, ap); - va_end(ap); -} diff --git a/lib/librumprun_rumpuser/rumpuser_mem.c b/lib/librumprun_rumpuser/rumpuser_mem.c deleted file mode 100644 index 4ac2ed4..0000000 --- a/lib/librumprun_rumpuser/rumpuser_mem.c +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * Copyright (c) 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 - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#include -#include - -int -rumpuser_malloc(size_t len, int alignment, void **retval) -{ - - /* - * If we are allocating precisely a page-sized chunk - * (the common case), use the underlying page allocator directly. - * This avoids the malloc header overhead for this very - * common allocation, leading to 50% better memory use. - * We can't easily use the page allocator for larger chucks - * of memory, since those allocations might have stricter - * alignment restrictions, and therefore it's just - * easier to use memalloc() in those rare cases; it's not - * as wasteful for larger chunks anyway. - * - * XXX: how to make sure that rump kernel's and our - * page sizes are the same? Could be problematic especially - * for architectures which support multiple page sizes. - * Note that the code will continue to work, but the optimization - * will not trigger for the common case. - */ - if (len == bmk_pagesize) { - bmk_assert(alignment <= bmk_pagesize); - *retval = bmk_platform_allocpg2(0); - } else { - *retval = bmk_memalloc(len, alignment); - } - if (*retval) - return 0; - else - return BMK_ENOMEM; -} - -void -rumpuser_free(void *buf, size_t buflen) -{ - - if (buflen == bmk_pagesize) - bmk_platform_freepg2(buf, 0); - else - bmk_memfree(buf); -} diff --git a/lib/librumprun_rumpuser/rumpuser_stubs.c b/lib/librumprun_rumpuser/rumpuser_stubs.c deleted file mode 100644 index f1c64a5..0000000 --- a/lib/librumprun_rumpuser/rumpuser_stubs.c +++ /dev/null @@ -1,55 +0,0 @@ -/*- - * Copyright (c) 2014 Antti Kantee. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Stub implementations for various rump kernel hypercalls that - * are not supported on these platforms. This file should go away - * with the next revision of the rump kernel hypercall interface. - */ - -#include - -int rumpuser_stub_nothing(void); -int rumpuser_stub_nothing(void) {return 0;} -#define NOTHING(name) \ -int name(void) __attribute__((alias("rumpuser_stub_nothing"))); - -int rumpuser_stub_enosys(void); -int rumpuser_stub_enosys(void) {return BMK_ENOSYS;} -#define NOSYS(name) \ -int name(void) __attribute__((alias("rumpuser_stub_enosys"))); - -NOTHING(rumpuser_dl_bootstrap); - -NOSYS(rumpuser_anonmmap); -NOSYS(rumpuser_unmap); - -NOSYS(rumpuser_kill); - -NOSYS(rumpuser_daemonize_begin); -NOSYS(rumpuser_daemonize_done); - -NOSYS(rumpuser_iovread); -NOSYS(rumpuser_iovwrite); diff --git a/lib/librumprun_rumpuser/rumpuser_synch.c b/lib/librumprun_rumpuser/rumpuser_synch.c deleted file mode 100644 index 8846efa..0000000 --- a/lib/librumprun_rumpuser/rumpuser_synch.c +++ /dev/null @@ -1,481 +0,0 @@ -/* - * Copyright (c) 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 - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * El-simplo threading/locking hypercalls for rump kernels, - * assumes one (1) CPU with non-preemptable scheduling. - * These are never used from interrupt context, so we don't need - * anything fancy. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#define WAIT_NOTIMEOUT -1 - -TAILQ_HEAD(waithead, waiter); -struct waiter { - struct bmk_thread *who; - TAILQ_ENTRY(waiter) entries; - int onlist; -}; - -static int -wait(struct waithead *wh, bmk_time_t nsec) -{ - struct waiter w; - bmk_time_t wakeup; - - w.who = bmk_sched_current(); - TAILQ_INSERT_TAIL(wh, &w, entries); - w.onlist = 1; - if (nsec != WAIT_NOTIMEOUT) - wakeup = bmk_clock_monotonic() + nsec; - bmk_sched_block_timeout(w.who, wakeup); - bmk_sched(); - - /* woken up by timeout? */ - if (w.onlist) - TAILQ_REMOVE(wh, &w, entries); - - return w.onlist ? BMK_ETIMEDOUT : 0; -} - -static void -wakeup_one(struct waithead *wh) -{ - struct waiter *w; - - if ((w = TAILQ_FIRST(wh)) != NULL) { - TAILQ_REMOVE(wh, w, entries); - w->onlist = 0; - bmk_sched_wake(w->who); - } -} - -static void -wakeup_all(struct waithead *wh) -{ - struct waiter *w; - - while ((w = TAILQ_FIRST(wh)) != NULL) { - TAILQ_REMOVE(wh, w, entries); - w->onlist = 0; - bmk_sched_wake(w->who); - } -} - -int -rumpuser_thread_create(void *(*f)(void *), void *arg, const char *thrname, - int joinable, int pri, int cpuidx, void **tptr) -{ - struct bmk_thread *thr; - - thr = bmk_sched_create(thrname, NULL, joinable, - (void (*)(void *))f, arg, NULL, 0); - if (!thr) - return BMK_EINVAL; - - *tptr = thr; - return 0; -} - -void -rumpuser_thread_exit(void) -{ - - bmk_sched_exit(); -} - -int -rumpuser_thread_join(void *p) -{ - - bmk_sched_join(p); - return 0; -} - -struct rumpuser_mtx { - struct waithead waiters; - int v; - int flags; - struct lwp *o; -}; - -void -rumpuser_mutex_init(struct rumpuser_mtx **mtxp, int flags) -{ - struct rumpuser_mtx *mtx; - - mtx = bmk_memcalloc(1, sizeof(*mtx)); - mtx->flags = flags; - TAILQ_INIT(&mtx->waiters); - *mtxp = mtx; -} - -void -rumpuser_mutex_enter(struct rumpuser_mtx *mtx) -{ - int nlocks; - - if (rumpuser_mutex_tryenter(mtx) != 0) { - rumpkern_unsched(&nlocks, NULL); - while (rumpuser_mutex_tryenter(mtx) != 0) - wait(&mtx->waiters, WAIT_NOTIMEOUT); - rumpkern_sched(nlocks, NULL); - } -} - -void -rumpuser_mutex_enter_nowrap(struct rumpuser_mtx *mtx) -{ - int rv; - - rv = rumpuser_mutex_tryenter(mtx); - /* one VCPU supported, no preemption => must succeed */ - if (rv != 0) { - bmk_platform_halt("rumpuser mutex error"); - } -} - -int -rumpuser_mutex_tryenter(struct rumpuser_mtx *mtx) -{ - struct lwp *l = rumpuser_curlwp(); - - if (mtx->v && mtx->o != l) - return BMK_EBUSY; - - mtx->v++; - mtx->o = l; - - return 0; -} - -void -rumpuser_mutex_exit(struct rumpuser_mtx *mtx) -{ - - bmk_assert(mtx->v > 0); - if (--mtx->v == 0) { - mtx->o = NULL; - wakeup_one(&mtx->waiters); - } -} - -void -rumpuser_mutex_destroy(struct rumpuser_mtx *mtx) -{ - - bmk_assert(TAILQ_EMPTY(&mtx->waiters) && mtx->o == NULL); - bmk_memfree(mtx); -} - -void -rumpuser_mutex_owner(struct rumpuser_mtx *mtx, struct lwp **lp) -{ - - *lp = mtx->o; -} - -struct rumpuser_rw { - struct waithead rwait; - struct waithead wwait; - int v; - struct lwp *o; -}; - -void -rumpuser_rw_init(struct rumpuser_rw **rwp) -{ - struct rumpuser_rw *rw; - - rw = bmk_memcalloc(1, sizeof(*rw)); - TAILQ_INIT(&rw->rwait); - TAILQ_INIT(&rw->wwait); - - *rwp = rw; -} - -void -rumpuser_rw_enter(int enum_rumprwlock, struct rumpuser_rw *rw) -{ - enum rumprwlock lk = enum_rumprwlock; - struct waithead *w = NULL; - int nlocks; - - switch (lk) { - case RUMPUSER_RW_WRITER: - w = &rw->wwait; - break; - case RUMPUSER_RW_READER: - w = &rw->rwait; - break; - } - - if (rumpuser_rw_tryenter(enum_rumprwlock, rw) != 0) { - rumpkern_unsched(&nlocks, NULL); - while (rumpuser_rw_tryenter(enum_rumprwlock, rw) != 0) - wait(w, WAIT_NOTIMEOUT); - rumpkern_sched(nlocks, NULL); - } -} - -int -rumpuser_rw_tryenter(int enum_rumprwlock, struct rumpuser_rw *rw) -{ - enum rumprwlock lk = enum_rumprwlock; - int rv = -1; - - switch (lk) { - case RUMPUSER_RW_WRITER: - if (rw->o == NULL) { - rw->o = rumpuser_curlwp(); - rv = 0; - } else { - rv = BMK_EBUSY; - } - break; - case RUMPUSER_RW_READER: - if (rw->o == NULL && TAILQ_EMPTY(&rw->wwait)) { - rw->v++; - rv = 0; - } else { - rv = BMK_EBUSY; - } - break; - } - - return rv; -} - -void -rumpuser_rw_exit(struct rumpuser_rw *rw) -{ - - if (rw->o) { - rw->o = NULL; - } else { - rw->v--; - } - - /* standard procedure, don't let readers starve out writers */ - if (!TAILQ_EMPTY(&rw->wwait)) { - if (rw->o == NULL) - wakeup_one(&rw->wwait); - } else if (!TAILQ_EMPTY(&rw->rwait) && rw->o == NULL) { - wakeup_all(&rw->rwait); - } -} - -void -rumpuser_rw_destroy(struct rumpuser_rw *rw) -{ - - bmk_memfree(rw); -} - -void -rumpuser_rw_held(int enum_rumprwlock, struct rumpuser_rw *rw, int *rvp) -{ - enum rumprwlock lk = enum_rumprwlock; - - switch (lk) { - case RUMPUSER_RW_WRITER: - *rvp = rw->o == rumpuser_curlwp(); - break; - case RUMPUSER_RW_READER: - *rvp = rw->v > 0; - break; - } -} - -void -rumpuser_rw_downgrade(struct rumpuser_rw *rw) -{ - - bmk_assert(rw->o == rumpuser_curlwp()); - rw->v = -1; -} - -int -rumpuser_rw_tryupgrade(struct rumpuser_rw *rw) -{ - - if (rw->v == -1) { - rw->v = 1; - rw->o = rumpuser_curlwp(); - return 0; - } - - return BMK_EBUSY; -} - -struct rumpuser_cv { - struct waithead waiters; - int nwaiters; -}; - -void -rumpuser_cv_init(struct rumpuser_cv **cvp) -{ - struct rumpuser_cv *cv; - - cv = bmk_memcalloc(1, sizeof(*cv)); - TAILQ_INIT(&cv->waiters); - *cvp = cv; -} - -void -rumpuser_cv_destroy(struct rumpuser_cv *cv) -{ - - bmk_assert(cv->nwaiters == 0); - bmk_memfree(cv); -} - -static void -cv_unsched(struct rumpuser_mtx *mtx, int *nlocks) -{ - - rumpkern_unsched(nlocks, mtx); - rumpuser_mutex_exit(mtx); -} - -static void -cv_resched(struct rumpuser_mtx *mtx, int nlocks) -{ - - /* see rumpuser(3) */ - if ((mtx->flags & (RUMPUSER_MTX_KMUTEX | RUMPUSER_MTX_SPIN)) == - (RUMPUSER_MTX_KMUTEX | RUMPUSER_MTX_SPIN)) { - rumpkern_sched(nlocks, mtx); - rumpuser_mutex_enter_nowrap(mtx); - } else { - rumpuser_mutex_enter_nowrap(mtx); - rumpkern_sched(nlocks, mtx); - } -} - -void -rumpuser_cv_wait(struct rumpuser_cv *cv, struct rumpuser_mtx *mtx) -{ - int nlocks; - - cv->nwaiters++; - cv_unsched(mtx, &nlocks); - wait(&cv->waiters, WAIT_NOTIMEOUT); - cv_resched(mtx, nlocks); - cv->nwaiters--; -} - -void -rumpuser_cv_wait_nowrap(struct rumpuser_cv *cv, struct rumpuser_mtx *mtx) -{ - - cv->nwaiters++; - rumpuser_mutex_exit(mtx); - wait(&cv->waiters, WAIT_NOTIMEOUT); - rumpuser_mutex_enter_nowrap(mtx); - cv->nwaiters--; -} - -int -rumpuser_cv_timedwait(struct rumpuser_cv *cv, struct rumpuser_mtx *mtx, - int64_t sec, int64_t nsec) -{ - int nlocks; - int rv; - - cv->nwaiters++; - cv_unsched(mtx, &nlocks); - rv = wait(&cv->waiters, sec * 1000*1000*1000ULL + nsec); - cv_resched(mtx, nlocks); - cv->nwaiters--; - - return rv; -} - -void -rumpuser_cv_signal(struct rumpuser_cv *cv) -{ - - wakeup_one(&cv->waiters); -} - -void -rumpuser_cv_broadcast(struct rumpuser_cv *cv) -{ - - wakeup_all(&cv->waiters); -} - -void -rumpuser_cv_has_waiters(struct rumpuser_cv *cv, int *rvp) -{ - - *rvp = cv->nwaiters != 0; -} - -/* - * curlwp - */ - -void -rumpuser_curlwpop(int enum_rumplwpop, struct lwp *l) -{ - struct bmk_thread *thread; - enum rumplwpop op = enum_rumplwpop; - - switch (op) { - case RUMPUSER_LWP_CREATE: - case RUMPUSER_LWP_DESTROY: - break; - case RUMPUSER_LWP_SET: - bmk_assert(rumpuser_curlwp() == NULL); - thread = bmk_sched_current(); - bmk_sched_settls(thread, 0, l); - break; - case RUMPUSER_LWP_CLEAR: - bmk_assert(rumpuser_curlwp() == l); - thread = bmk_sched_current(); - bmk_sched_settls(thread, 0, NULL); - break; - } -} - -struct lwp * -rumpuser_curlwp(void) -{ - - return bmk_sched_gettls(bmk_sched_current(), 0); -} diff --git a/platform/baremetal/Makefile b/platform/baremetal/Makefile index 0d895be..fbfd576 100644 --- a/platform/baremetal/Makefile +++ b/platform/baremetal/Makefile @@ -74,11 +74,11 @@ RUMPKERN_LIB= ${LIBS_VIO_NET} \ -lrumpdev -lrumpvfs -lrump COREDIR:= $(shell pwd)/../../lib/libbmk_core +RUMPUSERDIR:= $(shell pwd)/../../lib/libbmk_rumpuser BASEDIR:= $(shell pwd)/../../lib/librumprun_base -RUMPUSERDIR:= $(shell pwd)/../../lib/librumprun_rumpuser OBJS_BMK+= init.o -LIBS_USER= -L${BASEDIR}/baremetal -L${COREDIR}/baremetal -L${RUMPUSERDIR}/baremetal -lrumprun_rumpuser --start-group -lrumprun_base -lpthread -lc --end-group -lbmk_core +LIBS_USER= -L${BASEDIR}/baremetal -L${COREDIR}/baremetal -L${RUMPUSERDIR}/baremetal --start-group -lrumprun_base -lpthread -lc --end-group -lbmk_rumpuser -lbmk_core RUMP_LDLIBS= --whole-archive ${RUMPKERN_LIB} --no-whole-archive ${LIBS_USER} OBJS= ${OBJS_BMK} ${OBJS_APP} @@ -107,12 +107,12 @@ ${COREDIR}/baremetal/libbmk_core.a: && ${RUMPMAKE} MAKEOBJDIR=baremetal obj \ && ${RUMPMAKE} MAKEOBJDIR=baremetal dependall ) -${RUMPUSERDIR}/baremetal/librumprun_rumpuser.a: +${RUMPUSERDIR}/baremetal/libbmk_rumpuser.a: ( cd ${RUMPUSERDIR} \ && ${RUMPMAKE} MAKEOBJDIR=baremetal obj \ && ${RUMPMAKE} MAKEOBJDIR=baremetal dependall ) -rumprun.o: ${OBJS} ${BASEDIR}/baremetal/librumprun_base.a ${COREDIR}/baremetal/libbmk_core.a ${RUMPUSERDIR}/baremetal/librumprun_rumpuser.a +rumprun.o: ${OBJS} ${BASEDIR}/baremetal/librumprun_base.a ${COREDIR}/baremetal/libbmk_core.a ${RUMPUSERDIR}/baremetal/libbmk_rumpuser.a ${CC} -nostdlib ${CFLAGS} -Wl,-r ${OBJS_BMK} -o $@ tests: rumprun.o app-tools diff --git a/platform/xen/Makefile b/platform/xen/Makefile index ec2cc51..aa5b667 100644 --- a/platform/xen/Makefile +++ b/platform/xen/Makefile @@ -33,8 +33,8 @@ CFLAGS += -mno-red-zone -fno-reorder-blocks -fno-asynchronous-unwind-tables endif COREDIR:= $(shell pwd)/../../lib/libbmk_core +RUMPUSERDIR:= $(shell pwd)/../../lib/libbmk_rumpuser BASEDIR:= $(shell pwd)/../../lib/librumprun_base -RUMPUSERDIR:= $(shell pwd)/../../lib/librumprun_rumpuser ifeq (${CONFIG_SYSPROXY},yes) RUMP_LIBS_SYSPROXY = -lrumpkern_sysproxy @@ -47,7 +47,7 @@ RUMP_LIBS_NET+= -lrumpnet_local -lrumpnet_net -lrumpxen_xendev -lrumpnet # Define some default flags for linking. RUMP_LDLIBS = --whole-archive ${RUMP_LIBS_FS} ${RUMP_LIBS_NET} ${RUMP_LIBS_PCI} ${RUMP_LIBS_SYSPROXY} -lrumpxen_tc -lrump --no-whole-archive -RUMP_LDLIBS := ${RUMP_LDLIBS} -L${BASEDIR}/xen -L${COREDIR}/xen -L${RUMPUSERDIR}/xen -lrumprun_rumpuser --start-group -lrumprun_base -lpthread -lc --end-group -lbmk_core +RUMP_LDLIBS := ${RUMP_LDLIBS} -L${BASEDIR}/xen -L${COREDIR}/xen -L${RUMPUSERDIR}/xen --start-group -lrumprun_base -lpthread -lc --end-group -lbmk_rumpuser -lbmk_core LDFLAGS := -L$(abspath rump/lib) @@ -86,7 +86,7 @@ ${COREDIR}/xen/libbmk_core.a: && ${RUMPMAKE} MAKEOBJDIR=xen obj \ && ${RUMPMAKE} MAKEOBJDIR=xen dependall ) -${RUMPUSERDIR}/xen/librumprun_rumpuser.a: +${RUMPUSERDIR}/xen/libbmk_rumpuser.a: ( cd ${RUMPUSERDIR} \ && ${RUMPMAKE} MAKEOBJDIR=xen obj \ && ${RUMPMAKE} MAKEOBJDIR=xen dependall ) @@ -94,7 +94,7 @@ ${RUMPUSERDIR}/xen/librumprun_rumpuser.a: .PHONY: rumprun rumprun: $(OBJ_DIR)/rumprun.o -$(OBJ_DIR)/rumprun.o: $(RUMP_OBJS) ${BASEDIR}/xen/librumprun_base.a ${COREDIR}/xen/libbmk_core.a ${RUMPUSERDIR}/xen/librumprun_rumpuser.a +$(OBJ_DIR)/rumprun.o: $(RUMP_OBJS) ${BASEDIR}/xen/librumprun_base.a ${COREDIR}/xen/libbmk_core.a ${RUMPUSERDIR}/xen/libbmk_rumpuser.a $(CC) -Wl,-r $(CFLAGS) $(LDFLAGS) $(RUMP_OBJS) -nostdlib -o $@ APP_TOOLS_TARGETARCH= $(TARGET_ARCH)