diff --git a/idl/comrogue/allocator.idl b/idl/comrogue/allocator.idl index 4dcb637..d136734 100644 --- a/idl/comrogue/allocator.idl +++ b/idl/comrogue/allocator.idl @@ -1,3 +1,34 @@ +/* + * This file is part of the COMROGUE Operating System for Raspberry Pi + * + * Copyright (c) 2013, Eric J. Bowersox / Erbosoft Enterprises + * All rights reserved. + * + * This program is free for commercial and non-commercial use as long as the following conditions are + * adhered to. + * + * Copyright in this file remains Eric J. Bowersox and/or Erbosoft, and as such any copyright notices + * in the code are not to be removed. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list of conditions and + * the following disclaimer. + * * 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + * + * "Raspberry Pi" is a trademark of the Raspberry Pi Foundation. + */ import "comrogue/objectbase.idl"; /*------------------- @@ -40,3 +71,18 @@ interface IMallocSpy: IUnknown void PreHeapMinimize(void); void PostHeapMinimize(void); } + +/*--------------------------- + * IChunkAllocator interface + *--------------------------- + */ + +[object, uuid(76f6c6cf-2f4e-4d42-b620-99aa6872d477)] +interface IChunkAllocator: IUnknown +{ + [unique] typedef IChunkAllocator *PCHUNKALLOCATOR; + + HRESULT AllocChunk([in] UINT32 cbChunk, [in] UINT32 uiAlignment, [out] PVOID *ppvChunk); + HRESULT FreeChunk([in] PVOID pvChunk, [in] UINT32 cbChunk); + HRESULT PurgeUnusedRegion([in] PVOID pvRegion, [in] UINT32 cbRegion); +} diff --git a/idl/comrogue/object_types.idl b/idl/comrogue/object_types.idl index 786ac15..695b54d 100644 --- a/idl/comrogue/object_types.idl +++ b/idl/comrogue/object_types.idl @@ -74,6 +74,7 @@ interface ICOMROGUETypes typedef CHAR *PCHAR; typedef const CHAR *PCCHAR; typedef UCHAR *PUCHAR; + typedef BYTE *PBYTE; typedef WCHAR *PWCHAR; [string] typedef CHAR *PSTR; [string] typedef const CHAR *PCSTR; diff --git a/include/comrogue/heap.h b/include/comrogue/heap.h new file mode 100644 index 0000000..18220c9 --- /dev/null +++ b/include/comrogue/heap.h @@ -0,0 +1,68 @@ +/* + * This file is part of the COMROGUE Operating System for Raspberry Pi + * + * Copyright (c) 2013, Eric J. Bowersox / Erbosoft Enterprises + * All rights reserved. + * + * This program is free for commercial and non-commercial use as long as the following conditions are + * adhered to. + * + * Copyright in this file remains Eric J. Bowersox and/or Erbosoft, and as such any copyright notices + * in the code are not to be removed. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list of conditions and + * the following disclaimer. + * * 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + * + * "Raspberry Pi" is a trademark of the Raspberry Pi Foundation. + */ +#ifndef __HEAP_H_INCLUDED +#define __HEAP_H_INCLUDED + +#ifndef __ASM__ + +#include +#include +#include +#include + +/*------------------------------------------------------------------------------------ + * The raw heap data used to hold the heap internals. It's defined as opaque memory. + *------------------------------------------------------------------------------------ + */ + +typedef struct tagRAWHEAPDATA +{ + UINT32 opaque[8]; +} RAWHEAPDATA, *PRAWHEAPDATA; + +typedef void (*PFNRAWHEAPDATAFREE)(PRAWHEAPDATA prhd); + +/*-------------------- + * External functions + *-------------------- + */ + +CDECL_BEGIN + +extern HRESULT HeapCreate(PRAWHEAPDATA prhd, PFNRAWHEAPDATAFREE pfnFree, IChunkAllocator *pChunkAllocator, + IMalloc **ppHeap); + +CDECL_END + +#endif /* __ASM__ */ + +#endif /* __HEAP_H_INCLUDED */ diff --git a/include/comrogue/scode.h b/include/comrogue/scode.h index 94ccbc6..8d6aab8 100644 --- a/include/comrogue/scode.h +++ b/include/comrogue/scode.h @@ -93,6 +93,9 @@ #define STG_S_CONSOLIDATIONFAILED SCODE_CAST(0x00030205) /* consolidation failed but commit OK */ #define STG_S_CANNOTCONSOLIDATE SCODE_CAST(0x00030206) /* cannot consolidate but commit OK */ +/* Memory manager success codes */ +#define MEMMGR_S_NONZEROED SCODE_CAST(0x06010001) /* returned memory is non-zeroed */ + /* Basic error codes */ #define E_NOTIMPL SCODE_CAST(0x80000001) /* not implemented */ #define E_OUTOFMEMORY SCODE_CAST(0x80000002) /* out of memory */ @@ -164,5 +167,6 @@ #define MEMMGR_E_NOKERNSPC SCODE_CAST(0x86010006) /* no kernel space */ #define MEMMGR_E_RECURSED SCODE_CAST(0x86010007) /* tried to recurse into page allocation */ #define MEMMGR_E_BADTAGS SCODE_CAST(0x86010008) /* invalid tags for freed page */ +#define MEMMGR_E_BADHEAPDATASIZE SCODE_CAST(0x86010009) /* bad size of raw heap data block */ #endif /* __SCODE_H_INCLUDED */ diff --git a/kernel/lib/LICENSE.jemalloc b/kernel/lib/LICENSE.jemalloc new file mode 100644 index 0000000..134930c --- /dev/null +++ b/kernel/lib/LICENSE.jemalloc @@ -0,0 +1,26 @@ +Some of the code in this directory, particularly the heap_*.c files, is code based on/inspired by the jemalloc-3.3.1 +package, available at . The following are the license terms of jemalloc: +----------------------------------------------- +Copyright (C) 2002-2013 Jason Evans . +All rights reserved. +Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved. +Copyright (C) 2009-2013 Facebook, Inc. 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(s), + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice(s), + 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. diff --git a/kernel/lib/Makefile b/kernel/lib/Makefile index 4ccef91..4b05c44 100644 --- a/kernel/lib/Makefile +++ b/kernel/lib/Makefile @@ -32,7 +32,8 @@ MAKEFLAGS += -rR CRBASEDIR := $(abspath ../..) include $(CRBASEDIR)/armcompile.mk -LIB_OBJS = divide.o qdivrem.o intlib.o objhelp.o rbtree.o str.o strcopymem.o strcomparemem.o strsetmem.o lib_guids.o +LIB_OBJS = divide.o qdivrem.o heap_toplevel.o intlib.o objhelp.o rbtree.o str.o \ + strcopymem.o strcomparemem.o strsetmem.o lib_guids.o all: kernel-lib.o diff --git a/kernel/lib/heap_internals.h b/kernel/lib/heap_internals.h new file mode 100644 index 0000000..88f5261 --- /dev/null +++ b/kernel/lib/heap_internals.h @@ -0,0 +1,56 @@ +/* + * This file is part of the COMROGUE Operating System for Raspberry Pi + * + * Copyright (c) 2013, Eric J. Bowersox / Erbosoft Enterprises + * All rights reserved. + * + * This program is free for commercial and non-commercial use as long as the following conditions are + * adhered to. + * + * Copyright in this file remains Eric J. Bowersox and/or Erbosoft, and as such any copyright notices + * in the code are not to be removed. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list of conditions and + * the following disclaimer. + * * 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + * + * "Raspberry Pi" is a trademark of the Raspberry Pi Foundation. + */ +/* + * This code is based on/inspired by jemalloc-3.3.1. Please see LICENSE.jemalloc for further details. + */ +#ifndef __HEAP_INTERNALS_H_INCLUDED +#define __HEAP_INTERNALS_H_INCLUDED + +#include +#include +#include +#include + +/*---------------------------------- + * The actual heap data declaration + *---------------------------------- + */ + +typedef struct tagHEAPDATA { + IMalloc mallocInterface; /* pointer to IMalloc interface - MUST BE FIRST! */ + IConnectionPointContainer cpContainerInterface; /* pointer to IConnectionPointContainer interface */ + UINT32 uiRefCount; /* reference count */ + PFNRAWHEAPDATAFREE pfnFreeRawHeapData; /* pointer to function that frees the raw heap data, if any */ + IChunkAllocator *pChunkAllocator; /* chunk allocator pointer */ +} HEAPDATA, *PHEAPDATA; + +#endif /* __HEAP_INTERNALS_H_INCLUDED */ diff --git a/kernel/lib/heap_toplevel.c b/kernel/lib/heap_toplevel.c new file mode 100644 index 0000000..3a05854 --- /dev/null +++ b/kernel/lib/heap_toplevel.c @@ -0,0 +1,145 @@ +/* + * This file is part of the COMROGUE Operating System for Raspberry Pi + * + * Copyright (c) 2013, Eric J. Bowersox / Erbosoft Enterprises + * All rights reserved. + * + * This program is free for commercial and non-commercial use as long as the following conditions are + * adhered to. + * + * Copyright in this file remains Eric J. Bowersox and/or Erbosoft, and as such any copyright notices + * in the code are not to be removed. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list of conditions and + * the following disclaimer. + * * 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + * + * "Raspberry Pi" is a trademark of the Raspberry Pi Foundation. + */ +/* + * This code is based on/inspired by jemalloc-3.3.1. Please see LICENSE.jemalloc for further details. + */ +#include +#include +#include +#include +#include +#include "heap_internals.h" + +/*------------------------ + * IMalloc implementation + *------------------------ + */ + +static UINT32 IMalloc_AddRef(IUnknown *pThis) +{ + return ++(((PHEAPDATA)pThis)->uiRefCount); +} + +static UINT32 IMalloc_Release(IUnknown *pThis) +{ + PHEAPDATA phd = (PHEAPDATA)pThis; /* pointer to heap data */ + UINT32 rc; /* return from this function */ + PFNRAWHEAPDATAFREE pfnFree; /* pointer to "free" function */ + + rc = --(phd->uiRefCount); + if (rc == 0) + { + IUnknown_Release(phd->pChunkAllocator); + if (phd->pfnFreeRawHeapData) + { + pfnFree = phd->pfnFreeRawHeapData; + (*pfnFree)((PRAWHEAPDATA)phd); + } + } + return rc; +} + +/* The IMalloc vtable. */ +static const SEG_RODATA struct IMallocVTable vtblMalloc = +{ + .AddRef = IMalloc_AddRef, + .Release = IMalloc_Release +}; + +/*------------------------------------------ + * IConnectionPointContainer implementation + *------------------------------------------ + */ + +/* Quick macro to get the PHEAPDATA from the IConnectionPointContainer pointer */ +#define HeapDataPtr(pcpc) (((PBYTE)(pcpc)) - OFFSETOF(HEAPDATA, cpContainerInterface)) + +static UINT32 IConnectionPointContainer_AddRef(IUnknown *pThis) +{ + return IMalloc_AddRef((IUnknown *)HeapDataPtr(pThis)); +} + +static UINT32 IConnectionPointContainer_Release(IUnknown *pThis) +{ + return IMalloc_Release((IUnknown *)HeapDataPtr(pThis)); +} + +/* The IConnectionPointContainer vtable. */ +static const SEG_RODATA struct IConnectionPointContainerVTable vtblConnectionPointContainer = +{ + .AddRef = IConnectionPointContainer_AddRef, + .Release = IConnectionPointContainer_Release +}; + +/*------------------------ + * Heap creation function + *------------------------ + */ + +/* + * Creates a heap implementation and returns a pointer to its IMalloc interface. + * + * Parameters: + * - prhd = Pointer to a RAWHEAPDATA structure, which contains sufficient memory to hold the global data + * for the heap. + * - pfnFree = Pointer to a function called as the last stage of releasing the heap, which frees the + * "prhd" block. May be NULL. + * - pChunkAllocator = Pointer to the IChunkAllocator interface used by the heap to allocate chunks of memory + * for carving up by the heap. + * - ppHeap = Pointer location that will receive a pointer to the heap's IMalloc interface. + * + * Returns: + * Standard HRESULT success/failure. + */ +HRESULT HeapCreate(PRAWHEAPDATA prhd, PFNRAWHEAPDATAFREE pfnFree, IChunkAllocator *pChunkAllocator, + IMalloc **ppHeap) +{ + PHEAPDATA phd; /* pointer to actual heap data */ + + if (sizeof(RAWHEAPDATA) < sizeof(HEAPDATA)) + return MEMMGR_E_BADHEAPDATASIZE; /* bogus size of raw heap data */ + if (!prhd || !pChunkAllocator || !ppHeap) + return E_POINTER; /* invalid pointers */ + + /* initialize heap data */ + phd = (PHEAPDATA)prhd; + StrSetMem(phd, 0, sizeof(HEAPDATA)); + phd->mallocInterface.pVTable = &vtblMalloc; + phd->cpContainerInterface.pVTable = &vtblConnectionPointContainer; + phd->uiRefCount = 1; + phd->pfnFreeRawHeapData = pfnFree; + phd->pChunkAllocator = pChunkAllocator; + IUnknown_AddRef(phd->pChunkAllocator); + + *ppHeap = (IMalloc *)phd; + return S_OK; +}