1 /**
2 	MemoryManager.D
3 
4 	Ported from MemoryManager.cpp by Laeeth Isharc
5 //
6 // Platform:    Microsoft Windows
7 //
8 ///***************************************************************************
9 */
10 module xlld.memorymanager;
11 
12 import std.typecons: Flag, Yes;
13 import std.experimental.allocator.mallocator: Mallocator;
14 
15 alias Allocator = Mallocator;
16 alias allocator = Allocator.instance;
17 
18 enum StartingMemorySize = 10240;
19 enum MaxMemorySize=100*1024*1024;
20 
21 private MemoryPool excelCallPool;
22 
23 static this() {
24     excelCallPool = MemoryPool(StartingMemorySize);
25 }
26 
27 ubyte* GetTempMemory(Flag!"autoFree" autoFree = Yes.autoFree)(size_t numBytes)
28 {
29     static if(autoFree) {
30         return excelCallPool.allocate(numBytes).ptr;
31     } else {
32         return allocator.allocate(numBytes).ptr;
33     }
34 }
35 
36 void FreeAllTempMemory() nothrow @nogc
37 {
38     excelCallPool.freeAll;
39 }
40 
41 
42 struct MemoryPool {
43 
44     ubyte[] data;
45     size_t curPos=0;
46 
47     this(size_t startingMemorySize) nothrow @nogc {
48         import std.experimental.allocator: makeArray;
49 
50         if (data.length==0)
51             data=allocator.makeArray!(ubyte)(startingMemorySize);
52         curPos=0;
53     }
54 
55     ~this() nothrow @nogc {
56         dispose;
57     }
58 
59     void dispose() nothrow @nogc {
60         import std.experimental.allocator: dispose;
61 
62         if(data.length>0)
63             allocator.dispose(data);
64         data = [];
65         curPos=0;
66     }
67 
68     void dispose(string) nothrow @nogc {
69         dispose;
70     }
71 
72     ubyte[] allocate(size_t numBytes) nothrow @nogc {
73         import std.algorithm: min;
74         import std.experimental.allocator: expandArray;
75 
76         if (numBytes<=0)
77             return null;
78 
79         if (curPos + numBytes > data.length)
80         {
81             auto newAllocationSize = min(MaxMemorySize, data.length * 2);
82             if (newAllocationSize <= data.length)
83                 return null;
84             allocator.expandArray(data, newAllocationSize, 0);
85         }
86 
87         auto lpMemory = data[curPos .. curPos+numBytes];
88         curPos += numBytes;
89 
90         return lpMemory;
91     }
92 
93     // Frees all the temporary memory by setting the index for available memory back to the beginning
94     void freeAll() nothrow @nogc {
95         curPos = 0;
96     }
97 }