summaryrefslogtreecommitdiffstats
path: root/tests/memtest
diff options
context:
space:
mode:
authorJay Sorg <jay.sorg@gmail.com>2013-06-28 19:37:03 -0700
committerJay Sorg <jay.sorg@gmail.com>2013-06-28 19:37:03 -0700
commita330226dd999f2061e5616b06deb96197eb1cc59 (patch)
treefee7be6d969bb4af8ed9cfeccf8d7c19b02e122c /tests/memtest
parente75767e4dd02bddc37ea939b74071a4e710b41b9 (diff)
downloadxrdp-proprietary-a330226dd999f2061e5616b06deb96197eb1cc59.tar.gz
xrdp-proprietary-a330226dd999f2061e5616b06deb96197eb1cc59.zip
added libmem and a test
Diffstat (limited to 'tests/memtest')
-rw-r--r--tests/memtest/Makefile13
-rw-r--r--tests/memtest/libmem.c423
-rw-r--r--tests/memtest/libmem.h18
-rw-r--r--tests/memtest/memtest.c60
4 files changed, 514 insertions, 0 deletions
diff --git a/tests/memtest/Makefile b/tests/memtest/Makefile
new file mode 100644
index 00000000..c0310ece
--- /dev/null
+++ b/tests/memtest/Makefile
@@ -0,0 +1,13 @@
+
+OBJS = libmem.o memtest.o
+
+#CFLAGS = -O2 -Wall
+CFLAGS = -g
+
+all: memtest
+
+memtest: $(OBJS)
+ $(CC) -o memtest $(OBJS)
+
+clean:
+ rm -f $(OBJS) librdp.a
diff --git a/tests/memtest/libmem.c b/tests/memtest/libmem.c
new file mode 100644
index 00000000..8038f108
--- /dev/null
+++ b/tests/memtest/libmem.c
@@ -0,0 +1,423 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ALIGN_BY 1024
+#define ALIGN_BY_M1 (ALIGN_BY - 1)
+#define ALIGN(_in) (((_in) + ALIGN_BY_M1) & (~ALIGN_BY_M1))
+
+struct mem_item
+{
+ unsigned int addr;
+ int bytes;
+ struct mem_item* next;
+ struct mem_item* prev;
+};
+
+struct mem_info
+{
+ unsigned int addr;
+ int bytes;
+ int flags;
+ struct mem_item* free_head;
+ struct mem_item* free_tail;
+ struct mem_item* used_head;
+ struct mem_item* used_tail;
+};
+
+/*****************************************************************************/
+static int
+libmem_free_mem_item(struct mem_info* self, struct mem_item* mi)
+{
+ if (self == 0 || mi == 0)
+ {
+ return 0;
+ }
+ if (mi->prev != 0)
+ {
+ mi->prev->next = mi->next;
+ }
+ if (mi->next != 0)
+ {
+ mi->next->prev = mi->prev;
+ }
+ if (mi == self->free_head)
+ {
+ self->free_head = mi->next;
+ }
+ if (mi == self->free_tail)
+ {
+ self->free_tail = mi->prev;
+ }
+ if (mi == self->used_head)
+ {
+ self->used_head = mi->next;
+ }
+ if (mi == self->used_tail)
+ {
+ self->used_tail = mi->prev;
+ }
+ free(mi);
+ return 0;
+}
+
+/*****************************************************************************/
+void*
+libmem_init(unsigned int addr, int bytes)
+{
+ struct mem_info* self;
+ struct mem_item* mi;
+
+ self = (struct mem_info*)malloc(sizeof(struct mem_info));
+ memset(self, 0, sizeof(struct mem_info));
+ self->addr = addr;
+ self->bytes = bytes;
+ //self->flags = 1;
+ mi = (struct mem_item*)malloc(sizeof(struct mem_item));
+ memset(mi, 0, sizeof(struct mem_item));
+ mi->addr = addr;
+ mi->bytes = bytes;
+ self->free_head = mi;
+ self->free_tail = mi;
+ return self;
+}
+
+/*****************************************************************************/
+void
+libmem_deinit(void* aself)
+{
+ struct mem_info* self;
+
+ self = (struct mem_info*)aself;
+ if (self == 0)
+ {
+ return;
+ }
+ while (self->free_head != 0)
+ {
+ libmem_free_mem_item(self, self->free_head);
+ }
+ while (self->used_head != 0)
+ {
+ libmem_free_mem_item(self, self->used_head);
+ }
+ free(self);
+}
+
+/****************************************************************************/
+static int
+libmem_add_used_item(struct mem_info* self, unsigned int addr, int bytes)
+{
+ struct mem_item* mi;
+ struct mem_item* new_mi;
+ int added;
+
+ if (self == 0 || addr == 0)
+ {
+ return 1;
+ }
+ if (self->used_head == 0)
+ {
+ /* add first item */
+ new_mi = (struct mem_item*)malloc(sizeof(struct mem_item));
+ memset(new_mi, 0, sizeof(struct mem_item));
+ new_mi->addr = addr;
+ new_mi->bytes = bytes;
+ self->used_head = new_mi;
+ self->used_tail = new_mi;
+ return 0;
+ }
+ added = 0;
+ mi = self->used_head;
+ while (mi != 0)
+ {
+ if (mi->addr > addr)
+ {
+ /* add before */
+ new_mi = (struct mem_item*)malloc(sizeof(struct mem_item));
+ memset(new_mi, 0, sizeof(struct mem_item));
+ new_mi->addr = addr;
+ new_mi->bytes = bytes;
+ new_mi->prev = mi->prev;
+ new_mi->next = mi;
+ if (mi->prev != 0)
+ {
+ mi->prev->next = new_mi;
+ }
+ mi->prev = new_mi;
+ if (self->used_head == mi)
+ {
+ self->used_head = new_mi;
+ }
+ added = 1;
+ break;
+ }
+ mi = mi->next;
+ }
+ if (!added)
+ {
+ /* add last */
+ new_mi = (struct mem_item*)malloc(sizeof(struct mem_item));
+ memset(new_mi, 0, sizeof(struct mem_item));
+ new_mi->addr = addr;
+ new_mi->bytes = bytes;
+ self->used_tail->next = new_mi;
+ new_mi->prev = self->used_tail;
+ self->used_tail = new_mi;
+ }
+ return 0;
+}
+
+/****************************************************************************/
+static int
+libmem_add_free_item(struct mem_info* self, unsigned int addr, int bytes)
+{
+ struct mem_item* mi;
+ struct mem_item* new_mi;
+ int added;
+
+ if (self == 0 || addr == 0)
+ {
+ return 1;
+ }
+ if (self->free_head == 0)
+ {
+ /* add first item */
+ new_mi = (struct mem_item*)malloc(sizeof(struct mem_item));
+ memset(new_mi, 0, sizeof(struct mem_item));
+ new_mi->addr = addr;
+ new_mi->bytes = bytes;
+ self->free_head = new_mi;
+ self->free_tail = new_mi;
+ return 0;
+ }
+ added = 0;
+ mi = self->free_head;
+ while (mi != 0)
+ {
+ if (mi->addr > addr)
+ {
+ /* add before */
+ new_mi = (struct mem_item*)malloc(sizeof(struct mem_item));
+ memset(new_mi, 0, sizeof(struct mem_item));
+ new_mi->addr = addr;
+ new_mi->bytes = bytes;
+ new_mi->prev = mi->prev;
+ new_mi->next = mi;
+ if (mi->prev != 0)
+ {
+ mi->prev->next = new_mi;
+ }
+ mi->prev = new_mi;
+ if (self->free_head == mi)
+ {
+ self->free_head = new_mi;
+ }
+ added = 1;
+ break;
+ }
+ mi = mi->next;
+ }
+ if (!added)
+ {
+ /* add last */
+ new_mi = (struct mem_item*)malloc(sizeof(struct mem_item));
+ memset(new_mi, 0, sizeof(struct mem_item));
+ new_mi->addr = addr;
+ new_mi->bytes = bytes;
+ self->free_tail->next = new_mi;
+ new_mi->prev = self->free_tail;
+ self->free_tail = new_mi;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int
+libmem_pack_free(struct mem_info* self)
+{
+ struct mem_item* mi;
+ int cont;
+
+ cont = 1;
+ while (cont)
+ {
+ cont = 0;
+ mi = self->free_head;
+ while (mi != 0)
+ {
+ /* combine */
+ if (mi->next != 0)
+ {
+ if (mi->addr + mi->bytes == mi->next->addr)
+ {
+ mi->bytes += mi->next->bytes;
+ cont = 1;
+ libmem_free_mem_item(self, mi->next);
+ }
+ }
+ /* remove empties */
+ if (mi->bytes == 0)
+ {
+ cont = 1;
+ libmem_free_mem_item(self, mi);
+ mi = self->free_head;
+ continue;
+ }
+ mi = mi->next;
+ }
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int
+libmem_print(struct mem_info* self)
+{
+ struct mem_item* mi;
+
+ printf("libmem_print:\n");
+ printf(" used_head %p\n", self->used_head);
+ printf(" used_tail %p\n", self->used_tail);
+ mi = self->used_head;
+ if (mi != 0)
+ {
+ printf(" used list\n");
+ while (mi != 0)
+ {
+ printf(" ptr %p prev %p next %p addr 0x%8.8x bytes %d\n",
+ mi, mi->prev, mi->next, mi->addr, mi->bytes);
+ mi = mi->next;
+ }
+ }
+ printf(" free_head %p\n", self->free_head);
+ printf(" free_tail %p\n", self->free_tail);
+ mi = self->free_head;
+ if (mi != 0)
+ {
+ printf(" free list\n");
+ while (mi != 0)
+ {
+ printf(" ptr %p prev %p next %p addr 0x%8.8x bytes %d\n",
+ mi, mi->prev, mi->next, mi->addr, mi->bytes);
+ mi = mi->next;
+ }
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+unsigned int
+libmem_alloc(void* obj, int bytes)
+{
+ struct mem_info* self;
+ struct mem_item* mi;
+ unsigned int addr;
+
+ if (bytes < 1)
+ {
+ return 0;
+ }
+ bytes = ALIGN(bytes);
+ self = (struct mem_info*)obj;
+ addr = 0;
+ if (bytes > 16 * 1024)
+ {
+ /* big blocks */
+ mi = self->free_tail;
+ while (mi != 0)
+ {
+ if (bytes <= mi->bytes)
+ {
+ addr = mi->addr;
+ mi->bytes -= bytes;
+ mi->addr += bytes;
+ break;
+ }
+ mi = mi->prev;
+ }
+ }
+ else
+ {
+ /* small blocks */
+ mi = self->free_head;
+ while (mi != 0)
+ {
+ if (bytes <= mi->bytes)
+ {
+ addr = mi->addr;
+ mi->bytes -= bytes;
+ mi->addr += bytes;
+ break;
+ }
+ mi = mi->next;
+ }
+ }
+ if (addr != 0)
+ {
+ libmem_add_used_item(self, addr, bytes);
+ libmem_pack_free(self);
+ if (self->flags & 1)
+ {
+ libmem_print(self);
+ }
+ }
+ else
+ {
+ printf("libmem_alloc: error\n");
+ }
+ return addr;
+}
+
+/*****************************************************************************/
+int
+libmem_free(void* obj, unsigned int addr)
+{
+ struct mem_info* self;
+ struct mem_item* mi;
+
+ if (addr == 0)
+ {
+ return 0;
+ }
+ self = (struct mem_info*)obj;
+ mi = self->used_head;
+ while (mi != 0)
+ {
+ if (mi->addr == addr)
+ {
+ libmem_add_free_item(self, mi->addr, mi->bytes);
+ libmem_free_mem_item(self, mi);
+ libmem_pack_free(self);
+ if (self->flags & 1)
+ {
+ libmem_print(self);
+ }
+ return 0;
+ }
+ mi = mi->next;
+ }
+ printf("libmem_free: error\n");
+ return 1;
+}
+
+/*****************************************************************************/
+int
+libmem_set_flags(void* obj, int flags)
+{
+ struct mem_info* self;
+
+ self = (struct mem_info*)obj;
+ self->flags |= flags;
+}
+
+/*****************************************************************************/
+int
+libmem_clear_flags(void* obj, int flags)
+{
+ struct mem_info* self;
+
+ self = (struct mem_info*)obj;
+ self->flags &= ~flags;
+}
diff --git a/tests/memtest/libmem.h b/tests/memtest/libmem.h
new file mode 100644
index 00000000..4bc4b1ec
--- /dev/null
+++ b/tests/memtest/libmem.h
@@ -0,0 +1,18 @@
+
+#ifndef _LIBMEM_C
+#define _LIBMEM_C
+
+void*
+libmem_init(unsigned int addr, int bytes);
+void
+libmem_deinit(void* aself);
+unsigned int
+libmem_alloc(void* obj, int bytes);
+int
+libmem_free(void* obj, unsigned int addr);
+int
+libmem_set_flags(void* obj, int flags);
+int
+libmem_clear_flags(void* obj, int flags);
+
+#endif
diff --git a/tests/memtest/memtest.c b/tests/memtest/memtest.c
new file mode 100644
index 00000000..e7a26045
--- /dev/null
+++ b/tests/memtest/memtest.c
@@ -0,0 +1,60 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libmem.h"
+
+int main(int argc, char** argv)
+{
+ void* obj;
+ unsigned int addr1;
+ unsigned int addr2;
+ unsigned int addr3;
+ unsigned int addr4;
+ unsigned int addr5;
+ int index;
+ int rd;
+
+ srand(time(0));
+ obj = libmem_init(0x80000000, 64 * 1024 * 1024);
+ for (index = 0; index < 256; index++)
+ {
+ rd = rand() & 0xffff;
+ printf("1 rd %d\n", rd);
+ addr1 = libmem_alloc(obj, rd);
+ rd = rand() & 0xffff;
+ printf("2 rd %d\n", rd);
+ addr2 = libmem_alloc(obj, rd);
+ rd = rand() & 0xffff;
+ printf("3 rd %d\n", rd);
+ addr3 = libmem_alloc(obj, rd);
+ rd = rand() & 0xffff;
+ printf("4 rd %d\n", rd);
+ addr4 = libmem_alloc(obj, rd);
+ addr5 = libmem_alloc(obj, rd);
+ libmem_free(obj, addr1);
+ printf("5\n");
+ addr1 = libmem_alloc(obj, 64);
+ printf("6\n");
+ libmem_free(obj, addr3);
+ printf("7\n");
+ addr3 = libmem_alloc(obj, 64 * 1024);
+ libmem_free(obj, addr5);
+ addr5 = libmem_alloc(obj, 64 * 1024);
+ printf("8\n");
+ libmem_free(obj, addr1);
+ printf("9\n");
+ libmem_free(obj, addr2);
+ printf("10\n");
+ libmem_free(obj, addr3);
+ libmem_free(obj, addr4);
+ if (index == 255)
+ {
+ libmem_set_flags(obj, 1);
+ }
+ libmem_free(obj, addr5);
+ }
+ libmem_deinit(obj);
+ return 0;
+}