]> xenbits.xensource.com Git - people/liuw/rumprun.git/commitdiff
Rename librumprun_core to libbmk_core.
authorAntti Kantee <pooka@iki.fi>
Tue, 21 Apr 2015 12:23:42 +0000 (12:23 +0000)
committerAntti Kantee <pooka@iki.fi>
Tue, 21 Apr 2015 12:23:42 +0000 (12:23 +0000)
It doesn't have anything to do with rumprun, but is at a lower layer of
abstraction, so let's just match the header namespace here.

26 files changed:
lib/libbmk_core/Makefile [new file with mode: 0644]
lib/libbmk_core/arch/amd64/Makefile.inc [new file with mode: 0644]
lib/libbmk_core/arch/amd64/cpu_sched_switch.S [new file with mode: 0644]
lib/libbmk_core/arch/i386/Makefile.inc [new file with mode: 0644]
lib/libbmk_core/arch/i386/cpu_sched_switch.S [new file with mode: 0644]
lib/libbmk_core/arch/x86/Makefile.inc [new file with mode: 0644]
lib/libbmk_core/arch/x86/cpu_sched.c [new file with mode: 0644]
lib/libbmk_core/bmk_string.c [new file with mode: 0644]
lib/libbmk_core/init.c [new file with mode: 0644]
lib/libbmk_core/memalloc.c [new file with mode: 0644]
lib/libbmk_core/sched.c [new file with mode: 0644]
lib/libbmk_core/subr_prf.c [new file with mode: 0644]
lib/librumprun_core/Makefile [deleted file]
lib/librumprun_core/arch/amd64/Makefile.inc [deleted file]
lib/librumprun_core/arch/amd64/cpu_sched_switch.S [deleted file]
lib/librumprun_core/arch/i386/Makefile.inc [deleted file]
lib/librumprun_core/arch/i386/cpu_sched_switch.S [deleted file]
lib/librumprun_core/arch/x86/Makefile.inc [deleted file]
lib/librumprun_core/arch/x86/cpu_sched.c [deleted file]
lib/librumprun_core/bmk_string.c [deleted file]
lib/librumprun_core/init.c [deleted file]
lib/librumprun_core/memalloc.c [deleted file]
lib/librumprun_core/sched.c [deleted file]
lib/librumprun_core/subr_prf.c [deleted file]
platform/baremetal/Makefile
platform/xen/Makefile

