/* * ntp_iocplmem.c - separate memory pool for IOCPL related objects * * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project. * The contents of 'html/copyright.html' apply. * * -------------------------------------------------------------------- * Notes on the implementation: * * Implements a thin layer over Windows Memory pools */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include "ntpd.h" #include "ntp_iocplmem.h" /* ------------------------------------------------------------------- * We make a pool of our own for IO context objects -- the are owned by * the system until a completion result is pulled from the queue, and * they seriously go into the way of memory tracking until we can safely * cancel an IO request. * ------------------------------------------------------------------- */ static HANDLE hHeapHandle; /* ------------------------------------------------------------------- * Create a new heap for IO context objects */ void IOCPLPoolInit( size_t initSize ) { hHeapHandle = HeapCreate(0, initSize, 0); if (hHeapHandle == NULL) { msyslog(LOG_ERR, "Can't initialize Heap: %m"); exit(1); } } /* ------------------------------------------------------------------- * Delete the IO context heap * * Since we do not know what callbacks are pending, we just drop the * pool into oblivion. New allocs and frees will fail from this moment, * but we simply don't care. At least the normal heap dump stats will * show no leaks from IO context blocks. On the downside, we have to * track them ourselves if something goes wrong. */ void IOCPLPoolDone(void) { hHeapHandle = NULL; } /* ------------------------------------------------------------------- * Alloc & Free on local heap * * When the heap handle is NULL, these both will fail; Alloc with a NULL * return and Free silently. */ void * __fastcall IOCPLPoolAlloc( size_t size, const char * desc ) { void * ptr = NULL; if (hHeapHandle != NULL) ptr = HeapAlloc(hHeapHandle, HEAP_ZERO_MEMORY, max(size, 1)); if (ptr == NULL) errno = ENOMEM; DPRINTF(6, ("IOCPLPoolAlloc: '%s', heap=%p, ptr=%p\n", desc, hHeapHandle, ptr)); return ptr; } /* ----------------------------------------------------------------- */ void __fastcall IOCPLPoolFree( void * ptr, const char * desc ) { DPRINTF(6, ("IOCPLPoolFree: '%s', heap=%p, ptr=%p\n", desc, hHeapHandle, ptr)); if (ptr != NULL && hHeapHandle != NULL) HeapFree(hHeapHandle, 0, ptr); } /* ------------------------------------------------------------------- * Allocate a memory buffer and copy the data from a source buffer * into the new allocated memory slice. */ void * __fastcall IOCPLPoolMemDup( const void * psrc, size_t size, const char * desc ) { void * ptr = NULL; if (hHeapHandle != NULL) { ptr = HeapAlloc(hHeapHandle, 0, max(size, 1)); if (ptr != NULL) memcpy(ptr, psrc, size); } if (ptr == NULL) errno = ENOMEM; DPRINTF(6, ("IOCPLPoolMemDup: '%s', heap=%p, ptr=%p\n", desc, hHeapHandle, ptr)); return ptr; } /* -*- that's all folks -*- */