diff --git a/dev/VisualStudio/lwmem_dev.vcxproj b/dev/VisualStudio/lwmem_dev.vcxproj
index f0b63e3..694d66a 100644
--- a/dev/VisualStudio/lwmem_dev.vcxproj
+++ b/dev/VisualStudio/lwmem_dev.vcxproj
@@ -145,6 +145,7 @@
+
diff --git a/dev/VisualStudio/lwmem_dev.vcxproj.filters b/dev/VisualStudio/lwmem_dev.vcxproj.filters
index 49392e2..46dbc3b 100644
--- a/dev/VisualStudio/lwmem_dev.vcxproj.filters
+++ b/dev/VisualStudio/lwmem_dev.vcxproj.filters
@@ -8,6 +8,9 @@
{a9bad49b-d114-4596-8fe8-162c60f482ee}
+
+ {87f67bb1-45c3-4724-b7de-f1e8551453e3}
+
@@ -19,5 +22,8 @@
Source Files\LWMEM
+
+ Source Files\Tests
+
\ No newline at end of file
diff --git a/dev/VisualStudio/main.c b/dev/VisualStudio/main.c
index 1f28b00..ecfd59b 100644
--- a/dev/VisualStudio/main.c
+++ b/dev/VisualStudio/main.c
@@ -3,97 +3,12 @@
#include "string.h"
#include "stdint.h"
-#define ARRSIZE(x) (sizeof(x) / (sizeof((x)[0])))
-
-/* Define regions in increasing order */
-uint8_t mem1[1024];
-lwmem_region_t
-regions[] = {
- { mem1, sizeof(mem1) / 2 },
- { mem1 + sizeof(mem1) / 2, sizeof(mem1) / 2 },
-};
-
-#define ASSERT(x) do { \
- if (!(x)) { \
- printf("Assert failed with condition (" # x ")\r\n"); \
- } else {\
- printf("Assert passed with condition (" # x ")\r\n"); \
- }\
-} while (0)
-
-/* For debug purposes */
-lwmem_region_t* regions_used;
-size_t regions_count = 4; /* Use only 1 region for debug purposes of non-free areas */
+extern void lwmem_test_run(void);
+extern void lwmem_test_memory_structure(void);
int
main(void) {
- uint8_t* ptr1, *ptr2, *ptr3, *ptr4;
- uint8_t* rptr1, *rptr2, *rptr3, *rptr4;
-
- /* Create regions for debug purpose */
- if (!lwmem_debug_create_regions(®ions_used, regions_count, 128)) {
- printf("Cannot allocate memory for regions for debug purpose!\r\n");
- return -1;
- }
- lwmem_assignmem(regions_used, regions_count);
- printf("Manager is ready!\r\n");
- lwmem_debug_print(1, 1);
-
- /* Test case 1, allocate 3 blocks, each of different size */
- /* We know that sizeof internal metadata block is 8 bytes on win32 */
- printf("\r\n\r\nAllocating 4 pointers and freeing first and third..\r\n");
- ptr1 = lwmem_malloc(8);
- ptr2 = lwmem_malloc(4);
- ptr3 = lwmem_malloc(4);
- ptr4 = lwmem_malloc(16);
- lwmem_free(ptr1); /* Free but keep value for future comparison */
- lwmem_free(ptr3); /* Free but keep value for future comparison */
- lwmem_debug_print(1, 1);
- printf("Debug above is effectively state 3\r\n");
- lwmem_debug_save_state(); /* Every restore operations rewinds here */
-
- ptr1 = lwmem_malloc_from(®ions_used[2], 16);
- lwmem_debug_print(1, 1);
- ptr1 = lwmem_realloc_from(®ions_used[2], ptr1, 24);
- lwmem_debug_print(1, 1);
- lwmem_free(ptr1);
- lwmem_debug_print(1, 1);
-
- return 0;
-
- /* We always try to reallocate pointer ptr2 */
-
- /* Create 3a case */
- printf("\r\n------------------------------------------------------------------------\r\n");
- lwmem_debug_restore_to_saved();
- printf("State 3a\r\n");
- rptr1 = lwmem_realloc(ptr2, 8);
- lwmem_debug_print(1, 1);
- ASSERT(rptr1 == ptr2);
-
- /* Create 3b case */
- printf("\r\n------------------------------------------------------------------------\r\n");
- lwmem_debug_restore_to_saved();
- printf("State 3b\r\n");
- rptr2 = lwmem_realloc(ptr2, 20);
- lwmem_debug_print(1, 1);
- ASSERT(rptr2 == ptr2);
-
- /* Create 3c case */
- printf("\r\n------------------------------------------------------------------------\r\n");
- lwmem_debug_restore_to_saved();
- printf("State 3c\r\n");
- rptr3 = lwmem_realloc(ptr2, 24);
- lwmem_debug_print(1, 1);
- ASSERT(rptr3 == ptr1);
-
- /* Create 3d case */
- printf("\r\n------------------------------------------------------------------------\r\n");
- lwmem_debug_restore_to_saved();
- printf("State 3d\r\n");
- rptr4 = lwmem_realloc(ptr2, 36);
- lwmem_debug_print(1, 1);
- ASSERT(rptr4 != ptr1 && rptr4 != ptr2 && rptr4 != ptr3 && rptr4 != ptr4);
-
+ lwmem_test_memory_structure();
+ //lwmem_test_run();
return 0;
}
diff --git a/tests/lwmem_test.c b/tests/lwmem_test.c
new file mode 100644
index 0000000..a4b6f66
--- /dev/null
+++ b/tests/lwmem_test.c
@@ -0,0 +1,185 @@
+#include "lwmem/lwmem.h"
+
+/* Assert check */
+#define ASSERT(x) do { \
+ if (!(x)) { \
+ printf("Assert on line %d failed with condition (" # x ")\r\n", (int)__LINE__); \
+ } else {\
+ printf("Assert on line %d passed with condition (" # x ")\r\n", (int)__LINE__); \
+ }\
+} while (0)
+
+/********************************************/
+/* Test case helpers */
+#define IS_ALLOC_IN_REGION(ptr, region) ASSERT((unsigned char *)(ptr) >= (region)->start_addr && (unsigned char *)(ptr) < ((unsigned char *)(region)->start_addr + (region)->size))
+
+/********************************************/
+/* Configuration for default lwmem instance */
+
+/* Region memory declaration */
+uint8_t lw_mem1[1024], lw_mem2[256], lw_mem3[128];
+
+/* Regions descriptor */
+lwmem_region_t
+lw_regions[] = {
+ { lw_mem3, sizeof(lw_mem3) },
+ { lw_mem2, sizeof(lw_mem2) },
+ { lw_mem1, sizeof(lw_mem1) },
+};
+
+/********************************************/
+/********************************************/
+/* Configuration for custom lwmem instance */
+/* LwMEM instance */
+lwmem_t lw_c;
+
+/* Region memory declaration */
+uint8_t lw_c_mem1[1024], lw_c_mem2[256], lw_c_mem3[128];
+
+/* Regions descriptor */
+lwmem_region_t
+lw_c_regions[] = {
+ { lw_c_mem3, sizeof(lw_c_mem3) },
+ { lw_c_mem2, sizeof(lw_c_mem2) },
+ { lw_c_mem1, sizeof(lw_c_mem1) },
+};
+/********************************************/
+
+void
+lwmem_test_run(void) {
+ void* ptr_1, * ptr_2, * ptr_3, * ptr_4;
+ void* ptr_c_1, * ptr_c_2, * ptr_c_3, * ptr_c_4;
+
+ /* Initialize default lwmem instance */
+ /* Use one of 2 possible function calls: */
+ lwmem_assignmem(lw_regions, sizeof(lw_regions) / sizeof(lw_regions[0]));
+ //lwmem_assignmem_ex(NULL, lw_regions, sizeof(lw_regions) / sizeof(lw_regions[0]));
+
+ /* Initialize another, custom instance */
+ lwmem_assignmem_ex(&lw_c, lw_c_regions, sizeof(lw_c_regions) / sizeof(lw_c_regions[0]));
+
+ /* Regions initialized... */
+
+ /********************************************/
+ /* Run tests on default region */
+ /********************************************/
+
+ /* Allocation of 64 bytes must in in first region */
+ ptr_1 = lwmem_malloc(64);
+ IS_ALLOC_IN_REGION(ptr_1, &lw_regions[0]);
+
+ /* Allocation of 256 bytes can only be in 3rd region */
+ ptr_2 = lwmem_malloc(256);
+ IS_ALLOC_IN_REGION(ptr_2, &lw_regions[2]);
+
+ /* Allocation of 128 bytes can be in second or third region (depends on memory availability),
+ but in case of these tests it can be (and should be) in second region */
+ ptr_3 = lwmem_malloc(128);
+ IS_ALLOC_IN_REGION(ptr_3, &lw_regions[1]);
+
+ /* Free all pointers to default state */
+ lwmem_free(ptr_1);
+ lwmem_free(ptr_2);
+ lwmem_free(ptr_3);
+
+ /* Force allocation region to be used */
+ /* Allocation of 16-bytes forced to 2nd region */
+ ptr_1 = lwmem_malloc_ex(NULL, &lw_regions[1], 16);
+ IS_ALLOC_IN_REGION(ptr_1, &lw_regions[1]);
+
+ /* Allocate ptr 2 in any region of default lwmem, the first available must be 1st region */
+ ptr_2 = lwmem_malloc_ex(NULL, NULL, 16);
+ IS_ALLOC_IN_REGION(ptr_2, &lw_regions[0]);
+
+ /* Free pointers */
+ lwmem_free(ptr_1);
+ lwmem_free(ptr_2);
+
+ /********************************************/
+ /* Run tests on custom region */
+ /********************************************/
+
+ /* Allocation of 64 bytes must in in first region */
+ ptr_c_1 = lwmem_malloc_ex(&lw_c, NULL, 64);
+ IS_ALLOC_IN_REGION(ptr_c_1, &lw_c_regions[0]);
+
+ /* Allocation of 256 bytes can only be in 3rd region */
+ ptr_c_2 = lwmem_malloc_ex(&lw_c, NULL, 256);
+ IS_ALLOC_IN_REGION(ptr_c_2, &lw_c_regions[2]);
+
+ /* Allocation of 128 bytes can be in second or third region (depends on memory availability),
+ but in case of these tests it can be (and should be) in second region */
+ ptr_c_3 = lwmem_malloc_ex(&lw_c, NULL, 128);
+ IS_ALLOC_IN_REGION(ptr_c_3, &lw_c_regions[1]);
+
+ /* Free all pointers to default state */
+ lwmem_free(ptr_c_1);
+ lwmem_free(ptr_c_2);
+ lwmem_free(ptr_c_3);
+}
+
+/* For debug purposes */
+lwmem_region_t* regions_used;
+size_t regions_count = 4; /* Use only 1 region for debug purposes of non-free areas */
+
+void
+lwmem_test_memory_structure(void) {
+ uint8_t* ptr1, *ptr2, *ptr3, *ptr4;
+ uint8_t* rptr1, *rptr2, *rptr3, *rptr4;
+
+ /* Create regions for debug purpose */
+ if (!lwmem_debug_create_regions(®ions_used, regions_count, 128)) {
+ printf("Cannot allocate memory for regions for debug purpose!\r\n");
+ return;
+ }
+ lwmem_assignmem(regions_used, regions_count);
+ printf("Manager is ready!\r\n");
+ lwmem_debug_print(1, 1);
+
+ /* Test case 1, allocate 3 blocks, each of different size */
+ /* We know that sizeof internal metadata block is 8 bytes on win32 */
+ printf("\r\n\r\nAllocating 4 pointers and freeing first and third..\r\n");
+ ptr1 = lwmem_malloc(8);
+ ptr2 = lwmem_malloc(4);
+ ptr3 = lwmem_malloc(4);
+ ptr4 = lwmem_malloc(16);
+ lwmem_free(ptr1); /* Free but keep value for future comparison */
+ lwmem_free(ptr3); /* Free but keep value for future comparison */
+ lwmem_debug_print(1, 1);
+ printf("Debug above is effectively state 3\r\n");
+ lwmem_debug_save_state(); /* Every restore operations rewinds here */
+
+ /* We always try to reallocate pointer ptr2 */
+
+ /* Create 3a case */
+ printf("\r\n------------------------------------------------------------------------\r\n");
+ lwmem_debug_restore_to_saved();
+ printf("State 3a\r\n");
+ rptr1 = lwmem_realloc(ptr2, 8);
+ lwmem_debug_print(1, 1);
+ ASSERT(rptr1 == ptr2);
+
+ /* Create 3b case */
+ printf("\r\n------------------------------------------------------------------------\r\n");
+ lwmem_debug_restore_to_saved();
+ printf("State 3b\r\n");
+ rptr2 = lwmem_realloc(ptr2, 20);
+ lwmem_debug_print(1, 1);
+ ASSERT(rptr2 == ptr2);
+
+ /* Create 3c case */
+ printf("\r\n------------------------------------------------------------------------\r\n");
+ lwmem_debug_restore_to_saved();
+ printf("State 3c\r\n");
+ rptr3 = lwmem_realloc(ptr2, 24);
+ lwmem_debug_print(1, 1);
+ ASSERT(rptr3 == ptr1);
+
+ /* Create 3d case */
+ printf("\r\n------------------------------------------------------------------------\r\n");
+ lwmem_debug_restore_to_saved();
+ printf("State 3d\r\n");
+ rptr4 = lwmem_realloc(ptr2, 36);
+ lwmem_debug_print(1, 1);
+ ASSERT(rptr4 != ptr1 && rptr4 != ptr2 && rptr4 != ptr3 && rptr4 != ptr4);
+}
\ No newline at end of file