mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-07-23 05:42:18 +08:00
Add a simple page allocator
This commit is contained in:
parent
8e009cddfe
commit
3c302b62fd
1
Makefile
1
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
|
||||
|
@ -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',
|
||||
|
92
rtemsbsd/include/machine/rtems-bsd-page.h
Normal file
92
rtemsbsd/include/machine/rtems-bsd-page.h
Normal file
@ -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@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_ */
|
149
rtemsbsd/rtems/rtems-bsd-page.c
Normal file
149
rtemsbsd/rtems/rtems-bsd-page.c
Normal file
@ -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@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);
|
Loading…
x
Reference in New Issue
Block a user