diff options
author | vnugent <public@vaughnnugent.com> | 2023-03-27 02:20:06 -0400 |
---|---|---|
committer | vnugent <public@vaughnnugent.com> | 2023-03-27 02:20:06 -0400 |
commit | 6f7f4a4f03c7e62db64c01b2a0b128586bf11dad (patch) | |
tree | 2ef00d7d8527f5153ccd4188665bd9b47573cf27 /lib/WinRpMalloc/src/dllmain.c | |
parent | 6b5ca9e49e33eb3e03d6f7333661da7e6d0546fa (diff) |
Native heap api and alloc optimizations
Diffstat (limited to 'lib/WinRpMalloc/src/dllmain.c')
-rw-r--r-- | lib/WinRpMalloc/src/dllmain.c | 164 |
1 files changed, 163 insertions, 1 deletions
diff --git a/lib/WinRpMalloc/src/dllmain.c b/lib/WinRpMalloc/src/dllmain.c index 10ea3f5..1c1378e 100644 --- a/lib/WinRpMalloc/src/dllmain.c +++ b/lib/WinRpMalloc/src/dllmain.c @@ -1,6 +1,27 @@ -// dllmain.cpp : Defines the entry point for the DLL application. +/* +* Copyright (c) 2023 Vaughn Nugent +* +* Library: VNLib +* Package: WinRpMalloc +* File: dllmain.c +* +* WinRpMalloc is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published +* by the Free Software Foundation, either version 2 of the License, +* or (at your option) any later version. +* +* WinRpMalloc is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with WinRpMalloc. If not, see http://www.gnu.org/licenses/. +*/ #include "pch.h" +//Include the native heap header directly from its repo location +#include "../../NativeHeapApi/src/NativeHeapApi.h" BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { @@ -24,4 +45,145 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv break; } return TRUE; +} + +#define GLOBAL_HEAP_HANDLE_VALUE -10 +#define GLOBAL_HEAP_INIT_CHECK if (!rpmalloc_is_thread_initialized()) { rpmalloc_thread_initialize(); } + +//Define the heap methods + +HEAP_METHOD_EXPORT ERRNO heapCreate(UnmanagedHeapFlags* flags) +{ + //Check flags + if (flags->CreationFlags & HEAP_CREATION_IS_SHARED) + { + //User requested the global heap, synchronziation is not required, so we can clear the sync flag + flags->CreationFlags &= ~(HEAP_CREATION_SERIALZE_ENABLED); + + //Set the heap pointer as the global heap value + flags->HeapPointer = (LPVOID)GLOBAL_HEAP_HANDLE_VALUE; + + //Success + return TRUE; + } + + //Allocate a first class heap + flags->HeapPointer = rpmalloc_heap_acquire(); + + //Ignore remaining flags, zero/sync can be user optional + + //Return value greater than 0 + return flags->HeapPointer; +} + + +HEAP_METHOD_EXPORT ERRNO heapDestroy(LPVOID heap) +{ + //Destroy the heap + if ((int)heap == GLOBAL_HEAP_HANDLE_VALUE) + { + //Gloal heap, do nothing, and allow the entrypoint cleanup + return TRUE; + } + + //Free all before destroy + rpmalloc_heap_free_all(heap); + + //Destroy the heap + rpmalloc_heap_release(heap); + + return TRUE; +} + + +HEAP_METHOD_EXPORT LPVOID heapAlloc(LPVOID heap, size_t elements, size_t alignment, BOOL zero) +{ + //Multiply for element size + size_t size = elements * alignment; + + //Check for global heap + if ((int)heap == GLOBAL_HEAP_HANDLE_VALUE) + { + /* + * When called from the dotnet CLR the thread may not call the DLL + * thread attach method, so we need to check and initialze the heap + * for the current thread + */ + GLOBAL_HEAP_INIT_CHECK + + //Allocate the block + if (zero) + { + //Calloc + return rpcalloc(elements, alignment); + } + else + { + //Alloc without zero + return rpmalloc(size); + } + } + else + { + //First class heap, lock is held by caller, optionally zero the block + if (zero) + { + return rpmalloc_heap_calloc(heap, alignment, elements); + } + else + { + return rpmalloc_heap_alloc(heap, size); + } + } +} + + +HEAP_METHOD_EXPORT LPVOID heapRealloc(LPVOID heap, LPVOID block, size_t elements, size_t alignment, BOOL zero) +{ + //Multiply for element size + size_t size = elements * alignment; + + //Check for global heap + if ((int)heap == GLOBAL_HEAP_HANDLE_VALUE) + { + /* + * When called from the dotnet CLR the thread may not call the DLL + * thread attach method, so we need to check and initialze the heap + * for the current thread + */ + GLOBAL_HEAP_INIT_CHECK + + //Calloc + return rprealloc(block, size); + } + else + { + //First class heap, lock is held by caller + return rpmalloc_heap_realloc(heap, block, size, 0); + } +} + + +HEAP_METHOD_EXPORT ERRNO heapFree(LPVOID heap, LPVOID block) +{ + //Check for global heap + if ((int)heap == GLOBAL_HEAP_HANDLE_VALUE) + { + /* + * If free happens on a different thread, we must allocate the heap + * its cheap to check + */ + + GLOBAL_HEAP_INIT_CHECK + + //free block + rpfree(block); + } + else + { + //First class heap, lock is held by caller + rpmalloc_heap_free(heap, block); + } + + return TRUE; }
\ No newline at end of file |