1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#include "BsMMAlloc.h"
4#include <stdlib.h>
5#include <string.h>
6
7typedef struct tagMMAllocHeader MMAllocHeader;
8
9struct tagMMAllocHeader
10{
11 MMAllocHeader* next;
12 MMAllocHeader* prev;
13};
14
15void* mmalloc_new_context()
16{
17 MMAllocHeader* header = (MMAllocHeader*)malloc(sizeof(MMAllocHeader));
18 header->next = 0;
19 header->prev = 0;
20
21 return header;
22}
23
24void mmalloc_free_context(void* context)
25{
26 MMAllocHeader* header = (MMAllocHeader*)context;
27 while (header->next != 0)
28 mmfree((char*)header->next + sizeof(MMAllocHeader));
29
30 free(header);
31}
32
33void* mmalloc(void* context, int size)
34{
35 void* buffer = malloc(size + sizeof(MMAllocHeader));
36
37 MMAllocHeader* header = (MMAllocHeader*)buffer;
38 MMAllocHeader* parent = (MMAllocHeader*)context;
39
40 header->next = parent->next;
41 if (parent->next)
42 parent->next->prev = header;
43
44 header->prev = parent;
45 parent->next = header;
46
47 return (char*)buffer + sizeof(MMAllocHeader);
48}
49
50void mmfree(void* ptr)
51{
52 void* buffer = (char*)ptr - sizeof(MMAllocHeader);
53 MMAllocHeader* header = (MMAllocHeader*)buffer;
54
55 if (header->prev)
56 header->prev->next = header->next;
57
58 if (header->next)
59 header->next->prev = header->prev;
60
61 free(buffer);
62}
63
64char* mmalloc_strdup(void* context, const char* input)
65{
66 size_t length = strlen(input);
67 char* output = (char*)mmalloc(context, (int)(sizeof(char) * (length + 1)));
68
69 memcpy(output, input, length);
70 output[length] = '\0';
71
72 return output;
73}