aboutsummaryrefslogtreecommitdiff
path: root/lib/WinRpMalloc/src/dllmain.c
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2023-03-27 02:20:06 -0400
committerLibravatar vnugent <public@vaughnnugent.com>2023-03-27 02:20:06 -0400
commit6f7f4a4f03c7e62db64c01b2a0b128586bf11dad (patch)
tree2ef00d7d8527f5153ccd4188665bd9b47573cf27 /lib/WinRpMalloc/src/dllmain.c
parent6b5ca9e49e33eb3e03d6f7333661da7e6d0546fa (diff)
Native heap api and alloc optimizations
Diffstat (limited to 'lib/WinRpMalloc/src/dllmain.c')
-rw-r--r--lib/WinRpMalloc/src/dllmain.c164
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