diff --git a/lib/libbmk_core/Makefile b/lib/libbmk_core/Makefile
new file mode 100644 (file)
index 0000000..3e8c8c7
--- /dev/null
@@ -0,0 +1,10 @@
+LIB=           bmk_core
+LIBISPRIVATE=  # defined
+
+SRCS=          init.c bmk_string.c memalloc.c sched.c subr_prf.c
+
+CPPFLAGS+=     -I${.CURDIR}/../../include
+
+.include "${.CURDIR}/arch/${MACHINE}/Makefile.inc"
+
+.include <bsd.lib.mk>
diff --git a/lib/libbmk_core/arch/amd64/Makefile.inc b/lib/libbmk_core/arch/amd64/Makefile.inc
new file mode 100644 (file)
index 0000000..80b2d56
--- /dev/null
@@ -0,0 +1,6 @@
+MYDIR:=        ${.PARSEDIR}
+.PATH: ${MYDIR}
+
+SRCS+= cpu_sched_switch.S
+
+.include "${MYDIR}/../x86/Makefile.inc"
diff --git a/lib/libbmk_core/arch/amd64/cpu_sched_switch.S b/lib/libbmk_core/arch/amd64/cpu_sched_switch.S
new file mode 100644 (file)
index 0000000..4747652
--- /dev/null
@@ -0,0 +1,70 @@
+/*-
+ ****************************************************************************
+ * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
+ ****************************************************************************
+ *
+ *        File: sched.c
+ *      Author: Grzegorz Milos
+ *     Changes: Robert Kaiser
+ *
+ *        Date: Aug 2005
+ *
+ * Environment: Xen Minimal OS
+ * Description: simple scheduler for Mini-Os
+ *
+ * The scheduler is non-preemptive (cooperative), and schedules according
+ * to Round Robin algorithm.
+ *
+ ****************************************************************************
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <bmk-core/amd64/asm.h>
+
+ENTRY(bmk_cpu_sched_bouncer)
+       popq %rdi
+       popq %rbx
+       pushq $0                        /* correct stack alignment for SSE */
+       pushq $0
+       xorq %rbp,%rbp
+       call *%rbx
+       call bmk_sched_exit
+END(bmk_cpu_sched_bouncer)
+
+ENTRY(bmk__cpu_switch)
+       pushq %rbp
+       pushq %rbx
+       pushq %r12
+       pushq %r13
+       pushq %r14
+       pushq %r15
+       movq %rsp, (%rdi)               /* save ESP */
+       movq (%rsi), %rsp               /* restore ESP */
+       movq $1f, 8(%rdi)               /* save EIP */
+       pushq 8(%rsi)                   /* restore EIP */
+       ret
+1:
+       popq %r15
+       popq %r14
+       popq %r13
+       popq %r12
+       popq %rbx
+       popq %rbp
+       ret
+END(bmk__cpu_switch)
diff --git a/lib/libbmk_core/arch/i386/Makefile.inc b/lib/libbmk_core/arch/i386/Makefile.inc
new file mode 100644 (file)
index 0000000..80b2d56
--- /dev/null
@@ -0,0 +1,6 @@
+MYDIR:=        ${.PARSEDIR}
+.PATH: ${MYDIR}
+
+SRCS+= cpu_sched_switch.S
+
+.include "${MYDIR}/../x86/Makefile.inc"
diff --git a/lib/libbmk_core/arch/i386/cpu_sched_switch.S b/lib/libbmk_core/arch/i386/cpu_sched_switch.S
new file mode 100644 (file)
index 0000000..cc9ec7d
--- /dev/null
@@ -0,0 +1,73 @@
+/*-
+ ****************************************************************************
+ * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
+ ****************************************************************************
+ *
+ *        File: sched.c
+ *      Author: Grzegorz Milos
+ *     Changes: Robert Kaiser
+ *              
+ *        Date: Aug 2005
+ * 
+ * Environment: Xen Minimal OS
+ * Description: simple scheduler for Mini-Os
+ *
+ * The scheduler is non-preemptive (cooperative), and schedules according 
+ * to Round Robin algorithm.
+ *
+ ****************************************************************************
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <bmk-core/i386/asm.h>
+
+ENTRY(bmk_cpu_sched_bouncer)
+       popl %eax
+       popl %ebx
+       pushl $0
+       xorl %ebp,%ebp
+       pushl %eax
+       call *%ebx
+       call bmk_sched_exit
+END(bmk_cpu_sched_bouncer)
+
+ENTRY(bmk__cpu_switch)
+       movl 4(%esp), %ecx              /* prev */
+       movl 8(%esp), %edx              /* next */
+
+       /* reload tls for new thread */
+       movl $0x18, %eax
+       movl %eax, %gs
+
+       pushl %ebp
+       pushl %ebx
+       pushl %esi
+       pushl %edi
+       movl %esp, (%ecx)               /* save ESP */
+       movl (%edx), %esp               /* restore ESP */
+       movl $1f, 4(%ecx)               /* save EIP */
+       pushl 4(%edx)                   /* restore EIP */
+       ret
+1:
+       popl %edi
+       popl %esi
+       popl %ebx
+       popl %ebp
+       ret
+END(bmk__cpu_switch)
diff --git a/lib/libbmk_core/arch/x86/Makefile.inc b/lib/libbmk_core/arch/x86/Makefile.inc
new file mode 100644 (file)
index 0000000..757c137
--- /dev/null
@@ -0,0 +1,4 @@
+X86DIR:=${.PARSEDIR}
+.PATH: ${X86DIR}
+
+SRCS+= cpu_sched.c
diff --git a/lib/libbmk_core/arch/x86/cpu_sched.c b/lib/libbmk_core/arch/x86/cpu_sched.c
new file mode 100644 (file)
index 0000000..f9c945d
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ ****************************************************************************
+ * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
+ ****************************************************************************
+ *
+ *        File: sched.c
+ *      Author: Grzegorz Milos
+ *     Changes: Robert Kaiser
+ *
+ *        Date: Aug 2005
+ *
+ * Environment: Xen Minimal OS
+ * Description: simple scheduler for Mini-Os
+ *
+ * The scheduler is non-preemptive (cooperative), and schedules according
+ * to Round Robin algorithm.
+ *
+ ****************************************************************************
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <bmk-core/core.h>
+#include <bmk-core/sched.h>
+
+static void
+stack_push(void **stackp, unsigned long value)
+{
+       unsigned long *stack = *stackp;
+
+       stack--;
+       *stack = value;
+       *stackp = stack;
+}
+
+void
+bmk_cpu_sched_create(struct bmk_thread *thread, struct bmk_tcb *tcb,
+       void (*f)(void *), void *arg,
+       void *stack_base, unsigned long stack_size)
+{
+       void *stack_top = (char *)stack_base + stack_size;
+
+       /* Save pointer to the thread on the stack, used by current macro */
+       *(unsigned long *)stack_base = (unsigned long)thread;
+
+       /* these values are used by bmk_cpu_sched_bouncer() */
+       stack_push(&stack_top, (unsigned long)f);
+       stack_push(&stack_top, (unsigned long)arg);
+
+       tcb->btcb_sp = (unsigned long)stack_top;
+       tcb->btcb_ip = (unsigned long)bmk_cpu_sched_bouncer;
+}
+
+struct bmk_thread *
+bmk_cpu_sched_current(void)
+{
+       struct bmk_thread **current;
+
+       current = (void *)((unsigned long)&current & ~(bmk_stacksize-1));
+       return *current;
+};
diff --git a/lib/libbmk_core/bmk_string.c b/lib/libbmk_core/bmk_string.c
new file mode 100644 (file)
index 0000000..fb53980
--- /dev/null
@@ -0,0 +1,135 @@
+/*-
+ * 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.
+ */
+
+/*
+ * The assumption is that these won't be used very often,
+ * only for the very low-level routines.
+ *
+ * Some code from public domain implementations.
+ */
+
+#include <bmk-core/null.h>
+#include <bmk-core/string.h>
+
+unsigned long
+bmk_strlen(const char *str)
+{
+       unsigned long rv = 0;
+
+       while (*str++)
+               rv++;
+       return rv;
+}
+
+int
+bmk_strcmp(const char *a, const char *b)
+{
+
+       while (*a && *a++ == *b++) {
+               continue;
+       }
+       if (*a) {
+               a--;
+               b--;
+       }
+       return *a - *b;
+}
+
+int
+bmk_strncmp(const char *a, const char *b, unsigned long n)
+{
+       unsigned char u1, u2;
+
+       while (n-- > 0) {
+               u1 = (unsigned char)*a++;
+               u2 = (unsigned char)*b++;
+               if (u1 != u2)
+                       return u1 - u2;
+               if (u1 == '\0')
+                       return 0;
+       }
+       return 0;
+}
+
+char *
+bmk_strcpy(char *d, const char *s)
+{
+       char *orig = d;
+
+       while ((*d++ = *s++) != '\0')
+               continue;
+       return orig;
+}
+
+char *
+bmk_strncpy(char *d, const char *s, unsigned long n)
+{
+       char *orig = d;
+
+       while ((*d++ = *s++) && n--)
+               continue;
+       while (n--)
+               *d++ = '\0';
+       return orig;
+}
+
+void *
+bmk_memset(void *b, int c, unsigned long n)
+{
+       unsigned char *v = b;
+
+       while (n--)
+               *v++ = (unsigned char)c;
+
+       return b;
+}
+
+void *
+bmk_memcpy(void *d, const void *src, unsigned long n)
+{
+       unsigned char *dp;
+       const unsigned char *sp;
+
+       dp = d;
+       sp = src;
+
+       while (n--)
+               *dp++ = *sp++;
+
+       return d;
+}
+
+void *
+bmk_memchr(const void *d, int c, unsigned long n)
+{
+       const unsigned char *p = d;
+
+       while (n--) {
+               if (*p == (unsigned char)c)
+                       return (void *)(unsigned long)p;
+               p++;
+       }
+       return NULL;
+}
diff --git a/lib/libbmk_core/init.c b/lib/libbmk_core/init.c
new file mode 100644 (file)
index 0000000..215b59e
--- /dev/null
@@ -0,0 +1,41 @@
+/*-
+ * 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.
+ */
+
+#include <bmk-core/core.h>
+
+unsigned long bmk_stackpageorder;
+unsigned long bmk_stacksize;
+unsigned long bmk_pagesize;
+
+int
+bmk_core_init(unsigned long stackpageorder, unsigned long pagesize)
+{
+
+       bmk_stackpageorder = stackpageorder;
+       bmk_stacksize = (1<<stackpageorder) * pagesize;
+       bmk_pagesize = pagesize;
+
+       return 0;
+}
diff --git a/lib/libbmk_core/memalloc.c b/lib/libbmk_core/memalloc.c
new file mode 100644 (file)
index 0000000..4551fdc
--- /dev/null
@@ -0,0 +1,569 @@
+/*
+ * Copyright (c) 2013 Antti Kantee.  All rights reserved.
+ * Copyright (c) 1983, 1993
+ *     The Regents of the University of California.  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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS 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.
+ */
+
+/*
+ * malloc.c (Caltech) 2/21/82
+ * Chris Kingsley, kingsley@cit-20.
+ *
+ * This is a very fast storage allocator.  It allocates blocks of a small 
+ * number of different sizes, and keeps free lists of each size.  Blocks that
+ * don't exactly fit are passed up to the next larger size.  In this 
+ * implementation, the available sizes are 2^n-4 (or 2^n-10) bytes long.
+ * This is designed for use in a virtual memory environment.
+ *
+ * Modified for Xen Mini-OS:
+ *  + allocate backing storage with page_alloc() instead of sbrk()
+ *  + support alignment
+ *  + use ANSI C (hey, there's no rush!)
+ */
+
+#ifdef MEMALLOC_TESTING
+#define PAGE_SIZE getpagesize()
+#define MSTATS
+
+#include <sys/cdefs.h>
+
+#include <sys/types.h>
+#if defined(RCHECK)
+#include <sys/uio.h>
+#endif
+#if defined(RCHECK) || defined(MSTATS)
+#include <stdio.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#else
+
+#include <bmk-core/core.h>
+#include <bmk-core/string.h>
+#include <bmk-core/memalloc.h>
+#include <bmk-core/platform.h>
+
+#define NULL (void *)0
+#define ASSERT(x)
+
+#endif
+
+
+/*
+ * The overhead on a block is at least 4 bytes.  When free, this space
+ * contains a pointer to the next free block, and the bottom two bits must
+ * be zero.  When in use, the first byte is set to MAGIC, and the second
+ * byte is the size index.  The remaining bytes are for alignment.
+ * If range checking is enabled then a second word holds the size of the
+ * requested block, less 1, rounded up to a multiple of sizeof(RMAGIC).
+ * The order of elements is critical: ov_magic must overlay the low order
+ * bits of ov_next, and ov_magic can not be a valid ov_next bit pattern.
+ */
+union  overhead {
+       union   overhead *ov_next;      /* when free */
+       struct {
+               unsigned long  ovu_alignpad;    /* padding for alignment */
+               unsigned char   ovu_magic;      /* magic number */
+               unsigned char   ovu_index;      /* bucket # */
+#ifdef RCHECK
+               unsigned short  ovu_rmagic;     /* range magic number */
+               unsigned long   ovu_size;       /* actual block size */
+#endif
+       } ovu;
+#define        ov_alignpad     ovu.ovu_alignpad
+#define        ov_magic        ovu.ovu_magic
+#define        ov_index        ovu.ovu_index
+#define        ov_rmagic       ovu.ovu_rmagic
+#define        ov_size         ovu.ovu_size
+};
+
+#define        MAGIC           0xef            /* magic # on accounting info */
+#define UNMAGIC                0x12            /* magic # != MAGIC */
+#define UNMAGIC2       0x24            /* magic # != MAGIC/UNMAGIC */
+#ifdef RCHECK
+#define RMAGIC         0x5555          /* magic # on range info */
+#endif
+
+#ifdef RCHECK
+#define        RSLOP           sizeof (unsigned short)
+#else
+#define        RSLOP           0
+#endif
+
+/*
+ * nextf[i] is the pointer to the next free block of size 2^(i+MINSHIFT).  The
+ * smallest allocatable block is 1<<MINSHIFT bytes.  The overhead information
+ * precedes the data area returned to the user.
+ */
+#define MINSHIFT 5
+#define        NBUCKETS 30
+#define MINALIGN 16
+static union overhead *nextf[NBUCKETS];
+
+static long pagesz;                    /* page size */
+static int pagebucket;                 /* page size bucket */
+
+#ifdef MSTATS
+/*
+ * nmalloc[i] is the difference between the number of mallocs and frees
+ * for a given block size.
+ */
+static u_int nmalloc[NBUCKETS];
+#endif
+
+#if 0
+#ifdef _REENT
+static mutex_t malloc_mutex = MUTEX_INITIALIZER;
+#endif
+#endif
+
+/* not currently reentrant on mini-os */
+#define malloc_lock()
+#define malloc_unlock()
+
+static void morecore(int);
+#ifdef MSTATS
+void mstats(const char *);
+#endif
+
+#if defined(RCHECK) || defined(MEMALLOC_TESTING)
+#define        ASSERT(p)   if (!(p)) botch(__STRING(p))
+#include <sys/uio.h>
+
+static void botch(const char *);
+
+/*
+ * NOTE: since this may be called while malloc_mutex is locked, stdio must not
+ *       be used in this function.
+ */
+static void
+botch(const char *s)
+{
+       struct iovec iov[3];
+
+       iov[0].iov_base = "\nassertion botched: ";
+       iov[0].iov_len  = 20;
+       iov[1].iov_base = (void *)s;
+       iov[1].iov_len  = strlen(s);
+       iov[2].iov_base = "\n";
+       iov[2].iov_len  = 1;
+
+       /*
+        * This place deserves a word of warning: a cancellation point will
+        * occur when executing writev(), and we might be still owning
+        * malloc_mutex.  At this point we need to disable cancellation
+        * until `after' abort() because i) establishing a cancellation handler
+        * might, depending on the implementation, result in another malloc()
+        * to be executed, and ii) it is really not desirable to let execution
+        * continue.  `Fix me.'
+        * 
+        * Note that holding mutex_lock during abort() is safe.
+        */
+
+       (void)writev(STDERR_FILENO, iov, 3);
+       abort();
+}
+#endif
+
+void *
+bmk_memalloc(unsigned long nbytes, unsigned long align)
+{
+       union overhead *op;
+       void *rv;
+       unsigned long allocbytes;
+       int bucket;
+       unsigned amt;
+       unsigned long alignpad;
+
+       malloc_lock();
+
+       if (pagesz == 0) {
+               pagesz = bmk_pagesize;
+               ASSERT(pagesz > 0);
+
+#if 0
+               op = (union overhead *)(void *)sbrk(0);
+               n = n - sizeof (*op) - ((long)op & (n - 1));
+               if (n < 0)
+                       n += pagesz;
+               if (n) {
+                       if (sbrk((int)n) == (void *)-1) {
+                               malloc_unlock();
+                               return (NULL);
+                       }
+               }
+#endif
+
+               bucket = 0;
+               amt = 1<<MINSHIFT;
+               while (pagesz > amt) {
+                       amt <<= 1;
+                       bucket++;
+               }
+               pagebucket = bucket;
+       }
+
+       if (align & (align-1))
+               return NULL;
+       if (align < MINALIGN)
+               align = MINALIGN;
+       
+       /* need at least this many bytes plus header to satisfy alignment */
+       allocbytes = nbytes + ((sizeof(*op) + (align-1)) & ~(align-1));
+
+       /*
+        * Convert amount of memory requested into closest block size
+        * stored in hash buckets which satisfies request.
+        * Account for space used per block for accounting.
+        */
+       if (allocbytes <= pagesz - RSLOP) {
+#ifndef RCHECK
+               amt = 1<<MINSHIFT;      /* size of first bucket */
+               bucket = 0;
+#else
+               amt = 1<<(MINSHIFT+1);  /* size of first bucket */
+               bucket = 1;
+#endif
+       } else {
+               amt = (unsigned)pagesz;
+               bucket = pagebucket;
+       }
+       while (allocbytes > amt) {
+               amt <<= 1;
+               if (amt == 0)
+                       return (NULL);
+               bucket++;
+       }
+       /*
+        * If nothing in hash bucket right now,
+        * request more memory from the system.
+        */
+       if ((op = nextf[bucket]) == NULL) {
+               morecore(bucket);
+               if ((op = nextf[bucket]) == NULL) {
+                       malloc_unlock();
+                       return (NULL);
+               }
+       }
+       /* remove from linked list */
+       nextf[bucket] = op->ov_next;
+
+       /* align op before returned memory */
+       rv = (void *)(((unsigned long)(op+1) + align - 1) & ~(align - 1));
+       alignpad = (unsigned long)rv - (unsigned long)op;
+
+#ifdef MEMALLOC_TESTING
+       memset(op, MAGIC, alignpad);
+#endif
+
+       op = ((union overhead *)rv)-1;
+       op->ov_magic = MAGIC;
+       op->ov_index = bucket;
+       op->ov_alignpad = alignpad;
+#ifdef MSTATS
+       nmalloc[bucket]++;
+#endif
+       malloc_unlock();
+#ifdef RCHECK
+       /*
+        * Record allocated size of block and
+        * bound space with magic numbers.
+        */
+       op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
+       op->ov_rmagic = RMAGIC;
+       *(unsigned short *)((char *)(op + 1) + op->ov_size) = RMAGIC;
+#endif
+
+       return rv;
+}
+
+void *
+bmk_xmalloc(unsigned long howmuch)
+{
+       void *rv;
+
+       rv = bmk_memalloc(howmuch, 0);
+       if (rv == NULL)
+               bmk_platform_halt("xmalloc failed");
+       return rv;
+}
+
+void *
+bmk_memcalloc(unsigned long n, unsigned long size)
+{
+       void *v;
+       unsigned long tot = n * size;
+
+       if (size != 0 && tot / size != n)
+               return NULL;
+
+       if ((v = bmk_memalloc(tot, MINALIGN)) != NULL) {
+               bmk_memset(v, 0, tot);
+       }
+       return v;
+}
+
+static void *
+corealloc(int shift)
+{
+       void *v;
+
+#ifdef MEMALLOC_TESTING
+       v = malloc((1<<shift) * pagesz);
+#else
+       v = bmk_platform_allocpg2(shift);
+#endif
+
+       return v;
+}
+
+/*
+ * Allocate more memory to the indicated bucket.
+ */
+static void
+morecore(int bucket)
+{
+       union overhead *op;
+       long sz;                /* size of desired block */
+       long amt;                       /* amount to allocate */
+       long nblks;                     /* how many blocks we get */
+
+       if (bucket < pagebucket) {
+               amt = 0;
+               nblks = pagesz / (1<<(bucket + MINSHIFT));
+               sz = pagesz / nblks;
+       } else {
+               amt = bucket - pagebucket;
+               nblks = 1;
+               sz = 0; /* dummy */
+       }
+       op = (void *)corealloc(amt);
+       /* no more room! */
+       if (op == NULL)
+               return;
+       /*
+        * Add new memory allocated to that on
+        * free list for this hash bucket.
+        */
+       nextf[bucket] = op;
+       while (--nblks > 0) {
+               op->ov_next =
+                   (union overhead *)(void *)((char *)(void *)op+(unsigned long)sz);
+               op = op->ov_next;
+       }
+       op->ov_next = NULL;
+}
+
+void
+bmk_memfree(void *cp)
+{   
+       long size;
+       union overhead *op;
+       unsigned long alignpad;
+       void *origp;
+
+       if (cp == NULL)
+               return;
+       op = ((union overhead *)cp)-1;
+       if (op->ov_magic != MAGIC) {
+#ifdef MEMALLOC_TESTING
+               ASSERT(0);
+#endif
+               return;                         /* sanity */
+       }
+
+#ifdef RCHECK
+       ASSERT(op->ov_rmagic == RMAGIC);
+       ASSERT(*(unsigned short *)((char *)(op + 1) + op->ov_size) == RMAGIC);
+#endif
+       size = op->ov_index;
+       alignpad = op->ov_alignpad;
+       ASSERT(size < NBUCKETS);
+
+       malloc_lock();
+       origp = (unsigned char *)cp - alignpad;
+
+#ifdef MEMALLOC_TESTING
+       {
+               unsigned long i;
+
+               for (i = 0;
+                   (unsigned char *)origp + i < (unsigned char *)op;
+                   i++) {
+                       ASSERT(*((unsigned char *)origp + i) == MAGIC);
+                               
+               }
+       }
+#endif
+
+       op = (void *)origp;
+       op->ov_next = nextf[(unsigned int)size];/* also clobbers ov_magic */
+       nextf[(unsigned int)size] = op;
+#ifdef MSTATS
+       nmalloc[(unsigned long)size]--;
+#endif
+
+       malloc_unlock();
+}
+
+/*
+ * don't do any of "storage compaction" nonsense, "just" the three modes:
+ *   + cp == NULL ==> malloc
+ *   + nbytes == 0 ==> free
+ *   + else ==> realloc
+ */
+void *
+bmk_memrealloc(void *cp, unsigned long nbytes)
+{   
+       union overhead *op;
+       unsigned long size;
+       unsigned long alignpad;
+       void *np;
+
+       if (cp == NULL)
+               return bmk_memalloc(nbytes, MINALIGN);
+
+       if (nbytes == 0) {
+               bmk_memfree(cp);
+               return NULL;
+       }
+
+       op = ((union overhead *)cp)-1;
+       size = op->ov_index;
+       alignpad = op->ov_alignpad;
+
+       /* don't bother "compacting".  don't like it?  don't use realloc! */
+       if (((1<<(size+MINSHIFT)) - alignpad) >= nbytes)
+               return cp;
+
+       /* we're gonna need a bigger bucket */
+       np = bmk_memalloc(nbytes, 8);
+       if (np == NULL)
+               return NULL;
+
+       bmk_memcpy(np, cp, (1<<(size+MINSHIFT)) - alignpad);
+       bmk_memfree(cp);
+       return np;
+}
+
+#ifdef MSTATS
+/*
+ * mstats - print out statistics about malloc
+ * 
+ * Prints two lines of numbers, one showing the length of the free list
+ * for each size category, the second showing the number of mallocs -
+ * frees for each size category.
+ */
+void
+mstats(const char *s)
+{
+       int i, j;
+       union overhead *p;
+       int totfree = 0,
+       totused = 0;
+
+       fprintf(stderr, "Memory allocation statistics %s\nfree:\t", s);
+       for (i = 0; i < NBUCKETS; i++) {
+               for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)
+                       ;
+               fprintf(stderr, " %d", j);
+               totfree += j * (1 << (i + 3));
+       }
+       fprintf(stderr, "\nused:\t");
+       for (i = 0; i < NBUCKETS; i++) {
+               fprintf(stderr, " %d", nmalloc[i]);
+               totused += nmalloc[i] * (1 << (i + 3));
+       }
+       fprintf(stderr, "\n\tTotal in use: %d, total free: %d\n",
+           totused, totfree);
+}
+#endif
+
+#ifdef MEMALLOC_TESTING
+
+#define TEST_MINALLOC 0
+#define TEST_MAXALLOC 64*1024
+
+#define TEST_MINALIGN 1
+#define TEST_MAXALIGN 16
+
+#define NALLOC 1024
+#define NRING 16
+
+static void *
+testalloc(void)
+{
+       void *v, *nv;
+       size_t size1, size2, align;
+
+       /* doesn't give an even bucket distribution, but ... */
+       size1 = random() % ((TEST_MAXALLOC-TEST_MINALLOC)+1) + TEST_MINALLOC;
+       align = random() % ((TEST_MAXALIGN-TEST_MINALIGN)+1) + TEST_MINALIGN;
+
+       v = bmk_memalloc(size1, 1<<align);
+       if (!v)
+               return NULL;
+       ASSERT(((uintptr_t)v & (align-1)) == 0);
+       memset(v, UNMAGIC, size1);
+
+       size2 = random() % ((TEST_MAXALLOC-TEST_MINALLOC)+1) + TEST_MINALLOC;
+       nv = memrealloc(v, size2);
+       if (nv) {
+               memset(nv, UNMAGIC2, size2);
+               return nv;
+       }
+
+       return size2 ? v : NULL;
+}
+
+int
+main()
+{
+       void **rings; /* yay! */
+       void **ring_alloc, **ring_free; /* yay! */
+       int i, n;
+
+       srandom(time(NULL));
+
+       rings = malloc(NALLOC * NRING * sizeof(void *));
+       /* so we can free() immediately without stress */
+       memset(rings, 0, NALLOC * NRING * sizeof(void *));
+
+       for (n = 0;; n = (n+1) % NRING) {
+               if (n == 0)
+                       mstats("");
+
+               ring_alloc = &rings[n * NALLOC];
+               ring_free = &rings[((n + NRING/2) % NRING) * NALLOC];
+               for (i = 0; i < NALLOC; i++) {
+                       ring_alloc[i] = testalloc();
+                       bmk_memfree(ring_free[i]);
+               }
+       }
+}
+#endif
diff --git a/lib/libbmk_core/sched.c b/lib/libbmk_core/sched.c
new file mode 100644 (file)
index 0000000..5fcd402
--- /dev/null
@@ -0,0 +1,525 @@
+/*-
+ * Copyright (c) 2007-2015 Antti Kantee.  All Rights Reserved.
+ * Copyright (c) 2014 Justin Cormack.  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.
+ */
+
+/* 
+ ****************************************************************************
+ * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
+ ****************************************************************************
+ *
+ *        File: sched.c
+ *      Author: Grzegorz Milos
+ *     Changes: Robert Kaiser
+ *              
+ *        Date: Aug 2005
+ * 
+ * Environment: Xen Minimal OS
+ * Description: simple scheduler for Mini-Os
+ *
+ * The scheduler is non-preemptive (cooperative), and schedules according 
+ * to Round Robin algorithm.
+ *
+ ****************************************************************************
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <bmk-core/core.h>
+#include <bmk-core/memalloc.h>
+#include <bmk-core/platform.h>
+#include <bmk-core/printf.h>
+#include <bmk-core/queue.h>
+#include <bmk-core/string.h>
+#include <bmk-core/sched.h>
+
+#define TLS_COUNT 2
+#define NAME_MAXLEN 16
+
+#define THREAD_RUNNABLE        0x01
+#define THREAD_MUSTJOIN        0x02
+#define THREAD_JOINED  0x04
+#define THREAD_EXTSTACK        0x08
+#define THREAD_TIMEDOUT        0x10
+
+struct bmk_thread {
+       char bt_name[NAME_MAXLEN];
+
+       void *bt_tls[TLS_COUNT];
+
+       bmk_time_t bt_wakeup_time;
+
+       int bt_flags;
+       int bt_errno;
+
+       void *bt_stackbase;
+
+       void *bt_cookie;
+
+       /* MD thread control block */
+       struct bmk_tcb bt_tcb;
+
+       TAILQ_ENTRY(bmk_thread) bt_entries;
+};
+
+static TAILQ_HEAD(, bmk_thread) zombies = TAILQ_HEAD_INITIALIZER(zombies);
+static TAILQ_HEAD(, bmk_thread) threads = TAILQ_HEAD_INITIALIZER(threads);
+
+static void (*scheduler_hook)(void *, void *);
+
+static int
+is_runnable(struct bmk_thread *thread)
+{
+
+       return thread->bt_flags & THREAD_RUNNABLE;
+}
+
+static void
+set_runnable(struct bmk_thread *thread)
+{
+
+       thread->bt_flags |= THREAD_RUNNABLE;
+}
+
+static void
+clear_runnable(struct bmk_thread *thread)
+{
+
+       thread->bt_flags &= ~THREAD_RUNNABLE;
+}
+
+static void
+stackalloc(void **stack, unsigned long *ss)
+{
+
+       *stack = bmk_platform_allocpg2(bmk_stackpageorder);
+       *ss = bmk_stacksize;
+}
+
+static void
+stackfree(struct bmk_thread *thread)
+{
+
+       bmk_platform_freepg2(thread->bt_stackbase, bmk_stackpageorder);
+}
+
+static void
+print_threadinfo(struct bmk_thread *thread)
+{
+
+       bmk_printf("thread \"%s\" at %p, flags 0x%x\n",
+           thread->bt_name, thread, thread->bt_flags);
+}
+
+static void
+sched_switch(struct bmk_thread *prev, struct bmk_thread *next)
+{
+
+       if (scheduler_hook)
+               scheduler_hook(prev->bt_cookie, next->bt_cookie);
+       bmk_platform_cpu_sched_switch(&prev->bt_tcb, &next->bt_tcb);
+}
+
+struct bmk_thread *
+bmk_sched_current(void)
+{
+
+       return bmk_cpu_sched_current();
+}
+
+void
+bmk_sched_dumpqueue(void)
+{
+       struct bmk_thread *thr;
+
+       bmk_printf("BEGIN schedqueue dump\n");
+       TAILQ_FOREACH(thr, &threads, bt_entries) {
+               print_threadinfo(thr);
+       }
+       bmk_printf("END schedqueue dump\n");
+}
+
+void
+bmk_sched(void)
+{
+       struct bmk_thread *prev, *next, *thread, *tmp;
+       unsigned long flags;
+
+       prev = bmk_sched_current();
+       flags = bmk_platform_splhigh();
+
+#if 0
+       /* XXX */
+       if (_minios_in_hypervisor_callback) {
+               minios_printk("Must not call schedule() from a callback\n");
+               BUG();
+       }
+#endif
+
+       if (flags) {
+               bmk_platform_halt("Must not call sched() with IRQs disabled\n");
+       }
+
+       /* could do time management a bit better here */
+       do {
+               bmk_time_t tm, wakeup;
+
+               /* block domain for max 1s */
+               tm = bmk_clock_monotonic();
+               wakeup = tm + 1*1000*1000*1000ULL;
+
+               next = NULL;
+               TAILQ_FOREACH_SAFE(thread, &threads, bt_entries, tmp) {
+                       if (!is_runnable(thread)
+                           && thread->bt_wakeup_time >= 0) {
+                               if (thread->bt_wakeup_time <= tm) {
+                                       thread->bt_flags |= THREAD_TIMEDOUT;
+                                       bmk_sched_wake(thread);
+                               } else if (thread->bt_wakeup_time < wakeup)
+                                       wakeup = thread->bt_wakeup_time;
+                       }
+                       if (is_runnable(thread)) {
+                               next = thread;
+                               /* Put this thread on the end of the list */
+                               TAILQ_REMOVE(&threads, thread, bt_entries);
+                               TAILQ_INSERT_TAIL(&threads, thread, bt_entries);
+                               break;
+                       }
+               }
+               if (next)
+                       break;
+
+               /* sleep for a while */
+               bmk_platform_block(wakeup);
+       } while (1);
+
+       bmk_platform_splx(flags);
+
+       if (prev != next) {
+               sched_switch(prev, next);
+       }
+
+       /* reaper */
+       TAILQ_FOREACH_SAFE(thread, &zombies, bt_entries, tmp) {
+               if (thread != prev) {
+                       TAILQ_REMOVE(&zombies, thread, bt_entries);
+                       if ((thread->bt_flags & THREAD_EXTSTACK) == 0)
+                               stackfree(thread);
+                       bmk_memfree(thread);
+               }
+       }
+}
+
+/*
+ * Allocate tls and initialize it.
+ *
+ * XXX: this needs to change in the future so that
+ * we put the tcb in the same space instead of having multiple
+ * random copies flying around.
+ */
+extern const char _tdata_start[], _tdata_end[];
+extern const char _tbss_start[], _tbss_end[];
+static int
+allocothertls(struct bmk_thread *thread)
+{
+       const unsigned long tdatasize = _tdata_end - _tdata_start;
+       const unsigned long tbsssize = _tbss_end - _tbss_start;
+       struct bmk_tcb *tcb = &thread->bt_tcb;
+       char *tlsmem;
+
+       tlsmem = bmk_memalloc(tdatasize + tbsssize, 0);
+
+       bmk_memcpy(tlsmem, _tdata_start, tdatasize);
+       bmk_memset(tlsmem + tdatasize, 0, tbsssize);
+
+       tcb->btcb_tp = (unsigned long)(tlsmem + tdatasize + tbsssize);
+       tcb->btcb_tpsize = tdatasize + tbsssize;
+
+       return 0;
+}
+
+static void
+freeothertls(struct bmk_thread *thread)
+{
+       void *mem;
+
+       mem = (void *)(thread->bt_tcb.btcb_tp-thread->bt_tcb.btcb_tpsize);
+       bmk_memfree(mem);
+}
+
+struct bmk_thread *
+bmk_sched_create(const char *name, void *cookie, int joinable,
+       void (*f)(void *), void *data,
+       void *stack_base, unsigned long stack_size)
+{
+       struct bmk_thread *thread;
+       unsigned long flags;
+
+       thread = bmk_xmalloc(sizeof(*thread));
+       bmk_memset(thread, 0, sizeof(*thread));
+       bmk_strncpy(thread->bt_name, name, sizeof(thread->bt_name)-1);
+
+       if (!stack_base) {
+               bmk_assert(stack_size == 0);
+               stackalloc(&stack_base, &stack_size);
+       } else {
+               thread->bt_flags = THREAD_EXTSTACK;
+       }
+       thread->bt_stackbase = stack_base;
+       if (joinable)
+               thread->bt_flags |= THREAD_MUSTJOIN;
+
+       bmk_cpu_sched_create(thread, &thread->bt_tcb, f, data,
+           stack_base, stack_size);
+
+       thread->bt_cookie = cookie;
+
+       thread->bt_wakeup_time = -1;
+
+       flags = bmk_platform_splhigh();
+       TAILQ_INSERT_TAIL(&threads, thread, bt_entries);
+       bmk_platform_splx(flags);
+
+       allocothertls(thread);
+       set_runnable(thread);
+
+       return thread;
+}
+
+struct join_waiter {
+       struct bmk_thread *jw_thread;
+       struct bmk_thread *jw_wanted;
+       TAILQ_ENTRY(join_waiter) jw_entries;
+};
+static TAILQ_HEAD(, join_waiter) joinwq = TAILQ_HEAD_INITIALIZER(joinwq);
+
+void
+bmk_sched_exit(void)
+{
+       struct bmk_thread *thread = bmk_sched_current();
+       struct join_waiter *jw_iter;
+       unsigned long flags;
+
+       /* if joinable, gate until we are allowed to exit */
+       flags = bmk_platform_splhigh();
+       while (thread->bt_flags & THREAD_MUSTJOIN) {
+               thread->bt_flags |= THREAD_JOINED;
+               bmk_platform_splx(flags);
+
+               /* see if the joiner is already there */
+               TAILQ_FOREACH(jw_iter, &joinwq, jw_entries) {
+                       if (jw_iter->jw_wanted == thread) {
+                               bmk_sched_wake(jw_iter->jw_thread);
+                               break;
+                       }
+               }
+               bmk_sched_block(thread);
+               bmk_sched();
+               flags = bmk_platform_splhigh();
+       }
+       freeothertls(thread);
+
+       /* Remove from the thread list */
+       TAILQ_REMOVE(&threads, thread, bt_entries);
+       clear_runnable(thread);
+       /* Put onto exited list */
+       TAILQ_INSERT_HEAD(&zombies, thread, bt_entries);
+       bmk_platform_splx(flags);
+
+       /* bye */
+       bmk_sched();
+       bmk_platform_halt("schedule() returned for a dead thread!\n");
+}
+
+void
+bmk_sched_join(struct bmk_thread *joinable)
+{
+       struct join_waiter jw;
+       struct bmk_thread *thread = bmk_sched_current();
+       unsigned long flags;
+
+       bmk_assert(joinable->bt_flags & THREAD_MUSTJOIN);
+
+       flags = bmk_platform_splhigh();
+       /* wait for exiting thread to hit thread_exit() */
+       while ((joinable->bt_flags & THREAD_JOINED) == 0) {
+               bmk_platform_splx(flags);
+
+               jw.jw_thread = thread;
+               jw.jw_wanted = joinable;
+               TAILQ_INSERT_TAIL(&joinwq, &jw, jw_entries);
+               bmk_sched_block(thread);
+               bmk_sched();
+               TAILQ_REMOVE(&joinwq, &jw, jw_entries);
+
+               flags = bmk_platform_splhigh();
+       }
+
+       /* signal exiting thread that we have seen it and it may now exit */
+       bmk_assert(joinable->bt_flags & THREAD_JOINED);
+       joinable->bt_flags &= ~THREAD_MUSTJOIN;
+       bmk_platform_splx(flags);
+
+       bmk_sched_wake(joinable);
+}
+
+void
+bmk_sched_block_timeout(struct bmk_thread *thread, bmk_time_t deadline)
+{
+
+       thread->bt_wakeup_time = deadline;
+       clear_runnable(thread);
+}
+
+void
+bmk_sched_block(struct bmk_thread *thread)
+{
+
+       bmk_sched_block_timeout(thread, -1);
+}
+
+int
+bmk_sched_nanosleep_abstime(bmk_time_t nsec)
+{
+       struct bmk_thread *thread = bmk_sched_current();
+       int rv;
+
+       thread->bt_flags &= ~THREAD_TIMEDOUT;
+       thread->bt_wakeup_time = nsec;
+       clear_runnable(thread);
+       bmk_sched();
+
+       rv = !!(thread->bt_flags & THREAD_TIMEDOUT);
+       thread->bt_flags &= ~THREAD_TIMEDOUT;
+       return rv;
+}
+
+int
+bmk_sched_nanosleep(bmk_time_t nsec)
+{
+
+       return bmk_sched_nanosleep_abstime(nsec + bmk_clock_monotonic());
+}
+
+void
+bmk_sched_wake(struct bmk_thread *thread)
+{
+
+       thread->bt_wakeup_time = -1;
+       set_runnable(thread);
+}
+
+void
+bmk_sched_init(void (*mainfun)(void *), void *arg)
+{
+       struct bmk_thread *mainthread;
+       struct bmk_thread initthread;
+
+       mainthread = bmk_sched_create("main", NULL, 0, mainfun, arg, NULL, 0);
+       if (mainthread == NULL)
+               bmk_platform_halt("failed to create main thread");
+
+       bmk_memset(&initthread, 0, sizeof(initthread));
+       bmk_strcpy(initthread.bt_name, "init");
+       sched_switch(&initthread, mainthread);
+
+       bmk_platform_halt("bmk_sched_init unreachable");
+}
+
+void
+bmk_sched_set_hook(void (*f)(void *, void *))
+{
+
+       scheduler_hook = f;
+}
+
+struct bmk_thread *
+bmk_sched_init_mainlwp(void *cookie)
+{
+       struct bmk_thread *current = bmk_sched_current();
+
+       current->bt_cookie = cookie;
+       allocothertls(current);
+       return current;
+}
+
+const char *
+bmk_sched_threadname(struct bmk_thread *thread)
+{
+
+       return thread->bt_name;
+}
+
+int *
+bmk_sched_geterrno(void)
+{
+       struct bmk_thread *thread = bmk_sched_current();
+
+       return &thread->bt_errno;
+}
+
+void
+bmk_sched_settls(struct bmk_thread *thread, unsigned int which, void *value)
+{
+
+       if (which >= TLS_COUNT) {
+               bmk_platform_halt("out of bmk sched tls space");
+       }
+       thread->bt_tls[which] = value;
+}
+
+void *
+bmk_sched_gettls(struct bmk_thread *thread, unsigned int which)
+{
+
+       if (which >= TLS_COUNT) {
+               bmk_platform_halt("out of bmk sched tls space");
+       }
+       return thread->bt_tls[which];
+}
+
+void
+bmk_sched_yield(void)
+{
+       struct bmk_thread *current = bmk_sched_current();
+
+       TAILQ_REMOVE(&threads, current, bt_entries);
+       TAILQ_INSERT_TAIL(&threads, current, bt_entries);
+       bmk_sched();
+}
diff --git a/lib/libbmk_core/subr_prf.c b/lib/libbmk_core/subr_prf.c
new file mode 100644 (file)
index 0000000..415c62b
--- /dev/null
@@ -0,0 +1,638 @@
+/*     $NetBSD: subr_prf.c,v 1.157 2015/02/04 07:10:47 msaitoh Exp $   */
+
+/*-
+ * Copyright (c) 1986, 1988, 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS 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.
+ *
+ *     @(#)subr_prf.c  8.4 (Berkeley) 5/4/95
+ */
+
+/*
+ * This is the NetBSD kernel printf code heavily stripped.  Format support
+ * is the same, but the wrappers for calling printf have been reduced
+ * down to:
+ *   + printf
+ *   + snprintf
+ *   + vnsprintf
+ */
+
+#define _BMK_PRINTF_VA
+#include <bmk-core/null.h>
+#include <bmk-core/printf.h>
+#include <bmk-core/string.h>
+
+#define TOBUFONLY      0x01
+#define TOCONS         0x02
+
+#define __UNCONST(x) ((void *)(unsigned long)(x))
+#define KPRINTF_BUFSIZE (sizeof(long long)*8/3 + 2)
+
+/*
+ * local prototypes
+ */
+
+static void    cons_putchar(int, int);
+static int     kprintf(const char *, int, void *, char *, va_list);
+
+/*
+ * globals
+ */
+
+static void
+nullfun(void)
+{
+
+       return;
+}
+
+static void (*v_flush)(void);
+static void (*v_putc)(int);
+
+void
+bmk_printf_init(void (*putc)(int), void (*flush)(void))
+{
+
+       v_putc = putc;
+       if (flush == NULL)
+               flush = nullfun;
+       v_flush = flush;
+}
+
+static const char hexdigits[] = "0123456789abcdef";
+static const char HEXDIGITS[] = "0123456789ABCDEF";
+
+/*
+ * functions
+ */
+
+/* dmesg ring buffer */
+#ifndef BMK_DMESG_SIZE
+#define BMK_DMESG_SIZE (16*1024)
+#endif
+static char bmk_dmesg[BMK_DMESG_SIZE];
+static int bmk_dmesgoff;
+
+/*
+ * putchar: print a single character on console or user terminal.
+ *
+ * => if console, then the last MSGBUFS chars are saved in msgbuf
+ *     for inspection later (e.g. dmesg/syslog)
+ * => we must already be in the mutex!
+ */
+static void
+cons_putchar(int c, int flags)
+{
+
+       bmk_dmesg[bmk_dmesgoff] = c;
+       if (++bmk_dmesgoff == sizeof(bmk_dmesg)-1)
+               bmk_dmesgoff = 0;
+       (*v_putc)(c);
+}
+
+static void
+kprintf_lock(void)
+{
+
+       /* XXX */
+}
+
+static void
+kprintf_unlock(void)
+{
+
+       /* XXX */
+}
+
+/*
+ * bmk_printf: print a message to the console
+ */
+void
+bmk_printf(const char *fmt, ...)
+{
+        va_list ap;
+
+        kprintf_lock();
+
+        va_start(ap, fmt);
+        kprintf(fmt, TOCONS, NULL, NULL, ap);
+        va_end(ap);
+
+        kprintf_unlock();
+}
+
+/*
+ * bmk_vprintf: print a message to the console [already have
+ *      va_list]
+ */
+void
+bmk_vprintf(const char *fmt, va_list ap)
+{
+       kprintf_lock();
+
+       kprintf(fmt, TOCONS, NULL, NULL, ap);
+
+       kprintf_unlock();
+}
+
+/*
+ * bmk_snprintf: print a message to a buffer
+ */
+int
+bmk_snprintf(char *bf, unsigned long size, const char *fmt, ...)
+{
+       int retval;
+       va_list ap;
+
+       va_start(ap, fmt);
+       retval = bmk_vsnprintf(bf, size, fmt, ap);
+       va_end(ap);
+
+       return retval;
+}
+
+/*
+ * bmk_vsnprintf: print a message to a buffer [already have va_list]
+ */
+int
+bmk_vsnprintf(char *bf, unsigned long size, const char *fmt, va_list ap)
+{
+       int retval;
+       char *p;
+
+       p = bf + size;
+       retval = kprintf(fmt, TOBUFONLY, &p, bf, ap);
+       if (bf && size > 0) {
+               /* nul terminate */
+               if (size <= (unsigned long)retval)
+                       bf[size - 1] = '\0';
+               else
+                       bf[retval] = '\0';
+       }
+       return retval;
+}
+
+/*
+ * kprintf: scaled down version of printf(3).
+ *
+ * this version based on vfprintf() from libc which was derived from
+ * software contributed to Berkeley by Chris Torek.
+ *
+ * NOTE: The kprintf mutex must be held if we're going TOBUF or TOCONS!
+ */
+
+/*
+ * macros for converting digits to letters and vice versa
+ */
+#define        to_digit(c)     ((c) - '0')
+#define is_digit(c)    ((unsigned)to_digit(c) <= 9)
+#define        to_char(n)      ((n) + '0')
+
+/*
+ * flags used during conversion.
+ */
+#define        ALT             0x001           /* alternate form */
+#define        HEXPREFIX       0x002           /* add 0x or 0X prefix */
+#define        LADJUST         0x004           /* left adjustment */
+#define        LONGDBL         0x008           /* long double; unimplemented */
+#define        LONGINT         0x010           /* long integer */
+#define        QUADINT         0x020           /* quad integer */
+#define        SHORTINT        0x040           /* short integer */
+#define        MAXINT          0x080           /* intmax_t */
+#define        PTRINT          0x100           /* intptr_t */
+#define        SIZEINT         0x200           /* size_t */
+#define        ZEROPAD         0x400           /* zero (as opposed to blank) pad */
+#define FPT            0x800           /* Floating point number */
+
+       /*
+        * To extend shorts properly, we need both signed and unsigned
+        * argument extraction methods.
+        */
+#define        SARG() \
+       (flags&MAXINT ? va_arg(ap, long long) : \
+           flags&PTRINT ? va_arg(ap, long) : \
+           flags&SIZEINT ? va_arg(ap, long) : /* XXX */ \
+           flags&QUADINT ? va_arg(ap, long long) : \
+           flags&LONGINT ? va_arg(ap, long) : \
+           flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
+           (long)va_arg(ap, int))
+#define        UARG() \
+       (flags&MAXINT ? va_arg(ap, unsigned long long) : \
+           flags&PTRINT ? va_arg(ap, unsigned long) : \
+           flags&SIZEINT ? va_arg(ap, unsigned long) : \
+           flags&QUADINT ? va_arg(ap, unsigned long long) : \
+           flags&LONGINT ? va_arg(ap, unsigned long) : \
+           flags&SHORTINT ? (unsigned long)(unsigned long)va_arg(ap, int) : \
+           (unsigned long)va_arg(ap, unsigned int))
+
+#define KPRINTF_PUTCHAR(C) {                                           \
+       if (oflags == TOBUFONLY) {                                      \
+               if (sbuf && ((vp == NULL) || (sbuf < tailp)))           \
+                       *sbuf++ = (C);                                  \
+       } else {                                                        \
+               cons_putchar((C), oflags);                              \
+       }                                                               \
+}
+
+/*
+ * Guts of kernel printf.  Note, we already expect to be in a mutex!
+ */
+static int
+kprintf(const char *fmt0, int oflags, void *vp, char *sbuf, va_list ap)
+{
+       int ret = 0;            /* return value accumulator */
+       const char *fmt;        /* format string */
+       int ch;                 /* character from fmt */
+       int n;                  /* handy integer (short term usage) */
+       char *cp;               /* handy char pointer (short term usage) */
+       int flags;              /* flags as above */
+       int width;              /* width from format (%8d), or 0 */
+       int prec;               /* precision from format (%.3d), or -1 */
+       char sign;              /* sign prefix (' ', '+', '-', or \0) */
+
+       unsigned long long _uquad; /* integer arguments %[diouxX] */
+       enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
+       int dprec;              /* a copy of prec if [diouxX], 0 otherwise */
+       int realsz;             /* field size expanded by dprec */
+       int size;               /* size of converted field or string */
+       const char *xdigs;      /* digits for [xX] conversion */
+       char bf[KPRINTF_BUFSIZE]; /* space for %c, %[diouxX] */
+       char *tailp;            /* tail pointer for snprintf */
+
+       if (oflags == TOBUFONLY && (vp != NULL))
+               tailp = *(char **)vp;
+       else
+               tailp = NULL;
+
+       cp = NULL;      /* XXX: shutup gcc */
+       size = 0;       /* XXX: shutup gcc */
+
+       fmt = fmt0;
+       ret = 0;
+
+       xdigs = NULL;           /* XXX: shut up gcc warning */
+
+       /*
+        * Scan the format for conversions (`%' character).
+        */
+       for (;;) {
+               for (; *fmt != '%' && *fmt; fmt++) {
+                       ret++;
+                       KPRINTF_PUTCHAR(*fmt);
+               }
+               if (*fmt == 0)
+                       goto done;
+
+               fmt++;          /* skip over '%' */
+
+               flags = 0;
+               dprec = 0;
+               width = 0;
+               prec = -1;
+               sign = '\0';
+
+rflag:         ch = *fmt++;
+reswitch:      switch (ch) {
+               case ' ':
+                       /*
+                        * ``If the space and + flags both appear, the space
+                        * flag will be ignored.''
+                        *      -- ANSI X3J11
+                        */
+                       if (!sign)
+                               sign = ' ';
+                       goto rflag;
+               case '#':
+                       flags |= ALT;
+                       goto rflag;
+               case '*':
+                       /*
+                        * ``A negative field width argument is taken as a
+                        * - flag followed by a positive field width.''
+                        *      -- ANSI X3J11
+                        * They don't exclude field widths read from args.
+                        */
+                       if ((width = va_arg(ap, int)) >= 0)
+                               goto rflag;
+                       width = -width;
+                       /* FALLTHROUGH */
+               case '-':
+                       flags |= LADJUST;
+                       goto rflag;
+               case '+':
+                       sign = '+';
+                       goto rflag;
+               case '.':
+                       if ((ch = *fmt++) == '*') {
+                               n = va_arg(ap, int);
+                               prec = n < 0 ? -1 : n;
+                               goto rflag;
+                       }
+                       n = 0;
+                       while (is_digit(ch)) {
+                               n = 10 * n + to_digit(ch);
+                               ch = *fmt++;
+                       }
+                       prec = n < 0 ? -1 : n;
+                       goto reswitch;
+               case '0':
+                       /*
+                        * ``Note that 0 is taken as a flag, not as the
+                        * beginning of a field width.''
+                        *      -- ANSI X3J11
+                        */
+                       flags |= ZEROPAD;
+                       goto rflag;
+               case '1': case '2': case '3': case '4':
+               case '5': case '6': case '7': case '8': case '9':
+                       n = 0;
+                       do {
+                               n = 10 * n + to_digit(ch);
+                               ch = *fmt++;
+                       } while (is_digit(ch));
+                       width = n;
+                       goto reswitch;
+               case 'h':
+                       flags |= SHORTINT;
+                       goto rflag;
+               case 'j':
+                       flags |= MAXINT;
+                       goto rflag;
+               case 'l':
+                       if (*fmt == 'l') {
+                               fmt++;
+                               flags |= QUADINT;
+                       } else {
+                               flags |= LONGINT;
+                       }
+                       goto rflag;
+               case 'q':
+                       flags |= QUADINT;
+                       goto rflag;
+               case 't':
+                       flags |= PTRINT;
+                       goto rflag;
+               case 'z':
+                       flags |= SIZEINT;
+                       goto rflag;
+               case 'c':
+                       *(cp = bf) = va_arg(ap, int);
+                       size = 1;
+                       sign = '\0';
+                       break;
+               case 'D':
+                       flags |= LONGINT;
+                       /*FALLTHROUGH*/
+               case 'd':
+               case 'i':
+                       _uquad = SARG();
+                       if ((long long)_uquad < 0) {
+                               _uquad = -_uquad;
+                               sign = '-';
+                       }
+                       base = DEC;
+                       goto number;
+               case 'n':
+                       if (flags & MAXINT)
+                               *va_arg(ap, long long *) = ret;
+                       else if (flags & PTRINT)
+                               *va_arg(ap, long *) = ret;
+                       else if (flags & SIZEINT)
+                               *va_arg(ap, long *) = ret;
+                       else if (flags & QUADINT)
+                               *va_arg(ap, long long *) = ret;
+                       else if (flags & LONGINT)
+                               *va_arg(ap, long *) = ret;
+                       else if (flags & SHORTINT)
+                               *va_arg(ap, short *) = ret;
+                       else
+                               *va_arg(ap, int *) = ret;
+                       continue;       /* no output */
+               case 'O':
+                       flags |= LONGINT;
+                       /*FALLTHROUGH*/
+               case 'o':
+                       _uquad = UARG();
+                       base = OCT;
+                       goto nosign;
+               case 'p':
+                       /*
+                        * ``The argument shall be a pointer to void.  The
+                        * value of the pointer is converted to a sequence
+                        * of printable characters, in an implementation-
+                        * defined manner.''
+                        *      -- ANSI X3J11
+                        */
+                       /* NOSTRICT */
+                       _uquad = (unsigned long)va_arg(ap, void *);
+                       base = HEX;
+                       xdigs = hexdigits;
+                       flags |= HEXPREFIX;
+                       ch = 'x';
+                       goto nosign;
+               case 's':
+                       if ((cp = va_arg(ap, char *)) == NULL)
+                               /*XXXUNCONST*/
+                               cp = __UNCONST("(null)");
+                       if (prec >= 0) {
+                               /*
+                                * can't use strlen; can only look for the
+                                * NUL in the first `prec' characters, and
+                                * strlen() will go further.
+                                */
+                               char *p = bmk_memchr(cp, 0, prec);
+
+                               if (p != NULL) {
+                                       size = p - cp;
+                                       if (size > prec)
+                                               size = prec;
+                               } else
+                                       size = prec;
+                       } else
+                               size = bmk_strlen(cp);
+                       sign = '\0';
+                       break;
+               case 'U':
+                       flags |= LONGINT;
+                       /*FALLTHROUGH*/
+               case 'u':
+                       _uquad = UARG();
+                       base = DEC;
+                       goto nosign;
+               case 'X':
+                       xdigs = HEXDIGITS;
+                       goto hex;
+               case 'x':
+                       xdigs = hexdigits;
+hex:                   _uquad = UARG();
+                       base = HEX;
+                       /* leading 0x/X only if non-zero */
+                       if (flags & ALT && _uquad != 0)
+                               flags |= HEXPREFIX;
+
+                       /* unsigned conversions */
+nosign:                        sign = '\0';
+                       /*
+                        * ``... diouXx conversions ... if a precision is
+                        * specified, the 0 flag will be ignored.''
+                        *      -- ANSI X3J11
+                        */
+number:                        if ((dprec = prec) >= 0)
+                               flags &= ~ZEROPAD;
+
+                       /*
+                        * ``The result of converting a zero value with an
+                        * explicit precision of zero is no characters.''
+                        *      -- ANSI X3J11
+                        */
+                       cp = bf + KPRINTF_BUFSIZE;
+                       if (_uquad != 0 || prec != 0) {
+                               /*
+                                * Unsigned mod is hard, and unsigned mod
+                                * by a constant is easier than that by
+                                * a variable; hence this switch.
+                                */
+                               switch (base) {
+                               case OCT:
+                                       do {
+                                               *--cp = to_char(_uquad & 7);
+                                               _uquad >>= 3;
+                                       } while (_uquad);
+                                       /* handle octal leading 0 */
+                                       if (flags & ALT && *cp != '0')
+                                               *--cp = '0';
+                                       break;
+
+                               case DEC:
+                                       /* many numbers are 1 digit */
+                                       while (_uquad >= 10) {
+                                               *--cp = to_char(_uquad % 10);
+                                               _uquad /= 10;
+                                       }
+                                       *--cp = to_char(_uquad);
+                                       break;
+
+                               case HEX:
+                                       do {
+                                               *--cp = xdigs[_uquad & 15];
+                                               _uquad >>= 4;
+                                       } while (_uquad);
+                                       break;
+
+                               default:
+                                       /*XXXUNCONST*/
+                                       cp = __UNCONST("bug in kprintf: bad base");
+                                       size = bmk_strlen(cp);
+                                       goto skipsize;
+                               }
+                       }
+                       size = bf + KPRINTF_BUFSIZE - cp;
+               skipsize:
+                       break;
+               default:        /* "%?" prints ?, unless ? is NUL */
+                       if (ch == '\0')
+                               goto done;
+                       /* pretend it was %c with argument ch */
+                       cp = bf;
+                       *cp = ch;
+                       size = 1;
+                       sign = '\0';
+                       break;
+               }
+
+               /*
+                * All reasonable formats wind up here.  At this point, `cp'
+                * points to a string which (if not flags&LADJUST) should be
+                * padded out to `width' places.  If flags&ZEROPAD, it should
+                * first be prefixed by any sign or other prefix; otherwise,
+                * it should be blank padded before the prefix is emitted.
+                * After any left-hand padding and prefixing, emit zeroes
+                * required by a decimal [diouxX] precision, then print the
+                * string proper, then emit zeroes required by any leftover
+                * floating precision; finally, if LADJUST, pad with blanks.
+                *
+                * Compute actual size, so we know how much to pad.
+                * size excludes decimal prec; realsz includes it.
+                */
+               realsz = dprec > size ? dprec : size;
+               if (sign)
+                       realsz++;
+               else if (flags & HEXPREFIX)
+                       realsz+= 2;
+
+               /* adjust ret */
+               ret += width > realsz ? width : realsz;
+
+               /* right-adjusting blank padding */
+               if ((flags & (LADJUST|ZEROPAD)) == 0) {
+                       n = width - realsz;
+                       while (n-- > 0)
+                               KPRINTF_PUTCHAR(' ');
+               }
+
+               /* prefix */
+               if (sign) {
+                       KPRINTF_PUTCHAR(sign);
+               } else if (flags & HEXPREFIX) {
+                       KPRINTF_PUTCHAR('0');
+                       KPRINTF_PUTCHAR(ch);
+               }
+
+               /* right-adjusting zero padding */
+               if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) {
+                       n = width - realsz;
+                       while (n-- > 0)
+                               KPRINTF_PUTCHAR('0');
+               }
+
+               /* leading zeroes from decimal precision */
+               n = dprec - size;
+               while (n-- > 0)
+                       KPRINTF_PUTCHAR('0');
+
+               /* the string or number proper */
+               for (; size--; cp++)
+                       KPRINTF_PUTCHAR(*cp);
+               /* left-adjusting padding (always blank) */
+               if (flags & LADJUST) {
+                       n = width - realsz;
+                       while (n-- > 0)
+                               KPRINTF_PUTCHAR(' ');
+               }
+       }
+
+done:
+       if ((oflags == TOBUFONLY) && (vp != NULL))
+               *(char **)vp = sbuf;
+       (*v_flush)();
+
+       return ret;
+}
diff --git a/lib/librumprun_core/Makefile b/lib/librumprun_core/Makefile
deleted file mode 100644 (file)
index 9984df3..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-LIB=           rumprun_core
-LIBISPRIVATE=  # defined
-
-SRCS=          init.c bmk_string.c memalloc.c sched.c subr_prf.c
-
-CPPFLAGS+=     -I${.CURDIR}/../../include
-
-.include "${.CURDIR}/arch/${MACHINE}/Makefile.inc"
-
-.include <bsd.lib.mk>
diff --git a/lib/librumprun_core/arch/amd64/Makefile.inc b/lib/librumprun_core/arch/amd64/Makefile.inc
deleted file mode 100644 (file)
index 80b2d56..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-MYDIR:=        ${.PARSEDIR}
-.PATH: ${MYDIR}
-
-SRCS+= cpu_sched_switch.S
-
-.include "${MYDIR}/../x86/Makefile.inc"
diff --git a/lib/librumprun_core/arch/amd64/cpu_sched_switch.S b/lib/librumprun_core/arch/amd64/cpu_sched_switch.S
deleted file mode 100644 (file)
index 4747652..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*-
- ****************************************************************************
- * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
- ****************************************************************************
- *
- *        File: sched.c
- *      Author: Grzegorz Milos
- *     Changes: Robert Kaiser
- *
- *        Date: Aug 2005
- *
- * Environment: Xen Minimal OS
- * Description: simple scheduler for Mini-Os
- *
- * The scheduler is non-preemptive (cooperative), and schedules according
- * to Round Robin algorithm.
- *
- ****************************************************************************
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <bmk-core/amd64/asm.h>
-
-ENTRY(bmk_cpu_sched_bouncer)
-       popq %rdi
-       popq %rbx
-       pushq $0                        /* correct stack alignment for SSE */
-       pushq $0
-       xorq %rbp,%rbp
-       call *%rbx
-       call bmk_sched_exit
-END(bmk_cpu_sched_bouncer)
-
-ENTRY(bmk__cpu_switch)
-       pushq %rbp
-       pushq %rbx
-       pushq %r12
-       pushq %r13
-       pushq %r14
-       pushq %r15
-       movq %rsp, (%rdi)               /* save ESP */
-       movq (%rsi), %rsp               /* restore ESP */
-       movq $1f, 8(%rdi)               /* save EIP */
-       pushq 8(%rsi)                   /* restore EIP */
-       ret
-1:
-       popq %r15
-       popq %r14
-       popq %r13
-       popq %r12
-       popq %rbx
-       popq %rbp
-       ret
-END(bmk__cpu_switch)
diff --git a/lib/librumprun_core/arch/i386/Makefile.inc b/lib/librumprun_core/arch/i386/Makefile.inc
deleted file mode 100644 (file)
index 80b2d56..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-MYDIR:=        ${.PARSEDIR}
-.PATH: ${MYDIR}
-
-SRCS+= cpu_sched_switch.S
-
-.include "${MYDIR}/../x86/Makefile.inc"
diff --git a/lib/librumprun_core/arch/i386/cpu_sched_switch.S b/lib/librumprun_core/arch/i386/cpu_sched_switch.S
deleted file mode 100644 (file)
index cc9ec7d..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*-
- ****************************************************************************
- * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
- ****************************************************************************
- *
- *        File: sched.c
- *      Author: Grzegorz Milos
- *     Changes: Robert Kaiser
- *              
- *        Date: Aug 2005
- * 
- * Environment: Xen Minimal OS
- * Description: simple scheduler for Mini-Os
- *
- * The scheduler is non-preemptive (cooperative), and schedules according 
- * to Round Robin algorithm.
- *
- ****************************************************************************
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <bmk-core/i386/asm.h>
-
-ENTRY(bmk_cpu_sched_bouncer)
-       popl %eax
-       popl %ebx
-       pushl $0
-       xorl %ebp,%ebp
-       pushl %eax
-       call *%ebx
-       call bmk_sched_exit
-END(bmk_cpu_sched_bouncer)
-
-ENTRY(bmk__cpu_switch)
-       movl 4(%esp), %ecx              /* prev */
-       movl 8(%esp), %edx              /* next */
-
-       /* reload tls for new thread */
-       movl $0x18, %eax
-       movl %eax, %gs
-
-       pushl %ebp
-       pushl %ebx
-       pushl %esi
-       pushl %edi
-       movl %esp, (%ecx)               /* save ESP */
-       movl (%edx), %esp               /* restore ESP */
-       movl $1f, 4(%ecx)               /* save EIP */
-       pushl 4(%edx)                   /* restore EIP */
-       ret
-1:
-       popl %edi
-       popl %esi
-       popl %ebx
-       popl %ebp
-       ret
-END(bmk__cpu_switch)
diff --git a/lib/librumprun_core/arch/x86/Makefile.inc b/lib/librumprun_core/arch/x86/Makefile.inc
deleted file mode 100644 (file)
index 757c137..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-X86DIR:=${.PARSEDIR}
-.PATH: ${X86DIR}
-
-SRCS+= cpu_sched.c
diff --git a/lib/librumprun_core/arch/x86/cpu_sched.c b/lib/librumprun_core/arch/x86/cpu_sched.c
deleted file mode 100644 (file)
index f9c945d..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- ****************************************************************************
- * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
- ****************************************************************************
- *
- *        File: sched.c
- *      Author: Grzegorz Milos
- *     Changes: Robert Kaiser
- *
- *        Date: Aug 2005
- *
- * Environment: Xen Minimal OS
- * Description: simple scheduler for Mini-Os
- *
- * The scheduler is non-preemptive (cooperative), and schedules according
- * to Round Robin algorithm.
- *
- ****************************************************************************
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <bmk-core/core.h>
-#include <bmk-core/sched.h>
-
-static void
-stack_push(void **stackp, unsigned long value)
-{
-       unsigned long *stack = *stackp;
-
-       stack--;
-       *stack = value;
-       *stackp = stack;
-}
-
-void
-bmk_cpu_sched_create(struct bmk_thread *thread, struct bmk_tcb *tcb,
-       void (*f)(void *), void *arg,
-       void *stack_base, unsigned long stack_size)
-{
-       void *stack_top = (char *)stack_base + stack_size;
-
-       /* Save pointer to the thread on the stack, used by current macro */
-       *(unsigned long *)stack_base = (unsigned long)thread;
-
-       /* these values are used by bmk_cpu_sched_bouncer() */
-       stack_push(&stack_top, (unsigned long)f);
-       stack_push(&stack_top, (unsigned long)arg);
-
-       tcb->btcb_sp = (unsigned long)stack_top;
-       tcb->btcb_ip = (unsigned long)bmk_cpu_sched_bouncer;
-}
-
-struct bmk_thread *
-bmk_cpu_sched_current(void)
-{
-       struct bmk_thread **current;
-
-       current = (void *)((unsigned long)&current & ~(bmk_stacksize-1));
-       return *current;
-};
diff --git a/lib/librumprun_core/bmk_string.c b/lib/librumprun_core/bmk_string.c
deleted file mode 100644 (file)
index fb53980..0000000
+++ /dev/null
@@ -1,135 +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.
- */
-
-/*
- * The assumption is that these won't be used very often,
- * only for the very low-level routines.
- *
- * Some code from public domain implementations.
- */
-
-#include <bmk-core/null.h>
-#include <bmk-core/string.h>
-
-unsigned long
-bmk_strlen(const char *str)
-{
-       unsigned long rv = 0;
-
-       while (*str++)
-               rv++;
-       return rv;
-}
-
-int
-bmk_strcmp(const char *a, const char *b)
-{
-
-       while (*a && *a++ == *b++) {
-               continue;
-       }
-       if (*a) {
-               a--;
-               b--;
-       }
-       return *a - *b;
-}
-
-int
-bmk_strncmp(const char *a, const char *b, unsigned long n)
-{
-       unsigned char u1, u2;
-
-       while (n-- > 0) {
-               u1 = (unsigned char)*a++;
-               u2 = (unsigned char)*b++;
-               if (u1 != u2)
-                       return u1 - u2;
-               if (u1 == '\0')
-                       return 0;
-       }
-       return 0;
-}
-
-char *
-bmk_strcpy(char *d, const char *s)
-{
-       char *orig = d;
-
-       while ((*d++ = *s++) != '\0')
-               continue;
-       return orig;
-}
-
-char *
-bmk_strncpy(char *d, const char *s, unsigned long n)
-{
-       char *orig = d;
-
-       while ((*d++ = *s++) && n--)
-               continue;
-       while (n--)
-               *d++ = '\0';
-       return orig;
-}
-
-void *
-bmk_memset(void *b, int c, unsigned long n)
-{
-       unsigned char *v = b;
-
-       while (n--)
-               *v++ = (unsigned char)c;
-
-       return b;
-}
-
-void *
-bmk_memcpy(void *d, const void *src, unsigned long n)
-{
-       unsigned char *dp;
-       const unsigned char *sp;
-
-       dp = d;
-       sp = src;
-
-       while (n--)
-               *dp++ = *sp++;
-
-       return d;
-}
-
-void *
-bmk_memchr(const void *d, int c, unsigned long n)
-{
-       const unsigned char *p = d;
-
-       while (n--) {
-               if (*p == (unsigned char)c)
-                       return (void *)(unsigned long)p;
-               p++;
-       }
-       return NULL;
-}
diff --git a/lib/librumprun_core/init.c b/lib/librumprun_core/init.c
deleted file mode 100644 (file)
index 215b59e..0000000
+++ /dev/null
@@ -1,41 +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.
- */
-
-#include <bmk-core/core.h>
-
-unsigned long bmk_stackpageorder;
-unsigned long bmk_stacksize;
-unsigned long bmk_pagesize;
-
-int
-bmk_core_init(unsigned long stackpageorder, unsigned long pagesize)
-{
-
-       bmk_stackpageorder = stackpageorder;
-       bmk_stacksize = (1<<stackpageorder) * pagesize;
-       bmk_pagesize = pagesize;
-
-       return 0;
-}
diff --git a/lib/librumprun_core/memalloc.c b/lib/librumprun_core/memalloc.c
deleted file mode 100644 (file)
index 4551fdc..0000000
+++ /dev/null
@@ -1,569 +0,0 @@
-/*
- * Copyright (c) 2013 Antti Kantee.  All rights reserved.
- * Copyright (c) 1983, 1993
- *     The Regents of the University of California.  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.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS 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.
- */
-
-/*
- * malloc.c (Caltech) 2/21/82
- * Chris Kingsley, kingsley@cit-20.
- *
- * This is a very fast storage allocator.  It allocates blocks of a small 
- * number of different sizes, and keeps free lists of each size.  Blocks that
- * don't exactly fit are passed up to the next larger size.  In this 
- * implementation, the available sizes are 2^n-4 (or 2^n-10) bytes long.
- * This is designed for use in a virtual memory environment.
- *
- * Modified for Xen Mini-OS:
- *  + allocate backing storage with page_alloc() instead of sbrk()
- *  + support alignment
- *  + use ANSI C (hey, there's no rush!)
- */
-
-#ifdef MEMALLOC_TESTING
-#define PAGE_SIZE getpagesize()
-#define MSTATS
-
-#include <sys/cdefs.h>
-
-#include <sys/types.h>
-#if defined(RCHECK)
-#include <sys/uio.h>
-#endif
-#if defined(RCHECK) || defined(MSTATS)
-#include <stdio.h>
-#endif
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#else
-
-#include <bmk-core/core.h>
-#include <bmk-core/string.h>
-#include <bmk-core/memalloc.h>
-#include <bmk-core/platform.h>
-
-#define NULL (void *)0
-#define ASSERT(x)
-
-#endif
-
-
-/*
- * The overhead on a block is at least 4 bytes.  When free, this space
- * contains a pointer to the next free block, and the bottom two bits must
- * be zero.  When in use, the first byte is set to MAGIC, and the second
- * byte is the size index.  The remaining bytes are for alignment.
- * If range checking is enabled then a second word holds the size of the
- * requested block, less 1, rounded up to a multiple of sizeof(RMAGIC).
- * The order of elements is critical: ov_magic must overlay the low order
- * bits of ov_next, and ov_magic can not be a valid ov_next bit pattern.
- */
-union  overhead {
-       union   overhead *ov_next;      /* when free */
-       struct {
-               unsigned long  ovu_alignpad;    /* padding for alignment */
-               unsigned char   ovu_magic;      /* magic number */
-               unsigned char   ovu_index;      /* bucket # */
-#ifdef RCHECK
-               unsigned short  ovu_rmagic;     /* range magic number */
-               unsigned long   ovu_size;       /* actual block size */
-#endif
-       } ovu;
-#define        ov_alignpad     ovu.ovu_alignpad
-#define        ov_magic        ovu.ovu_magic
-#define        ov_index        ovu.ovu_index
-#define        ov_rmagic       ovu.ovu_rmagic
-#define        ov_size         ovu.ovu_size
-};
-
-#define        MAGIC           0xef            /* magic # on accounting info */
-#define UNMAGIC                0x12            /* magic # != MAGIC */
-#define UNMAGIC2       0x24            /* magic # != MAGIC/UNMAGIC */
-#ifdef RCHECK
-#define RMAGIC         0x5555          /* magic # on range info */
-#endif
-
-#ifdef RCHECK
-#define        RSLOP           sizeof (unsigned short)
-#else
-#define        RSLOP           0
-#endif
-
-/*
- * nextf[i] is the pointer to the next free block of size 2^(i+MINSHIFT).  The
- * smallest allocatable block is 1<<MINSHIFT bytes.  The overhead information
- * precedes the data area returned to the user.
- */
-#define MINSHIFT 5
-#define        NBUCKETS 30
-#define MINALIGN 16
-static union overhead *nextf[NBUCKETS];
-
-static long pagesz;                    /* page size */
-static int pagebucket;                 /* page size bucket */
-
-#ifdef MSTATS
-/*
- * nmalloc[i] is the difference between the number of mallocs and frees
- * for a given block size.
- */
-static u_int nmalloc[NBUCKETS];
-#endif
-
-#if 0
-#ifdef _REENT
-static mutex_t malloc_mutex = MUTEX_INITIALIZER;
-#endif
-#endif
-
-/* not currently reentrant on mini-os */
-#define malloc_lock()
-#define malloc_unlock()
-
-static void morecore(int);
-#ifdef MSTATS
-void mstats(const char *);
-#endif
-
-#if defined(RCHECK) || defined(MEMALLOC_TESTING)
-#define        ASSERT(p)   if (!(p)) botch(__STRING(p))
-#include <sys/uio.h>
-
-static void botch(const char *);
-
-/*
- * NOTE: since this may be called while malloc_mutex is locked, stdio must not
- *       be used in this function.
- */
-static void
-botch(const char *s)
-{
-       struct iovec iov[3];
-
-       iov[0].iov_base = "\nassertion botched: ";
-       iov[0].iov_len  = 20;
-       iov[1].iov_base = (void *)s;
-       iov[1].iov_len  = strlen(s);
-       iov[2].iov_base = "\n";
-       iov[2].iov_len  = 1;
-
-       /*
-        * This place deserves a word of warning: a cancellation point will
-        * occur when executing writev(), and we might be still owning
-        * malloc_mutex.  At this point we need to disable cancellation
-        * until `after' abort() because i) establishing a cancellation handler
-        * might, depending on the implementation, result in another malloc()
-        * to be executed, and ii) it is really not desirable to let execution
-        * continue.  `Fix me.'
-        * 
-        * Note that holding mutex_lock during abort() is safe.
-        */
-
-       (void)writev(STDERR_FILENO, iov, 3);
-       abort();
-}
-#endif
-
-void *
-bmk_memalloc(unsigned long nbytes, unsigned long align)
-{
-       union overhead *op;
-       void *rv;
-       unsigned long allocbytes;
-       int bucket;
-       unsigned amt;
-       unsigned long alignpad;
-
-       malloc_lock();
-
-       if (pagesz == 0) {
-               pagesz = bmk_pagesize;
-               ASSERT(pagesz > 0);
-
-#if 0
-               op = (union overhead *)(void *)sbrk(0);
-               n = n - sizeof (*op) - ((long)op & (n - 1));
-               if (n < 0)
-                       n += pagesz;
-               if (n) {
-                       if (sbrk((int)n) == (void *)-1) {
-                               malloc_unlock();
-                               return (NULL);
-                       }
-               }
-#endif
-
-               bucket = 0;
-               amt = 1<<MINSHIFT;
-               while (pagesz > amt) {
-                       amt <<= 1;
-                       bucket++;
-               }
-               pagebucket = bucket;
-       }
-
-       if (align & (align-1))
-               return NULL;
-       if (align < MINALIGN)
-               align = MINALIGN;
-       
-       /* need at least this many bytes plus header to satisfy alignment */
-       allocbytes = nbytes + ((sizeof(*op) + (align-1)) & ~(align-1));
-
-       /*
-        * Convert amount of memory requested into closest block size
-        * stored in hash buckets which satisfies request.
-        * Account for space used per block for accounting.
-        */
-       if (allocbytes <= pagesz - RSLOP) {
-#ifndef RCHECK
-               amt = 1<<MINSHIFT;      /* size of first bucket */
-               bucket = 0;
-#else
-               amt = 1<<(MINSHIFT+1);  /* size of first bucket */
-               bucket = 1;
-#endif
-       } else {
-               amt = (unsigned)pagesz;
-               bucket = pagebucket;
-       }
-       while (allocbytes > amt) {
-               amt <<= 1;
-               if (amt == 0)
-                       return (NULL);
-               bucket++;
-       }
-       /*
-        * If nothing in hash bucket right now,
-        * request more memory from the system.
-        */
-       if ((op = nextf[bucket]) == NULL) {
-               morecore(bucket);
-               if ((op = nextf[bucket]) == NULL) {
-                       malloc_unlock();
-                       return (NULL);
-               }
-       }
-       /* remove from linked list */
-       nextf[bucket] = op->ov_next;
-
-       /* align op before returned memory */
-       rv = (void *)(((unsigned long)(op+1) + align - 1) & ~(align - 1));
-       alignpad = (unsigned long)rv - (unsigned long)op;
-
-#ifdef MEMALLOC_TESTING
-       memset(op, MAGIC, alignpad);
-#endif
-
-       op = ((union overhead *)rv)-1;
-       op->ov_magic = MAGIC;
-       op->ov_index = bucket;
-       op->ov_alignpad = alignpad;
-#ifdef MSTATS
-       nmalloc[bucket]++;
-#endif
-       malloc_unlock();
-#ifdef RCHECK
-       /*
-        * Record allocated size of block and
-        * bound space with magic numbers.
-        */
-       op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
-       op->ov_rmagic = RMAGIC;
-       *(unsigned short *)((char *)(op + 1) + op->ov_size) = RMAGIC;
-#endif
-
-       return rv;
-}
-
-void *
-bmk_xmalloc(unsigned long howmuch)
-{
-       void *rv;
-
-       rv = bmk_memalloc(howmuch, 0);
-       if (rv == NULL)
-               bmk_platform_halt("xmalloc failed");
-       return rv;
-}
-
-void *
-bmk_memcalloc(unsigned long n, unsigned long size)
-{
-       void *v;
-       unsigned long tot = n * size;
-
-       if (size != 0 && tot / size != n)
-               return NULL;
-
-       if ((v = bmk_memalloc(tot, MINALIGN)) != NULL) {
-               bmk_memset(v, 0, tot);
-       }
-       return v;
-}
-
-static void *
-corealloc(int shift)
-{
-       void *v;
-
-#ifdef MEMALLOC_TESTING
-       v = malloc((1<<shift) * pagesz);
-#else
-       v = bmk_platform_allocpg2(shift);
-#endif
-
-       return v;
-}
-
-/*
- * Allocate more memory to the indicated bucket.
- */
-static void
-morecore(int bucket)
-{
-       union overhead *op;
-       long sz;                /* size of desired block */
-       long amt;                       /* amount to allocate */
-       long nblks;                     /* how many blocks we get */
-
-       if (bucket < pagebucket) {
-               amt = 0;
-               nblks = pagesz / (1<<(bucket + MINSHIFT));
-               sz = pagesz / nblks;
-       } else {
-               amt = bucket - pagebucket;
-               nblks = 1;
-               sz = 0; /* dummy */
-       }
-       op = (void *)corealloc(amt);
-       /* no more room! */
-       if (op == NULL)
-               return;
-       /*
-        * Add new memory allocated to that on
-        * free list for this hash bucket.
-        */
-       nextf[bucket] = op;
-       while (--nblks > 0) {
-               op->ov_next =
-                   (union overhead *)(void *)((char *)(void *)op+(unsigned long)sz);
-               op = op->ov_next;
-       }
-       op->ov_next = NULL;
-}
-
-void
-bmk_memfree(void *cp)
-{   
-       long size;
-       union overhead *op;
-       unsigned long alignpad;
-       void *origp;
-
-       if (cp == NULL)
-               return;
-       op = ((union overhead *)cp)-1;
-       if (op->ov_magic != MAGIC) {
-#ifdef MEMALLOC_TESTING
-               ASSERT(0);
-#endif
-               return;                         /* sanity */
-       }
-
-#ifdef RCHECK
-       ASSERT(op->ov_rmagic == RMAGIC);
-       ASSERT(*(unsigned short *)((char *)(op + 1) + op->ov_size) == RMAGIC);
-#endif
-       size = op->ov_index;
-       alignpad = op->ov_alignpad;
-       ASSERT(size < NBUCKETS);
-
-       malloc_lock();
-       origp = (unsigned char *)cp - alignpad;
-
-#ifdef MEMALLOC_TESTING
-       {
-               unsigned long i;
-
-               for (i = 0;
-                   (unsigned char *)origp + i < (unsigned char *)op;
-                   i++) {
-                       ASSERT(*((unsigned char *)origp + i) == MAGIC);
-                               
-               }
-       }
-#endif
-
-       op = (void *)origp;
-       op->ov_next = nextf[(unsigned int)size];/* also clobbers ov_magic */
-       nextf[(unsigned int)size] = op;
-#ifdef MSTATS
-       nmalloc[(unsigned long)size]--;
-#endif
-
-       malloc_unlock();
-}
-
-/*
- * don't do any of "storage compaction" nonsense, "just" the three modes:
- *   + cp == NULL ==> malloc
- *   + nbytes == 0 ==> free
- *   + else ==> realloc
- */
-void *
-bmk_memrealloc(void *cp, unsigned long nbytes)
-{   
-       union overhead *op;
-       unsigned long size;
-       unsigned long alignpad;
-       void *np;
-
-       if (cp == NULL)
-               return bmk_memalloc(nbytes, MINALIGN);
-
-       if (nbytes == 0) {
-               bmk_memfree(cp);
-               return NULL;
-       }
-
-       op = ((union overhead *)cp)-1;
-       size = op->ov_index;
-       alignpad = op->ov_alignpad;
-
-       /* don't bother "compacting".  don't like it?  don't use realloc! */
-       if (((1<<(size+MINSHIFT)) - alignpad) >= nbytes)
-               return cp;
-
-       /* we're gonna need a bigger bucket */
-       np = bmk_memalloc(nbytes, 8);
-       if (np == NULL)
-               return NULL;
-
-       bmk_memcpy(np, cp, (1<<(size+MINSHIFT)) - alignpad);
-       bmk_memfree(cp);
-       return np;
-}
-
-#ifdef MSTATS
-/*
- * mstats - print out statistics about malloc
- * 
- * Prints two lines of numbers, one showing the length of the free list
- * for each size category, the second showing the number of mallocs -
- * frees for each size category.
- */
-void
-mstats(const char *s)
-{
-       int i, j;
-       union overhead *p;
-       int totfree = 0,
-       totused = 0;
-
-       fprintf(stderr, "Memory allocation statistics %s\nfree:\t", s);
-       for (i = 0; i < NBUCKETS; i++) {
-               for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)
-                       ;
-               fprintf(stderr, " %d", j);
-               totfree += j * (1 << (i + 3));
-       }
-       fprintf(stderr, "\nused:\t");
-       for (i = 0; i < NBUCKETS; i++) {
-               fprintf(stderr, " %d", nmalloc[i]);
-               totused += nmalloc[i] * (1 << (i + 3));
-       }
-       fprintf(stderr, "\n\tTotal in use: %d, total free: %d\n",
-           totused, totfree);
-}
-#endif
-
-#ifdef MEMALLOC_TESTING
-
-#define TEST_MINALLOC 0
-#define TEST_MAXALLOC 64*1024
-
-#define TEST_MINALIGN 1
-#define TEST_MAXALIGN 16
-
-#define NALLOC 1024
-#define NRING 16
-
-static void *
-testalloc(void)
-{
-       void *v, *nv;
-       size_t size1, size2, align;
-
-       /* doesn't give an even bucket distribution, but ... */
-       size1 = random() % ((TEST_MAXALLOC-TEST_MINALLOC)+1) + TEST_MINALLOC;
-       align = random() % ((TEST_MAXALIGN-TEST_MINALIGN)+1) + TEST_MINALIGN;
-
-       v = bmk_memalloc(size1, 1<<align);
-       if (!v)
-               return NULL;
-       ASSERT(((uintptr_t)v & (align-1)) == 0);
-       memset(v, UNMAGIC, size1);
-
-       size2 = random() % ((TEST_MAXALLOC-TEST_MINALLOC)+1) + TEST_MINALLOC;
-       nv = memrealloc(v, size2);
-       if (nv) {
-               memset(nv, UNMAGIC2, size2);
-               return nv;
-       }
-
-       return size2 ? v : NULL;
-}
-
-int
-main()
-{
-       void **rings; /* yay! */
-       void **ring_alloc, **ring_free; /* yay! */
-       int i, n;
-
-       srandom(time(NULL));
-
-       rings = malloc(NALLOC * NRING * sizeof(void *));
-       /* so we can free() immediately without stress */
-       memset(rings, 0, NALLOC * NRING * sizeof(void *));
-
-       for (n = 0;; n = (n+1) % NRING) {
-               if (n == 0)
-                       mstats("");
-
-               ring_alloc = &rings[n * NALLOC];
-               ring_free = &rings[((n + NRING/2) % NRING) * NALLOC];
-               for (i = 0; i < NALLOC; i++) {
-                       ring_alloc[i] = testalloc();
-                       bmk_memfree(ring_free[i]);
-               }
-       }
-}
-#endif
diff --git a/lib/librumprun_core/sched.c b/lib/librumprun_core/sched.c
deleted file mode 100644 (file)
index 5fcd402..0000000
+++ /dev/null
@@ -1,525 +0,0 @@
-/*-
- * Copyright (c) 2007-2015 Antti Kantee.  All Rights Reserved.
- * Copyright (c) 2014 Justin Cormack.  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.
- */
-
-/* 
- ****************************************************************************
- * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
- ****************************************************************************
- *
- *        File: sched.c
- *      Author: Grzegorz Milos
- *     Changes: Robert Kaiser
- *              
- *        Date: Aug 2005
- * 
- * Environment: Xen Minimal OS
- * Description: simple scheduler for Mini-Os
- *
- * The scheduler is non-preemptive (cooperative), and schedules according 
- * to Round Robin algorithm.
- *
- ****************************************************************************
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <bmk-core/core.h>
-#include <bmk-core/memalloc.h>
-#include <bmk-core/platform.h>
-#include <bmk-core/printf.h>
-#include <bmk-core/queue.h>
-#include <bmk-core/string.h>
-#include <bmk-core/sched.h>
-
-#define TLS_COUNT 2
-#define NAME_MAXLEN 16
-
-#define THREAD_RUNNABLE        0x01
-#define THREAD_MUSTJOIN        0x02
-#define THREAD_JOINED  0x04
-#define THREAD_EXTSTACK        0x08
-#define THREAD_TIMEDOUT        0x10
-
-struct bmk_thread {
-       char bt_name[NAME_MAXLEN];
-
-       void *bt_tls[TLS_COUNT];
-
-       bmk_time_t bt_wakeup_time;
-
-       int bt_flags;
-       int bt_errno;
-
-       void *bt_stackbase;
-
-       void *bt_cookie;
-
-       /* MD thread control block */
-       struct bmk_tcb bt_tcb;
-
-       TAILQ_ENTRY(bmk_thread) bt_entries;
-};
-
-static TAILQ_HEAD(, bmk_thread) zombies = TAILQ_HEAD_INITIALIZER(zombies);
-static TAILQ_HEAD(, bmk_thread) threads = TAILQ_HEAD_INITIALIZER(threads);
-
-static void (*scheduler_hook)(void *, void *);
-
-static int
-is_runnable(struct bmk_thread *thread)
-{
-
-       return thread->bt_flags & THREAD_RUNNABLE;
-}
-
-static void
-set_runnable(struct bmk_thread *thread)
-{
-
-       thread->bt_flags |= THREAD_RUNNABLE;
-}
-
-static void
-clear_runnable(struct bmk_thread *thread)
-{
-
-       thread->bt_flags &= ~THREAD_RUNNABLE;
-}
-
-static void
-stackalloc(void **stack, unsigned long *ss)
-{
-
-       *stack = bmk_platform_allocpg2(bmk_stackpageorder);
-       *ss = bmk_stacksize;
-}
-
-static void
-stackfree(struct bmk_thread *thread)
-{
-
-       bmk_platform_freepg2(thread->bt_stackbase, bmk_stackpageorder);
-}
-
-static void
-print_threadinfo(struct bmk_thread *thread)
-{
-
-       bmk_printf("thread \"%s\" at %p, flags 0x%x\n",
-           thread->bt_name, thread, thread->bt_flags);
-}
-
-static void
-sched_switch(struct bmk_thread *prev, struct bmk_thread *next)
-{
-
-       if (scheduler_hook)
-               scheduler_hook(prev->bt_cookie, next->bt_cookie);
-       bmk_platform_cpu_sched_switch(&prev->bt_tcb, &next->bt_tcb);
-}
-
-struct bmk_thread *
-bmk_sched_current(void)
-{
-
-       return bmk_cpu_sched_current();
-}
-
-void
-bmk_sched_dumpqueue(void)
-{
-       struct bmk_thread *thr;
-
-       bmk_printf("BEGIN schedqueue dump\n");
-       TAILQ_FOREACH(thr, &threads, bt_entries) {
-               print_threadinfo(thr);
-       }
-       bmk_printf("END schedqueue dump\n");
-}
-
-void
-bmk_sched(void)
-{
-       struct bmk_thread *prev, *next, *thread, *tmp;
-       unsigned long flags;
-
-       prev = bmk_sched_current();
-       flags = bmk_platform_splhigh();
-
-#if 0
-       /* XXX */
-       if (_minios_in_hypervisor_callback) {
-               minios_printk("Must not call schedule() from a callback\n");
-               BUG();
-       }
-#endif
-
-       if (flags) {
-               bmk_platform_halt("Must not call sched() with IRQs disabled\n");
-       }
-
-       /* could do time management a bit better here */
-       do {
-               bmk_time_t tm, wakeup;
-
-               /* block domain for max 1s */
-               tm = bmk_clock_monotonic();
-               wakeup = tm + 1*1000*1000*1000ULL;
-
-               next = NULL;
-               TAILQ_FOREACH_SAFE(thread, &threads, bt_entries, tmp) {
-                       if (!is_runnable(thread)
-                           && thread->bt_wakeup_time >= 0) {
-                               if (thread->bt_wakeup_time <= tm) {
-                                       thread->bt_flags |= THREAD_TIMEDOUT;
-                                       bmk_sched_wake(thread);
-                               } else if (thread->bt_wakeup_time < wakeup)
-                                       wakeup = thread->bt_wakeup_time;
-                       }
-                       if (is_runnable(thread)) {
-                               next = thread;
-                               /* Put this thread on the end of the list */
-                               TAILQ_REMOVE(&threads, thread, bt_entries);
-                               TAILQ_INSERT_TAIL(&threads, thread, bt_entries);
-                               break;
-                       }
-               }
-               if (next)
-                       break;
-
-               /* sleep for a while */
-               bmk_platform_block(wakeup);
-       } while (1);
-
-       bmk_platform_splx(flags);
-
-       if (prev != next) {
-               sched_switch(prev, next);
-       }
-
-       /* reaper */
-       TAILQ_FOREACH_SAFE(thread, &zombies, bt_entries, tmp) {
-               if (thread != prev) {
-                       TAILQ_REMOVE(&zombies, thread, bt_entries);
-                       if ((thread->bt_flags & THREAD_EXTSTACK) == 0)
-                               stackfree(thread);
-                       bmk_memfree(thread);
-               }
-       }
-}
-
-/*
- * Allocate tls and initialize it.
- *
- * XXX: this needs to change in the future so that
- * we put the tcb in the same space instead of having multiple
- * random copies flying around.
- */
-extern const char _tdata_start[], _tdata_end[];
-extern const char _tbss_start[], _tbss_end[];
-static int
-allocothertls(struct bmk_thread *thread)
-{
-       const unsigned long tdatasize = _tdata_end - _tdata_start;
-       const unsigned long tbsssize = _tbss_end - _tbss_start;
-       struct bmk_tcb *tcb = &thread->bt_tcb;
-       char *tlsmem;
-
-       tlsmem = bmk_memalloc(tdatasize + tbsssize, 0);
-
-       bmk_memcpy(tlsmem, _tdata_start, tdatasize);
-       bmk_memset(tlsmem + tdatasize, 0, tbsssize);
-
-       tcb->btcb_tp = (unsigned long)(tlsmem + tdatasize + tbsssize);
-       tcb->btcb_tpsize = tdatasize + tbsssize;
-
-       return 0;
-}
-
-static void
-freeothertls(struct bmk_thread *thread)
-{
-       void *mem;
-
-       mem = (void *)(thread->bt_tcb.btcb_tp-thread->bt_tcb.btcb_tpsize);
-       bmk_memfree(mem);
-}
-
-struct bmk_thread *
-bmk_sched_create(const char *name, void *cookie, int joinable,
-       void (*f)(void *), void *data,
-       void *stack_base, unsigned long stack_size)
-{
-       struct bmk_thread *thread;
-       unsigned long flags;
-
-       thread = bmk_xmalloc(sizeof(*thread));
-       bmk_memset(thread, 0, sizeof(*thread));
-       bmk_strncpy(thread->bt_name, name, sizeof(thread->bt_name)-1);
-
-       if (!stack_base) {
-               bmk_assert(stack_size == 0);
-               stackalloc(&stack_base, &stack_size);
-       } else {
-               thread->bt_flags = THREAD_EXTSTACK;
-       }
-       thread->bt_stackbase = stack_base;
-       if (joinable)
-               thread->bt_flags |= THREAD_MUSTJOIN;
-
-       bmk_cpu_sched_create(thread, &thread->bt_tcb, f, data,
-           stack_base, stack_size);
-
-       thread->bt_cookie = cookie;
-
-       thread->bt_wakeup_time = -1;
-
-       flags = bmk_platform_splhigh();
-       TAILQ_INSERT_TAIL(&threads, thread, bt_entries);
-       bmk_platform_splx(flags);
-
-       allocothertls(thread);
-       set_runnable(thread);
-
-       return thread;
-}
-
-struct join_waiter {
-       struct bmk_thread *jw_thread;
-       struct bmk_thread *jw_wanted;
-       TAILQ_ENTRY(join_waiter) jw_entries;
-};
-static TAILQ_HEAD(, join_waiter) joinwq = TAILQ_HEAD_INITIALIZER(joinwq);
-
-void
-bmk_sched_exit(void)
-{
-       struct bmk_thread *thread = bmk_sched_current();
-       struct join_waiter *jw_iter;
-       unsigned long flags;
-
-       /* if joinable, gate until we are allowed to exit */
-       flags = bmk_platform_splhigh();
-       while (thread->bt_flags & THREAD_MUSTJOIN) {
-               thread->bt_flags |= THREAD_JOINED;
-               bmk_platform_splx(flags);
-
-               /* see if the joiner is already there */
-               TAILQ_FOREACH(jw_iter, &joinwq, jw_entries) {
-                       if (jw_iter->jw_wanted == thread) {
-                               bmk_sched_wake(jw_iter->jw_thread);
-                               break;
-                       }
-               }
-               bmk_sched_block(thread);
-               bmk_sched();
-               flags = bmk_platform_splhigh();
-       }
-       freeothertls(thread);
-
-       /* Remove from the thread list */
-       TAILQ_REMOVE(&threads, thread, bt_entries);
-       clear_runnable(thread);
-       /* Put onto exited list */
-       TAILQ_INSERT_HEAD(&zombies, thread, bt_entries);
-       bmk_platform_splx(flags);
-
-       /* bye */
-       bmk_sched();
-       bmk_platform_halt("schedule() returned for a dead thread!\n");
-}
-
-void
-bmk_sched_join(struct bmk_thread *joinable)
-{
-       struct join_waiter jw;
-       struct bmk_thread *thread = bmk_sched_current();
-       unsigned long flags;
-
-       bmk_assert(joinable->bt_flags & THREAD_MUSTJOIN);
-
-       flags = bmk_platform_splhigh();
-       /* wait for exiting thread to hit thread_exit() */
-       while ((joinable->bt_flags & THREAD_JOINED) == 0) {
-               bmk_platform_splx(flags);
-
-               jw.jw_thread = thread;
-               jw.jw_wanted = joinable;
-               TAILQ_INSERT_TAIL(&joinwq, &jw, jw_entries);
-               bmk_sched_block(thread);
-               bmk_sched();
-               TAILQ_REMOVE(&joinwq, &jw, jw_entries);
-
-               flags = bmk_platform_splhigh();
-       }
-
-       /* signal exiting thread that we have seen it and it may now exit */
-       bmk_assert(joinable->bt_flags & THREAD_JOINED);
-       joinable->bt_flags &= ~THREAD_MUSTJOIN;
-       bmk_platform_splx(flags);
-
-       bmk_sched_wake(joinable);
-}
-
-void
-bmk_sched_block_timeout(struct bmk_thread *thread, bmk_time_t deadline)
-{
-
-       thread->bt_wakeup_time = deadline;
-       clear_runnable(thread);
-}
-
-void
-bmk_sched_block(struct bmk_thread *thread)
-{
-
-       bmk_sched_block_timeout(thread, -1);
-}
-
-int
-bmk_sched_nanosleep_abstime(bmk_time_t nsec)
-{
-       struct bmk_thread *thread = bmk_sched_current();
-       int rv;
-
-       thread->bt_flags &= ~THREAD_TIMEDOUT;
-       thread->bt_wakeup_time = nsec;
-       clear_runnable(thread);
-       bmk_sched();
-
-       rv = !!(thread->bt_flags & THREAD_TIMEDOUT);
-       thread->bt_flags &= ~THREAD_TIMEDOUT;
-       return rv;
-}
-
-int
-bmk_sched_nanosleep(bmk_time_t nsec)
-{
-
-       return bmk_sched_nanosleep_abstime(nsec + bmk_clock_monotonic());
-}
-
-void
-bmk_sched_wake(struct bmk_thread *thread)
-{
-
-       thread->bt_wakeup_time = -1;
-       set_runnable(thread);
-}
-
-void
-bmk_sched_init(void (*mainfun)(void *), void *arg)
-{
-       struct bmk_thread *mainthread;
-       struct bmk_thread initthread;
-
-       mainthread = bmk_sched_create("main", NULL, 0, mainfun, arg, NULL, 0);
-       if (mainthread == NULL)
-               bmk_platform_halt("failed to create main thread");
-
-       bmk_memset(&initthread, 0, sizeof(initthread));
-       bmk_strcpy(initthread.bt_name, "init");
-       sched_switch(&initthread, mainthread);
-
-       bmk_platform_halt("bmk_sched_init unreachable");
-}
-
-void
-bmk_sched_set_hook(void (*f)(void *, void *))
-{
-
-       scheduler_hook = f;
-}
-
-struct bmk_thread *
-bmk_sched_init_mainlwp(void *cookie)
-{
-       struct bmk_thread *current = bmk_sched_current();
-
-       current->bt_cookie = cookie;
-       allocothertls(current);
-       return current;
-}
-
-const char *
-bmk_sched_threadname(struct bmk_thread *thread)
-{
-
-       return thread->bt_name;
-}
-
-int *
-bmk_sched_geterrno(void)
-{
-       struct bmk_thread *thread = bmk_sched_current();
-
-       return &thread->bt_errno;
-}
-
-void
-bmk_sched_settls(struct bmk_thread *thread, unsigned int which, void *value)
-{
-
-       if (which >= TLS_COUNT) {
-               bmk_platform_halt("out of bmk sched tls space");
-       }
-       thread->bt_tls[which] = value;
-}
-
-void *
-bmk_sched_gettls(struct bmk_thread *thread, unsigned int which)
-{
-
-       if (which >= TLS_COUNT) {
-               bmk_platform_halt("out of bmk sched tls space");
-       }
-       return thread->bt_tls[which];
-}
-
-void
-bmk_sched_yield(void)
-{
-       struct bmk_thread *current = bmk_sched_current();
-
-       TAILQ_REMOVE(&threads, current, bt_entries);
-       TAILQ_INSERT_TAIL(&threads, current, bt_entries);
-       bmk_sched();
-}
diff --git a/lib/librumprun_core/subr_prf.c b/lib/librumprun_core/subr_prf.c
deleted file mode 100644 (file)
index 415c62b..0000000
+++ /dev/null
@@ -1,638 +0,0 @@
-/*     $NetBSD: subr_prf.c,v 1.157 2015/02/04 07:10:47 msaitoh Exp $   */
-
-/*-
- * Copyright (c) 1986, 1988, 1991, 1993
- *     The Regents of the University of California.  All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * 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.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS 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.
- *
- *     @(#)subr_prf.c  8.4 (Berkeley) 5/4/95
- */
-
-/*
- * This is the NetBSD kernel printf code heavily stripped.  Format support
- * is the same, but the wrappers for calling printf have been reduced
- * down to:
- *   + printf
- *   + snprintf
- *   + vnsprintf
- */
-
-#define _BMK_PRINTF_VA
-#include <bmk-core/null.h>
-#include <bmk-core/printf.h>
-#include <bmk-core/string.h>
-
-#define TOBUFONLY      0x01
-#define TOCONS         0x02
-
-#define __UNCONST(x) ((void *)(unsigned long)(x))
-#define KPRINTF_BUFSIZE (sizeof(long long)*8/3 + 2)
-
-/*
- * local prototypes
- */
-
-static void    cons_putchar(int, int);
-static int     kprintf(const char *, int, void *, char *, va_list);
-
-/*
- * globals
- */
-
-static void
-nullfun(void)
-{
-
-       return;
-}
-
-static void (*v_flush)(void);
-static void (*v_putc)(int);
-
-void
-bmk_printf_init(void (*putc)(int), void (*flush)(void))
-{
-
-       v_putc = putc;
-       if (flush == NULL)
-               flush = nullfun;
-       v_flush = flush;
-}
-
-static const char hexdigits[] = "0123456789abcdef";
-static const char HEXDIGITS[] = "0123456789ABCDEF";
-
-/*
- * functions
- */
-
-/* dmesg ring buffer */
-#ifndef BMK_DMESG_SIZE
-#define BMK_DMESG_SIZE (16*1024)
-#endif
-static char bmk_dmesg[BMK_DMESG_SIZE];
-static int bmk_dmesgoff;
-
-/*
- * putchar: print a single character on console or user terminal.
- *
- * => if console, then the last MSGBUFS chars are saved in msgbuf
- *     for inspection later (e.g. dmesg/syslog)
- * => we must already be in the mutex!
- */
-static void
-cons_putchar(int c, int flags)
-{
-
-       bmk_dmesg[bmk_dmesgoff] = c;
-       if (++bmk_dmesgoff == sizeof(bmk_dmesg)-1)
-               bmk_dmesgoff = 0;
-       (*v_putc)(c);
-}
-
-static void
-kprintf_lock(void)
-{
-
-       /* XXX */
-}
-
-static void
-kprintf_unlock(void)
-{
-
-       /* XXX */
-}
-
-/*
- * bmk_printf: print a message to the console
- */
-void
-bmk_printf(const char *fmt, ...)
-{
-        va_list ap;
-
-        kprintf_lock();
-
-        va_start(ap, fmt);
-        kprintf(fmt, TOCONS, NULL, NULL, ap);
-        va_end(ap);
-
-        kprintf_unlock();
-}
-
-/*
- * bmk_vprintf: print a message to the console [already have
- *      va_list]
- */
-void
-bmk_vprintf(const char *fmt, va_list ap)
-{
-       kprintf_lock();
-
-       kprintf(fmt, TOCONS, NULL, NULL, ap);
-
-       kprintf_unlock();
-}
-
-/*
- * bmk_snprintf: print a message to a buffer
- */
-int
-bmk_snprintf(char *bf, unsigned long size, const char *fmt, ...)
-{
-       int retval;
-       va_list ap;
-
-       va_start(ap, fmt);
-       retval = bmk_vsnprintf(bf, size, fmt, ap);
-       va_end(ap);
-
-       return retval;
-}
-
-/*
- * bmk_vsnprintf: print a message to a buffer [already have va_list]
- */
-int
-bmk_vsnprintf(char *bf, unsigned long size, const char *fmt, va_list ap)
-{
-       int retval;
-       char *p;
-
-       p = bf + size;
-       retval = kprintf(fmt, TOBUFONLY, &p, bf, ap);
-       if (bf && size > 0) {
-               /* nul terminate */
-               if (size <= (unsigned long)retval)
-                       bf[size - 1] = '\0';
-               else
-                       bf[retval] = '\0';
-       }
-       return retval;
-}
-
-/*
- * kprintf: scaled down version of printf(3).
- *
- * this version based on vfprintf() from libc which was derived from
- * software contributed to Berkeley by Chris Torek.
- *
- * NOTE: The kprintf mutex must be held if we're going TOBUF or TOCONS!
- */
-
-/*
- * macros for converting digits to letters and vice versa
- */
-#define        to_digit(c)     ((c) - '0')
-#define is_digit(c)    ((unsigned)to_digit(c) <= 9)
-#define        to_char(n)      ((n) + '0')
-
-/*
- * flags used during conversion.
- */
-#define        ALT             0x001           /* alternate form */
-#define        HEXPREFIX       0x002           /* add 0x or 0X prefix */
-#define        LADJUST         0x004           /* left adjustment */
-#define        LONGDBL         0x008           /* long double; unimplemented */
-#define        LONGINT         0x010           /* long integer */
-#define        QUADINT         0x020           /* quad integer */
-#define        SHORTINT        0x040           /* short integer */
-#define        MAXINT          0x080           /* intmax_t */
-#define        PTRINT          0x100           /* intptr_t */
-#define        SIZEINT         0x200           /* size_t */
-#define        ZEROPAD         0x400           /* zero (as opposed to blank) pad */
-#define FPT            0x800           /* Floating point number */
-
-       /*
-        * To extend shorts properly, we need both signed and unsigned
-        * argument extraction methods.
-        */
-#define        SARG() \
-       (flags&MAXINT ? va_arg(ap, long long) : \
-           flags&PTRINT ? va_arg(ap, long) : \
-           flags&SIZEINT ? va_arg(ap, long) : /* XXX */ \
-           flags&QUADINT ? va_arg(ap, long long) : \
-           flags&LONGINT ? va_arg(ap, long) : \
-           flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
-           (long)va_arg(ap, int))
-#define        UARG() \
-       (flags&MAXINT ? va_arg(ap, unsigned long long) : \
-           flags&PTRINT ? va_arg(ap, unsigned long) : \
-           flags&SIZEINT ? va_arg(ap, unsigned long) : \
-           flags&QUADINT ? va_arg(ap, unsigned long long) : \
-           flags&LONGINT ? va_arg(ap, unsigned long) : \
-           flags&SHORTINT ? (unsigned long)(unsigned long)va_arg(ap, int) : \
-           (unsigned long)va_arg(ap, unsigned int))
-
-#define KPRINTF_PUTCHAR(C) {                                           \
-       if (oflags == TOBUFONLY) {                                      \
-               if (sbuf && ((vp == NULL) || (sbuf < tailp)))           \
-                       *sbuf++ = (C);                                  \
-       } else {                                                        \
-               cons_putchar((C), oflags);                              \
-       }                                                               \
-}
-
-/*
- * Guts of kernel printf.  Note, we already expect to be in a mutex!
- */
-static int
-kprintf(const char *fmt0, int oflags, void *vp, char *sbuf, va_list ap)
-{
-       int ret = 0;            /* return value accumulator */
-       const char *fmt;        /* format string */
-       int ch;                 /* character from fmt */
-       int n;                  /* handy integer (short term usage) */
-       char *cp;               /* handy char pointer (short term usage) */
-       int flags;              /* flags as above */
-       int width;              /* width from format (%8d), or 0 */
-       int prec;               /* precision from format (%.3d), or -1 */
-       char sign;              /* sign prefix (' ', '+', '-', or \0) */
-
-       unsigned long long _uquad; /* integer arguments %[diouxX] */
-       enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
-       int dprec;              /* a copy of prec if [diouxX], 0 otherwise */
-       int realsz;             /* field size expanded by dprec */
-       int size;               /* size of converted field or string */
-       const char *xdigs;      /* digits for [xX] conversion */
-       char bf[KPRINTF_BUFSIZE]; /* space for %c, %[diouxX] */
-       char *tailp;            /* tail pointer for snprintf */
-
-       if (oflags == TOBUFONLY && (vp != NULL))
-               tailp = *(char **)vp;
-       else
-               tailp = NULL;
-
-       cp = NULL;      /* XXX: shutup gcc */
-       size = 0;       /* XXX: shutup gcc */
-
-       fmt = fmt0;
-       ret = 0;
-
-       xdigs = NULL;           /* XXX: shut up gcc warning */
-
-       /*
-        * Scan the format for conversions (`%' character).
-        */
-       for (;;) {
-               for (; *fmt != '%' && *fmt; fmt++) {
-                       ret++;
-                       KPRINTF_PUTCHAR(*fmt);
-               }
-               if (*fmt == 0)
-                       goto done;
-
-               fmt++;          /* skip over '%' */
-
-               flags = 0;
-               dprec = 0;
-               width = 0;
-               prec = -1;
-               sign = '\0';
-
-rflag:         ch = *fmt++;
-reswitch:      switch (ch) {
-               case ' ':
-                       /*
-                        * ``If the space and + flags both appear, the space
-                        * flag will be ignored.''
-                        *      -- ANSI X3J11
-                        */
-                       if (!sign)
-                               sign = ' ';
-                       goto rflag;
-               case '#':
-                       flags |= ALT;
-                       goto rflag;
-               case '*':
-                       /*
-                        * ``A negative field width argument is taken as a
-                        * - flag followed by a positive field width.''
-                        *      -- ANSI X3J11
-                        * They don't exclude field widths read from args.
-                        */
-                       if ((width = va_arg(ap, int)) >= 0)
-                               goto rflag;
-                       width = -width;
-                       /* FALLTHROUGH */
-               case '-':
-                       flags |= LADJUST;
-                       goto rflag;
-               case '+':
-                       sign = '+';
-                       goto rflag;
-               case '.':
-                       if ((ch = *fmt++) == '*') {
-                               n = va_arg(ap, int);
-                               prec = n < 0 ? -1 : n;
-                               goto rflag;
-                       }
-                       n = 0;
-                       while (is_digit(ch)) {
-                               n = 10 * n + to_digit(ch);
-                               ch = *fmt++;
-                       }
-                       prec = n < 0 ? -1 : n;
-                       goto reswitch;
-               case '0':
-                       /*
-                        * ``Note that 0 is taken as a flag, not as the
-                        * beginning of a field width.''
-                        *      -- ANSI X3J11
-                        */
-                       flags |= ZEROPAD;
-                       goto rflag;
-               case '1': case '2': case '3': case '4':
-               case '5': case '6': case '7': case '8': case '9':
-                       n = 0;
-                       do {
-                               n = 10 * n + to_digit(ch);
-                               ch = *fmt++;
-                       } while (is_digit(ch));
-                       width = n;
-                       goto reswitch;
-               case 'h':
-                       flags |= SHORTINT;
-                       goto rflag;
-               case 'j':
-                       flags |= MAXINT;
-                       goto rflag;
-               case 'l':
-                       if (*fmt == 'l') {
-                               fmt++;
-                               flags |= QUADINT;
-                       } else {
-                               flags |= LONGINT;
-                       }
-                       goto rflag;
-               case 'q':
-                       flags |= QUADINT;
-                       goto rflag;
-               case 't':
-                       flags |= PTRINT;
-                       goto rflag;
-               case 'z':
-                       flags |= SIZEINT;
-                       goto rflag;
-               case 'c':
-                       *(cp = bf) = va_arg(ap, int);
-                       size = 1;
-                       sign = '\0';
-                       break;
-               case 'D':
-                       flags |= LONGINT;
-                       /*FALLTHROUGH*/
-               case 'd':
-               case 'i':
-                       _uquad = SARG();
-                       if ((long long)_uquad < 0) {
-                               _uquad = -_uquad;
-                               sign = '-';
-                       }
-                       base = DEC;
-                       goto number;
-               case 'n':
-                       if (flags & MAXINT)
-                               *va_arg(ap, long long *) = ret;
-                       else if (flags & PTRINT)
-                               *va_arg(ap, long *) = ret;
-                       else if (flags & SIZEINT)
-                               *va_arg(ap, long *) = ret;
-                       else if (flags & QUADINT)
-                               *va_arg(ap, long long *) = ret;
-                       else if (flags & LONGINT)
-                               *va_arg(ap, long *) = ret;
-                       else if (flags & SHORTINT)
-                               *va_arg(ap, short *) = ret;
-                       else
-                               *va_arg(ap, int *) = ret;
-                       continue;       /* no output */
-               case 'O':
-                       flags |= LONGINT;
-                       /*FALLTHROUGH*/
-               case 'o':
-                       _uquad = UARG();
-                       base = OCT;
-                       goto nosign;
-               case 'p':
-                       /*
-                        * ``The argument shall be a pointer to void.  The
-                        * value of the pointer is converted to a sequence
-                        * of printable characters, in an implementation-
-                        * defined manner.''
-                        *      -- ANSI X3J11
-                        */
-                       /* NOSTRICT */
-                       _uquad = (unsigned long)va_arg(ap, void *);
-                       base = HEX;
-                       xdigs = hexdigits;
-                       flags |= HEXPREFIX;
-                       ch = 'x';
-                       goto nosign;
-               case 's':
-                       if ((cp = va_arg(ap, char *)) == NULL)
-                               /*XXXUNCONST*/
-                               cp = __UNCONST("(null)");
-                       if (prec >= 0) {
-                               /*
-                                * can't use strlen; can only look for the
-                                * NUL in the first `prec' characters, and
-                                * strlen() will go further.
-                                */
-                               char *p = bmk_memchr(cp, 0, prec);
-
-                               if (p != NULL) {
-                                       size = p - cp;
-                                       if (size > prec)
-                                               size = prec;
-                               } else
-                                       size = prec;
-                       } else
-                               size = bmk_strlen(cp);
-                       sign = '\0';
-                       break;
-               case 'U':
-                       flags |= LONGINT;
-                       /*FALLTHROUGH*/
-               case 'u':
-                       _uquad = UARG();
-                       base = DEC;
-                       goto nosign;
-               case 'X':
-                       xdigs = HEXDIGITS;
-                       goto hex;
-               case 'x':
-                       xdigs = hexdigits;
-hex:                   _uquad = UARG();
-                       base = HEX;
-                       /* leading 0x/X only if non-zero */
-                       if (flags & ALT && _uquad != 0)
-                               flags |= HEXPREFIX;
-
-                       /* unsigned conversions */
-nosign:                        sign = '\0';
-                       /*
-                        * ``... diouXx conversions ... if a precision is
-                        * specified, the 0 flag will be ignored.''
-                        *      -- ANSI X3J11
-                        */
-number:                        if ((dprec = prec) >= 0)
-                               flags &= ~ZEROPAD;
-
-                       /*
-                        * ``The result of converting a zero value with an
-                        * explicit precision of zero is no characters.''
-                        *      -- ANSI X3J11
-                        */
-                       cp = bf + KPRINTF_BUFSIZE;
-                       if (_uquad != 0 || prec != 0) {
-                               /*
-                                * Unsigned mod is hard, and unsigned mod
-                                * by a constant is easier than that by
-                                * a variable; hence this switch.
-                                */
-                               switch (base) {
-                               case OCT:
-                                       do {
-                                               *--cp = to_char(_uquad & 7);
-                                               _uquad >>= 3;
-                                       } while (_uquad);
-                                       /* handle octal leading 0 */
-                                       if (flags & ALT && *cp != '0')
-                                               *--cp = '0';
-                                       break;
-
-                               case DEC:
-                                       /* many numbers are 1 digit */
-                                       while (_uquad >= 10) {
-                                               *--cp = to_char(_uquad % 10);
-                                               _uquad /= 10;
-                                       }
-                                       *--cp = to_char(_uquad);
-                                       break;
-
-                               case HEX:
-                                       do {
-                                               *--cp = xdigs[_uquad & 15];
-                                               _uquad >>= 4;
-                                       } while (_uquad);
-                                       break;
-
-                               default:
-                                       /*XXXUNCONST*/
-                                       cp = __UNCONST("bug in kprintf: bad base");
-                                       size = bmk_strlen(cp);
-                                       goto skipsize;
-                               }
-                       }
-                       size = bf + KPRINTF_BUFSIZE - cp;
-               skipsize:
-                       break;
-               default:        /* "%?" prints ?, unless ? is NUL */
-                       if (ch == '\0')
-                               goto done;
-                       /* pretend it was %c with argument ch */
-                       cp = bf;
-                       *cp = ch;
-                       size = 1;
-                       sign = '\0';
-                       break;
-               }
-
-               /*
-                * All reasonable formats wind up here.  At this point, `cp'
-                * points to a string which (if not flags&LADJUST) should be
-                * padded out to `width' places.  If flags&ZEROPAD, it should
-                * first be prefixed by any sign or other prefix; otherwise,
-                * it should be blank padded before the prefix is emitted.
-                * After any left-hand padding and prefixing, emit zeroes
-                * required by a decimal [diouxX] precision, then print the
-                * string proper, then emit zeroes required by any leftover
-                * floating precision; finally, if LADJUST, pad with blanks.
-                *
-                * Compute actual size, so we know how much to pad.
-                * size excludes decimal prec; realsz includes it.
-                */
-               realsz = dprec > size ? dprec : size;
-               if (sign)
-                       realsz++;
-               else if (flags & HEXPREFIX)
-                       realsz+= 2;
-
-               /* adjust ret */
-               ret += width > realsz ? width : realsz;
-
-               /* right-adjusting blank padding */
-               if ((flags & (LADJUST|ZEROPAD)) == 0) {
-                       n = width - realsz;
-                       while (n-- > 0)
-                               KPRINTF_PUTCHAR(' ');
-               }
-
-               /* prefix */
-               if (sign) {
-                       KPRINTF_PUTCHAR(sign);
-               } else if (flags & HEXPREFIX) {
-                       KPRINTF_PUTCHAR('0');
-                       KPRINTF_PUTCHAR(ch);
-               }
-
-               /* right-adjusting zero padding */
-               if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) {
-                       n = width - realsz;
-                       while (n-- > 0)
-                               KPRINTF_PUTCHAR('0');
-               }
-
-               /* leading zeroes from decimal precision */
-               n = dprec - size;
-               while (n-- > 0)
-                       KPRINTF_PUTCHAR('0');
-
-               /* the string or number proper */
-               for (; size--; cp++)
-                       KPRINTF_PUTCHAR(*cp);
-               /* left-adjusting padding (always blank) */
-               if (flags & LADJUST) {
-                       n = width - realsz;
-                       while (n-- > 0)
-                               KPRINTF_PUTCHAR(' ');
-               }
-       }
-
-done:
-       if ((oflags == TOBUFONLY) && (vp != NULL))
-               *(char **)vp = sbuf;
-       (*v_flush)();
-
-       return ret;
-}
index 639ffa3f79d7b0c7e1c4f93a4f5516b60bc37bf9..0d895be55912dd51c86504e60c57c9d602dd288f 100644 (file)
@@ -73,12 +73,12 @@ RUMPKERN_LIB=       ${LIBS_VIO_NET}                                 \
                ${LIBS_SYSPROXY}                                \
                -lrumpdev -lrumpvfs -lrump
 
