1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 module tanya.memory.tests.mmappool;
5 
6 import tanya.memory.mmappool;
7 
8 @nogc nothrow pure @system unittest
9 {
10     auto p = MmapPool.instance.allocate(20);
11     assert(p);
12     MmapPool.instance.deallocate(p);
13 
14     p = MmapPool.instance.allocate(0);
15     assert(p.length == 0);
16 }
17 
18 @nogc nothrow pure @system unittest
19 {
20     auto p = MmapPool.instance.allocate(20);
21 
22     assert(MmapPool.instance.deallocate(p));
23 }
24 
25 @nogc nothrow pure @system unittest
26 {
27     void[] p;
28     assert(!MmapPool.instance.reallocateInPlace(p, 5));
29     assert(p is null);
30 
31     p = MmapPool.instance.allocate(1);
32     auto orig = p.ptr;
33 
34     assert(MmapPool.instance.reallocateInPlace(p, 2));
35     assert(p.length == 2);
36     assert(p.ptr == orig);
37 
38     assert(MmapPool.instance.reallocateInPlace(p, 4));
39     assert(p.length == 4);
40     assert(p.ptr == orig);
41 
42     assert(MmapPool.instance.reallocateInPlace(p, 2));
43     assert(p.length == 2);
44     assert(p.ptr == orig);
45 
46     MmapPool.instance.deallocate(p);
47 }
48 
49 @nogc nothrow pure @system unittest
50 {
51     void[] p;
52     MmapPool.instance.reallocate(p, 10 * int.sizeof);
53     (cast(int[]) p)[7] = 123;
54 
55     assert(p.length == 40);
56 
57     MmapPool.instance.reallocate(p, 8 * int.sizeof);
58 
59     assert(p.length == 32);
60     assert((cast(int[]) p)[7] == 123);
61 
62     MmapPool.instance.reallocate(p, 20 * int.sizeof);
63     (cast(int[]) p)[15] = 8;
64 
65     assert(p.length == 80);
66     assert((cast(int[]) p)[15] == 8);
67     assert((cast(int[]) p)[7] == 123);
68 
69     MmapPool.instance.reallocate(p, 8 * int.sizeof);
70 
71     assert(p.length == 32);
72     assert((cast(int[]) p)[7] == 123);
73 
74     MmapPool.instance.deallocate(p);
75 }
76 
77 // A lot of allocations/deallocations, but it is the minimum caused a
78 // segmentation fault because MmapPool reallocateInPlace moves a block wrong.
79 @nogc nothrow pure @system unittest
80 {
81     auto a = MmapPool.instance.allocate(16);
82     auto d = MmapPool.instance.allocate(16);
83     auto b = MmapPool.instance.allocate(16);
84     auto e = MmapPool.instance.allocate(16);
85     auto c = MmapPool.instance.allocate(16);
86     auto f = MmapPool.instance.allocate(16);
87 
88     MmapPool.instance.deallocate(a);
89     MmapPool.instance.deallocate(b);
90     MmapPool.instance.deallocate(c);
91 
92     a = MmapPool.instance.allocate(50);
93     MmapPool.instance.reallocateInPlace(a, 64);
94     MmapPool.instance.deallocate(a);
95 
96     a = MmapPool.instance.allocate(1);
97     auto tmp1 = MmapPool.instance.allocate(1);
98     auto h1 = MmapPool.instance.allocate(1);
99     auto tmp2 = cast(ubyte[]) MmapPool.instance.allocate(1);
100 
101     auto h2 = MmapPool.instance.allocate(2);
102     tmp1 = MmapPool.instance.allocate(1);
103     MmapPool.instance.deallocate(h2);
104     MmapPool.instance.deallocate(h1);
105 
106     h2 = MmapPool.instance.allocate(2);
107     h1 = MmapPool.instance.allocate(1);
108     MmapPool.instance.deallocate(h2);
109 
110     auto rep = cast(void[]) tmp2;
111     MmapPool.instance.reallocate(rep, tmp1.length);
112     tmp2 = cast(ubyte[]) rep;
113 
114     MmapPool.instance.reallocate(tmp1, 9);
115 
116     rep = cast(void[]) tmp2;
117     MmapPool.instance.reallocate(rep, tmp1.length);
118     tmp2 = cast(ubyte[]) rep;
119     MmapPool.instance.reallocate(tmp1, 17);
120 
121     tmp2[$ - 1] = 0;
122 
123     MmapPool.instance.deallocate(tmp1);
124 
125     b = MmapPool.instance.allocate(16);
126 
127     MmapPool.instance.deallocate(h1);
128     MmapPool.instance.deallocate(a);
129     MmapPool.instance.deallocate(b);
130     MmapPool.instance.deallocate(d);
131     MmapPool.instance.deallocate(e);
132     MmapPool.instance.deallocate(f);
133 }