|
@@ -3,6 +3,28 @@
|
|
|
#include <stdio.h>
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
+struct chunkControl {
|
|
|
+ size_t nodeCount;
|
|
|
+ size_t chunkSize;
|
|
|
+};
|
|
|
+
|
|
|
+struct nodeControl {
|
|
|
+ struct chunkControl *chunk;
|
|
|
+ size_t nodeSize;
|
|
|
+};
|
|
|
+
|
|
|
+#define ROUND_UP_LENGTH(len) ((len+7) & ~0x07)
|
|
|
+
|
|
|
+extern struct nodeControl *mallocNextNode;
|
|
|
+
|
|
|
+#ifdef L_malloc
|
|
|
+
|
|
|
+ * Note: This variable makes the code NOT thread save. */
|
|
|
+struct nodeControl *mallocNextNode = 0;
|
|
|
+static size_t PageSize = 0;
|
|
|
+
|
|
|
+#endif
|
|
|
+
|
|
|
#ifdef L_calloc_dbg
|
|
|
|
|
|
void *
|
|
@@ -61,12 +83,64 @@ calloc(size_t num, size_t size)
|
|
|
void *
|
|
|
malloc(size_t len)
|
|
|
{
|
|
|
- void * result = mmap((void *)0, len, PROT_READ | PROT_WRITE,
|
|
|
- MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
|
|
- if (result == (void*)-1)
|
|
|
- return 0;
|
|
|
-
|
|
|
- return result;
|
|
|
+ void *result;
|
|
|
+ struct chunkControl *chunk;
|
|
|
+ struct nodeControl *next;
|
|
|
+ size_t size;
|
|
|
+
|
|
|
+
|
|
|
+ len = ROUND_UP_LENGTH(len);
|
|
|
+
|
|
|
+ if (len == 0)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+TryAgain:
|
|
|
+ if (mallocNextNode != 0) {
|
|
|
+
|
|
|
+ next = mallocNextNode;
|
|
|
+ chunk = next->chunk;
|
|
|
+ if (((char *)next + sizeof(struct nodeControl)*2 + len) <
|
|
|
+ ((char *)chunk + chunk->chunkSize))
|
|
|
+ {
|
|
|
+
|
|
|
+ * pointer ahead and update chunk node count */
|
|
|
+ next->nodeSize = len;
|
|
|
+ result = (char *)next + sizeof(struct nodeControl);
|
|
|
+ chunk->nodeCount++;
|
|
|
+ next = (struct nodeControl *)
|
|
|
+ ((char *)next + (sizeof(struct nodeControl) + len));
|
|
|
+ next->chunk = chunk;
|
|
|
+ next->nodeSize = 0;
|
|
|
+ mallocNextNode = next;
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (PageSize == 0) {
|
|
|
+ PageSize = getpagesize();
|
|
|
+ }
|
|
|
+ size = len + (sizeof(struct chunkControl) + (sizeof(struct nodeControl) * 2));
|
|
|
+ if (size < PageSize * 2) {
|
|
|
+ size = PageSize * 2;
|
|
|
+ }
|
|
|
+ size = (size + (PageSize-1)) & ~(PageSize-1);
|
|
|
+
|
|
|
+ chunk = mmap((void *)0, size, PROT_READ | PROT_WRITE,
|
|
|
+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
|
|
+ if (chunk == (void*)-1)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ chunk->chunkSize = size;
|
|
|
+ chunk->nodeCount = 0;
|
|
|
+ next = (struct nodeControl *)
|
|
|
+ ((char *)chunk + sizeof(struct chunkControl));
|
|
|
+ next->chunk = chunk;
|
|
|
+ mallocNextNode = next;
|
|
|
+
|
|
|
+ goto TryAgain;
|
|
|
}
|
|
|
|
|
|
#endif
|
|
@@ -76,7 +150,58 @@ malloc(size_t len)
|
|
|
void
|
|
|
free(void * ptr)
|
|
|
{
|
|
|
- munmap(ptr, 0);
|
|
|
+ struct chunkControl *chunk;
|
|
|
+ struct nodeControl *node;
|
|
|
+
|
|
|
+ if (ptr == 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ * and the chunk it belongs to */
|
|
|
+ node = (struct nodeControl *)ptr - 1;
|
|
|
+ chunk = node->chunk;
|
|
|
+
|
|
|
+ chunk->nodeCount--;
|
|
|
+ if (chunk->nodeCount == 0) {
|
|
|
+ if ((void *)mallocNextNode >= (void *)chunk &&
|
|
|
+ ((void *)mallocNextNode < (void *)((char *)chunk + chunk->chunkSize)))
|
|
|
+ {
|
|
|
+ mallocNextNode = 0;
|
|
|
+ }
|
|
|
+ munmap(chunk, chunk->chunkSize);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
+
|
|
|
+#ifdef L_realloc
|
|
|
+
|
|
|
+void *
|
|
|
+realloc(void *ptr, size_t len)
|
|
|
+{
|
|
|
+ struct nodeControl *node;
|
|
|
+ size_t oldSize;
|
|
|
+ void *new;
|
|
|
+
|
|
|
+
|
|
|
+ if (ptr == 0) {
|
|
|
+ return malloc(len);
|
|
|
+ }
|
|
|
+ if (len == 0) {
|
|
|
+ free(ptr);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ node = (struct nodeControl *)ptr - 1;
|
|
|
+ oldSize = node->nodeSize;
|
|
|
+ if (oldSize >= len) {
|
|
|
+ return ptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ new = malloc(len);
|
|
|
+ memcpy(new, ptr, len);
|
|
|
+ free(ptr);
|
|
|
+ return new;
|
|
|
+}
|
|
|
+
|
|
|
+#endif
|
|
|
+
|