-COREDIR:=      $(shell pwd)/../../lib/librumprun_core
+COREDIR:=      $(shell pwd)/../../lib/libbmk_core
 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 -lrumprun_core
+LIBS_USER=     -L${BASEDIR}/baremetal -L${COREDIR}/baremetal -L${RUMPUSERDIR}/baremetal -lrumprun_rumpuser --start-group -lrumprun_base -lpthread -lc --end-group -lbmk_core
 RUMP_LDLIBS=   --whole-archive ${RUMPKERN_LIB} --no-whole-archive ${LIBS_USER}
 
 OBJS= ${OBJS_BMK} ${OBJS_APP}
@@ -102,7 +102,7 @@ ${BASEDIR}/baremetal/librumprun_base.a:
            && ${RUMPMAKE} MAKEOBJDIR=baremetal obj \
            && ${RUMPMAKE} MAKEOBJDIR=baremetal dependall )
 
-${COREDIR}/baremetal/librumprun_core.a:
+${COREDIR}/baremetal/libbmk_core.a:
        ( cd ${COREDIR} \
            && ${RUMPMAKE} MAKEOBJDIR=baremetal obj \
            && ${RUMPMAKE} MAKEOBJDIR=baremetal dependall )
@@ -112,7 +112,7 @@ ${RUMPUSERDIR}/baremetal/librumprun_rumpuser.a:
            && ${RUMPMAKE} MAKEOBJDIR=baremetal obj \
            && ${RUMPMAKE} MAKEOBJDIR=baremetal dependall )
 
