[rtems-libbsd commit] Add a simple page allocator

Sebastian Huber sebh at rtems.org
Thu Jan 29 08:32:05 UTC 2015


Module:    rtems-libbsd
Branch:    master
Commit:    3c302b62fda9e429b8796b1f244fd70568bb3fb5
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=3c302b62fda9e429b8796b1f244fd70568bb3fb5

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Jan 27 08:26:53 2015 +0100

Add a simple page allocator

---

 Makefile                                  |   1 +
 freebsd-to-rtems.py                       |   1 +
 rtemsbsd/include/machine/rtems-bsd-page.h |  92 ++++++++++++++++++
 rtemsbsd/rtems/rtems-bsd-page.c           | 149 ++++++++++++++++++++++++++++++
 4 files changed, 243 insertions(+)

diff --git a/Makefile b/Makefile
index a3a02a3..6c0625b 100644
--- a/Makefile
+++ b/Makefile
@@ -83,6 +83,7 @@ LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-mutex.c
 LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-muteximpl.c
 LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-newproc.c
 LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-nexus.c
+LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-page.c
 LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-panic.c
 LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-pci_bus.c
 LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-pci_cfgreg.c
diff --git a/freebsd-to-rtems.py b/freebsd-to-rtems.py
index ab33522..439c4b1 100755
--- a/freebsd-to-rtems.py
+++ b/freebsd-to-rtems.py
@@ -681,6 +681,7 @@ rtems.addRTEMSSourceFiles(
 		'rtems/rtems-bsd-muteximpl.c',
 		'rtems/rtems-bsd-newproc.c',
 		'rtems/rtems-bsd-nexus.c',
+		'rtems/rtems-bsd-page.c',
 		'rtems/rtems-bsd-panic.c',
 		'rtems/rtems-bsd-pci_bus.c',
 		'rtems/rtems-bsd-pci_cfgreg.c',
diff --git a/rtemsbsd/include/machine/rtems-bsd-page.h b/rtemsbsd/include/machine/rtems-bsd-page.h
new file mode 100644
index 0000000..b732c1a
--- /dev/null
+++ b/rtemsbsd/include/machine/rtems-bsd-page.h
@@ -0,0 +1,92 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_bsd_machine
+ *
+ * @brief TODO.
+ */
+
+/*
+ * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * 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 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 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.
+ */
+
+#ifndef _RTEMS_BSD_MACHINE_RTEMS_BSD_PAGE_H_
+#define _RTEMS_BSD_MACHINE_RTEMS_BSD_PAGE_H_
+
+/*
+ * A page is a fixed size memory area of size PAGE_SIZE with the ability to
+ * associate an object with it.  The memory pool for pages has a fixed size and
+ * is allocated during system initialization.  This API is intended to be used
+ * by ZONE(9).
+ */
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <stdint.h>
+
+__BEGIN_DECLS
+
+extern void **rtems_bsd_page_object_table;
+
+extern uintptr_t rtems_bsd_page_area_begin;
+
+void *rtems_bsd_page_alloc(uintptr_t size_in_bytes, int wait);
+
+void rtems_bsd_page_free(void *addr);
+
+static inline void **
+rtems_bsd_page_get_object_entry(void *addr)
+{
+	uintptr_t a = (uintptr_t)addr;
+	uintptr_t b = rtems_bsd_page_area_begin;
+	uintptr_t s = PAGE_SHIFT;
+
+	return (&rtems_bsd_page_object_table[(a - b) >> s]);
+}
+
+static inline void *
+rtems_bsd_page_get_object(void *addr)
+{
+	void **obj_entry = rtems_bsd_page_get_object_entry(addr);
+
+	return (*obj_entry);
+}
+
+static inline void
+rtems_bsd_page_set_object(void *addr, void *obj)
+{
+	void **obj_entry = rtems_bsd_page_get_object_entry(addr);
+
+	*obj_entry = obj;
+}
+
+__END_DECLS
+
+#endif /* _RTEMS_BSD_MACHINE_RTEMS_BSD_PAGE_H_ */
diff --git a/rtemsbsd/rtems/rtems-bsd-page.c b/rtemsbsd/rtems/rtems-bsd-page.c
new file mode 100644
index 0000000..929d466
--- /dev/null
+++ b/rtemsbsd/rtems/rtems-bsd-page.c
@@ -0,0 +1,149 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_bsd_rtems
+ *
+ * @brief TODO.
+ */
+
+/*
+ * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * 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 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 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 <machine/rtems-bsd-kernel-space.h>
+#include <machine/rtems-bsd-page.h>
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/types.h>
+#include <rtems/bsd/sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <vm/uma.h>
+
+#include <stdlib.h>
+
+#include <rtems/malloc.h>
+#include <rtems/rbheap.h>
+
+/* FIXME: This must be application configurable */
+#define PAGE_HEAP_SIZE (8 * 1024 * 1024)
+
+void **rtems_bsd_page_object_table;
+
+uintptr_t rtems_bsd_page_area_begin;
+
+static rtems_rbheap_control page_heap;
+
+struct mtx page_heap_mtx;
+
+void *
+rtems_bsd_page_alloc(uintptr_t size_in_bytes, int wait)
+{
+	void *addr;
+
+	mtx_lock(&page_heap_mtx);
+
+	addr = rtems_rbheap_allocate(&page_heap, size_in_bytes);
+	if (addr == NULL && wait) {
+		int i;
+
+		for (i = 0; i < 8; i++) {
+			mtx_unlock(&page_heap_mtx);
+			uma_reclaim();
+			mtx_lock(&page_heap_mtx);
+
+			addr = rtems_rbheap_allocate(&page_heap, size_in_bytes);
+			if (addr != NULL)
+				break;
+
+			msleep(&page_heap, &page_heap_mtx, 0,
+			    "page alloc", (hz / 4) * (i + 1));
+		}
+
+		if (i == 8) {
+			panic("rtems_bsd_page_alloc: page starvation");
+		}
+	}
+
+	mtx_unlock(&page_heap_mtx);
+
+	return (addr);
+}
+
+void
+rtems_bsd_page_free(void *addr)
+{
+	mtx_lock(&page_heap_mtx);
+	rtems_rbheap_free(&page_heap, addr);
+	wakeup(&page_heap);
+	mtx_unlock(&page_heap_mtx);
+}
+
+static void
+rtems_bsd_page_init(void *arg)
+{
+	rtems_status_code sc;
+	void *area;
+	void **obj_table;
+	rtems_rbheap_chunk *chunks;
+	size_t i;
+	size_t n;
+
+	mtx_init(&page_heap_mtx, "page heap", NULL, MTX_DEF);
+
+	area = rtems_heap_allocate_aligned_with_boundary(PAGE_HEAP_SIZE,
+	    PAGE_SIZE, 0);
+	BSD_ASSERT(area != NULL);
+
+	sc = rtems_rbheap_initialize(&page_heap, area, PAGE_HEAP_SIZE,
+	    PAGE_SIZE, rtems_rbheap_extend_descriptors_with_malloc, NULL);
+	BSD_ASSERT(sc == RTEMS_SUCCESSFUL);
+
+	rtems_rbheap_set_extend_descriptors(&page_heap,
+	    rtems_rbheap_extend_descriptors_never);
+
+	n = PAGE_HEAP_SIZE / PAGE_SIZE;
+
+	chunks = malloc(n * sizeof(*chunks), M_RTEMS_HEAP, M_NOWAIT);
+	BSD_ASSERT(chunks != NULL);
+
+	for (i = 0; i < n; ++i) {
+		rtems_rbheap_add_to_spare_descriptor_chain(&page_heap,
+		    &chunks[i]);
+	}
+
+	obj_table = calloc(n, sizeof(*obj_table));
+
+	rtems_bsd_page_area_begin = (uintptr_t)area;
+	rtems_bsd_page_object_table = obj_table;
+}
+
+SYSINIT(rtems_bsd_page, SI_SUB_VM, SI_ORDER_FIRST, rtems_bsd_page_init, NULL);




More information about the vc mailing list