#include "../bmem.h"
#include "../bmem.inl"
#include "../cassert.h"
#if !defined(__WINDOWS__)
#error This file is for Windows
#endif
#include "../nowarn.hxx"
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#if defined(__MEMORY_AUDITOR__)
#include <stdlib.h>
#if defined(_MSC_VER) && _MSC_VER > 1400
#if !defined(NAPPGUI_NO_CRTDBG)
#define _WITH_CRTDBG 1
#include <crtdbg.h>
#endif
#endif
#endif
#include "../nowarn.hxx"
#if defined(__MEMORY_SUBSYTEM_CHECKING__)
#define i_MAX 1000000
static void *i_MEM[i_MAX];
static uint32_t i_INDEX = 0;
static void i_mem_append(void *ptr)
{
uint32_t i;
for (i = 0; i < i_INDEX; ++i)
{
if (i_MEM[i] == NULL)
{
i_MEM[i] = ptr;
return;
}
}
i_MEM[i_INDEX] = ptr;
i_INDEX++;
cassert(i_INDEX < i_MAX);
}
static void i_mem_remove(void *ptr)
{
uint32_t i;
for (i = 0; i < i_INDEX; ++i)
{
if (i_MEM[i] == ptr)
{
i_MEM[i] = NULL;
return;
}
}
cassert(FALSE);
}
static bool_t i_mem_is_empty(void)
{
uint32_t i;
for (i = 0; i < i_INDEX; ++i)
{
if (i_MEM[i] != NULL)
return FALSE;
}
return TRUE;
}
#endif
static HANDLE i_HEAP = NULL;
void _bmem_start(void)
{
cassert_unref(i_HEAP == NULL, i_HEAP);
#if defined(__MEMORY_AUDITOR__)
#else
#endif
}
void _bmem_finish(void)
{
#if defined(__MEMORY_SUBSYTEM_CHECKING__)
cassert(i_mem_is_empty() == TRUE);
#endif
}
void _bmem_atexit(void)
{
#if defined(__MEMORY_AUDITOR__)
#if _WITH_CRTDBG
_CrtDumpMemoryLeaks();
#endif
#else
cassert(i_HEAP == NULL);
#endif
}
byte_t *bmem_aligned_malloc(const uint32_t size, const uint32_t align)
{
void *mem = NULL;
#if defined(__MEMORY_AUDITOR__)
#if _WITH_CRTDBG
mem = _aligned_malloc_dbg((size_t)size, (size_t)align, __FILE__, __LINE__);
#else
mem = _aligned_malloc((size_t)size, (size_t)align);
#endif
#else
mem = _aligned_malloc((size_t)size, (size_t)align);
#endif
#if defined(__MEMORY_SUBSYTEM_CHECKING__)
i_mem_append(mem);
#endif
cassert((mem != NULL) && ((intptr_t)mem % align) == 0);
return cast(mem, byte_t);
}
byte_t *bmem_aligned_realloc(byte_t *mem, const uint32_t size, const uint32_t new_size, const uint32_t align)
{
void *new_mem = NULL;
unref(size);
#if defined(__MEMORY_SUBSYTEM_CHECKING__)
i_mem_remove(mem);
#endif
#if defined(__MEMORY_AUDITOR__)
#if _WITH_CRTDBG
new_mem = _aligned_realloc_dbg(mem, (size_t)new_size, (size_t)align, __FILE__, __LINE__);
#else
new_mem = _aligned_realloc(mem, (size_t)new_size, (size_t)align);
#endif
#else
new_mem = _aligned_realloc(mem, (size_t)new_size, (size_t)align);
unref(size);
#endif
#if defined(__MEMORY_SUBSYTEM_CHECKING__)
i_mem_append(new_mem);
#endif
cassert((mem != NULL) && ((intptr_t)mem % align) == 0);
return cast(new_mem, byte_t);
}
void bmem_free(byte_t *mem)
{
#if defined(__MEMORY_SUBSYTEM_CHECKING__)
i_mem_remove(mem);
#endif
#if defined(__MEMORY_AUDITOR__)
#if _WITH_CRTDBG
_aligned_free_dbg(mem);
#else
_aligned_free(mem);
#endif
#else
_aligned_free(mem);
#endif
}
void bmem_set1(byte_t *dest, const uint32_t size, const byte_t mask)
{
cassert_no_null(dest);
cassert(size > 0);
memset(cast(dest, void), (int)mask, (size_t)size);
}
void bmem_set_zero(byte_t *mem, const uint32_t size)
{
cassert_no_null(mem);
cassert(size > 0);
ZeroMemory(cast(mem, void), (size_t)size);
}