-rumprun.o: ${OBJS} ${BASEDIR}/baremetal/librumprun_base.a ${COREDIR}/baremetal/librumprun_core.a ${RUMPUSERDIR}/baremetal/librumprun_rumpuser.a
+rumprun.o: ${OBJS} ${BASEDIR}/baremetal/librumprun_base.a ${COREDIR}/baremetal/libbmk_core.a ${RUMPUSERDIR}/baremetal/librumprun_rumpuser.a
        ${CC} -nostdlib ${CFLAGS} -Wl,-r ${OBJS_BMK} -o $@
 
 tests: rumprun.o app-tools
index 8284f1db3c88477a6db1cc7756198eec2d0ad056..ec2cc51f9bbfe94c89a9cc36f65afd0cf18eb721 100644 (file)
@@ -32,7 +32,7 @@ ifeq ($(TARGET_ARCH),x86_64)
 CFLAGS += -mno-red-zone -fno-reorder-blocks -fno-asynchronous-unwind-tables
 endif
 
-COREDIR:=       $(shell pwd)/../../lib/librumprun_core
+COREDIR:=       $(shell pwd)/../../lib/libbmk_core
 BASEDIR:=       $(shell pwd)/../../lib/librumprun_base
 RUMPUSERDIR:=  $(shell pwd)/../../lib/librumprun_rumpuser
 
@@ -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 -lrumprun_core
+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
 
 LDFLAGS := -L$(abspath rump/lib)
 
@@ -81,7 +81,7 @@ ${BASEDIR}/xen/librumprun_base.a:
            && ${RUMPMAKE} MAKEOBJDIR=xen obj \
            && ${RUMPMAKE} MAKEOBJDIR=xen dependall )
 
-${COREDIR}/xen/librumprun_core.a:
+${COREDIR}/xen/libbmk_core.a:
        ( cd ${COREDIR} \
            && ${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/librumprun_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/librumprun_rumpuser.a
        $(CC) -Wl,-r $(CFLAGS) $(LDFLAGS) $(RUMP_OBJS) -nostdlib -o $@
 
 APP_TOOLS_TARGETARCH= $(TARGET_ARCH)