--- /dev/null
+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 <bsd.lib.mk>
--- /dev/null
+/*-
+ * 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 <bmk-core/null.h>
+#include <bmk-core/platform.h>
+#include <bmk-core/sched.h>
+
+#include <bmk-rumpuser/core_types.h>
+#include <bmk-rumpuser/rumpuser.h>
+
+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;
+}
--- /dev/null
+/*-
+ * 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 <bmk-core/errno.h>
+#include <bmk-core/memalloc.h>
+#include <bmk-core/null.h>
+#include <bmk-core/sched.h>
+#include <bmk-core/string.h>
+
+#include <bmk-rumpuser/core_types.h>
+#include <bmk-rumpuser/rumpuser.h>
+
+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;
+}
--- /dev/null
+/*-
+ * 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 <bmk-core/printf.h>
+
+#include <bmk-rumpuser/core_types.h>
+#include <bmk-rumpuser/rumpuser.h>
+
+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);
+}
--- /dev/null
+/*-
+ * 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 <bmk-core/core.h>
+#include <bmk-core/errno.h>
+#include <bmk-core/memalloc.h>
+#include <bmk-core/null.h>
+
+#include <bmk-rumpuser/core_types.h>
+#include <bmk-rumpuser/rumpuser.h>
+
+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);
+}
--- /dev/null
+/*-
+ * 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 <bmk-core/errno.h>
+
+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);
--- /dev/null
+/*
+ * 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 <bmk-core/core.h>
+#include <bmk-core/errno.h>
+#include <bmk-core/memalloc.h>
+#include <bmk-core/queue.h>
+#include <bmk-core/sched.h>
+#include <bmk-core/string.h>
+
+#include <bmk-rumpuser/core_types.h>
+#include <bmk-rumpuser/rumpuser.h>
+
+#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);
+}
+++ /dev/null
-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 <bsd.lib.mk>
+++ /dev/null
-/*-
- * 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 <bmk-core/null.h>
-#include <bmk-core/platform.h>
-#include <bmk-core/sched.h>
-
-#include <bmk-rumpuser/core_types.h>
-#include <bmk-rumpuser/rumpuser.h>
-
-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;
-}
+++ /dev/null
-/*-
- * 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 <bmk-core/errno.h>
-#include <bmk-core/memalloc.h>
-#include <bmk-core/null.h>
-#include <bmk-core/sched.h>
-#include <bmk-core/string.h>
-
-#include <bmk-rumpuser/core_types.h>
-#include <bmk-rumpuser/rumpuser.h>
-
-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;
-}
+++ /dev/null
-/*-
- * 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 <bmk-core/printf.h>
-
-#include <bmk-rumpuser/core_types.h>
-#include <bmk-rumpuser/rumpuser.h>
-
-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);
-}
+++ /dev/null
-/*-
- * 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 <bmk-core/core.h>
-#include <bmk-core/errno.h>
-#include <bmk-core/memalloc.h>
-#include <bmk-core/null.h>
-
-#include <bmk-rumpuser/core_types.h>
-#include <bmk-rumpuser/rumpuser.h>
-
-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);
-}
+++ /dev/null
-/*-
- * 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 <bmk-core/errno.h>
-
-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);
+++ /dev/null
-/*
- * 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 <bmk-core/core.h>
-#include <bmk-core/errno.h>
-#include <bmk-core/memalloc.h>
-#include <bmk-core/queue.h>
-#include <bmk-core/sched.h>
-#include <bmk-core/string.h>
-
-#include <bmk-rumpuser/core_types.h>
-#include <bmk-rumpuser/rumpuser.h>
-
-#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);
-}
-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}
&& ${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
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
# 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)
&& ${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 )
.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)