Frobby 0.9.5
ArenaTest.cpp
Go to the documentation of this file.
1/* Frobby: Software for monomial ideal computations.
2 Copyright (C) 2011 University of Aarhus
3 Contact Bjarke Hammersholt Roune for license information (www.broune.com)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see http://www.gnu.org/licenses/.
17*/
18#include "stdinc.h"
19#include "Arena.h"
20#include "tests.h"
21
22#include <algorithm>
23#include <sstream>
24
26
27TEST(Arena, NoOp) {
28 Arena arena;
29}
30
31TEST(Arena, Big) {
32 Arena arena;
33 void* a = arena.alloc(5);
34 arena.freeTop(arena.alloc(1024 * 1024));
35 arena.freeTop(arena.alloc(1024 * 1024));
36 ASSERT_FALSE(arena.isEmpty());
37 arena.freeTop(a);
38 ASSERT_TRUE(arena.isEmpty());
39
40}
41
42TEST(Arena, Zero) {
43 Arena arena;
44 void* a = arena.alloc(0);
45 void* b = arena.alloc(0);
46 void* c = arena.alloc(0);
47 ASSERT_NEQ(a, b);
48 ASSERT_NEQ(a, c);
49 ASSERT_NEQ(b, c);
50 ASSERT_FALSE(arena.isEmpty());
51}
52
53TEST(Arena, Many) {
54 Arena arena;
55 vector<pair<char*, char*> > allocs;
56
57 for (size_t i = 3; i < 10; ++i) {
58 for (size_t size = 0; size < 100; ++size) {
59 char* a = static_cast<char*>(arena.alloc(size));
60 pair<char*, char*> p(a, a + size);
61 for (size_t j = 0; j < allocs.size(); ++j) {
62 pair<char*, char*> p2 = allocs[j];
63 if (p.first <= p2.first)
64 ASSERT_FALSE_SILENT(p2.first < p.second);
65 else
66 ASSERT_FALSE_SILENT(p.first < p2.second);
67 }
68 fill(p.first, p.second, static_cast<char>(-1));
69 allocs.push_back(p);
70 }
71
72 while (allocs.size() > 10 * i) {
73 arena.freeTop(allocs.back().first);
74 allocs.pop_back();
75 }
76
77 arena.freeAndAllAfter(allocs[5 * i].first);
78 allocs.resize(5 * i);
79 }
80 ASSERT_FALSE(arena.isEmpty());
81 arena.freeAndAllAfter(allocs.front().first);
82 ASSERT_TRUE(arena.isEmpty());
83}
84
85TEST(Arena, BigAndOverflow) {
86 Arena arena;
87 // aligning size causes overflow
88 ASSERT_EXCEPTION(arena.alloc(static_cast<size_t>(-1)), bad_alloc);
89
90 // 2x size is an overflow
91 ASSERT_EXCEPTION(arena.alloc(static_cast<size_t>(-1)/2 + 1), bad_alloc);
92
93 // causes attempt at allocating almost the entire virtual memory space
94 // which cannot succeed
95 ASSERT_EXCEPTION(arena.alloc(static_cast<size_t>(-1)/2 - 100), bad_alloc);
96
97 // sizeof(long) * x overflows to a smaller value (0).
98 const size_t smallerOverflow = 1ul << (8*sizeof(long) - 1);
99 ASSERT(smallerOverflow > 0);
100 ASSERT(smallerOverflow * sizeof(long) == 0);
101 ASSERT_EXCEPTION(arena.allocArray<long>(smallerOverflow), bad_alloc);
102
103 // sizeof(int) * x overflows to a greater value
104 const size_t greaterOverflow = (~(0ul)) >> 1;
105 ASSERT(sizeof(long) >= 4);
106 ASSERT(greaterOverflow * sizeof(long) > greaterOverflow);
107 ASSERT(greaterOverflow != (greaterOverflow * sizeof(long)) / sizeof(long));
108 ASSERT_EXCEPTION(arena.allocArray<long>(greaterOverflow), bad_alloc);
109
110 ASSERT_TRUE(arena.isEmpty());
111}
112
113namespace {
114 template<class T, size_t ThrowAt>
115 class _frobby_Helper {
116 public:
117 _frobby_Helper() {
118 _id = ++_count;
119 if (_id == ThrowAt) {
120 _log << 'T' << _id;
121 throw _id;
122 } else
123 _log << '+' << _id;
124 }
125
126 ~_frobby_Helper() {
127 _log << '-' << _id;
128 }
129
130 void setId(size_t id) {_id = id;}
131
132 static string getLog() {return _log.str();}
133
134 private:
135 size_t _id;
136 static size_t _count;
137 static ostringstream _log;
138 };
139
140 template<class T, size_t ThrowAt>
141 size_t _frobby_Helper<T, ThrowAt>::_count = 0;
142
143 template<class T, size_t ThrowAt>
144 ostringstream _frobby_Helper<T, ThrowAt>::_log;
145}
146#define MAKE_HELPER(NAME, THROW_AT) \
147 namespace { \
148 struct _frobby_##NAME##HelperTag {}; \
149 typedef _frobby_Helper<_frobby_##NAME##HelperTag, THROW_AT> NAME##Helper; \
150 }
151
152MAKE_HELPER(ConDecon, 0)
153TEST(Arena, ConDecon) {
154 Arena arena;
155 arena.freeTopArray(arena.allocArray<ConDeconHelper>(0));
156 arena.freeTopArray(arena.allocArray<ConDeconHelper>(3));
157 arena.freeTopArray(arena.allocArray<ConDeconHelper>(0));
158 ASSERT_EQ(ConDeconHelper::getLog(), "+1+2+3-3-2-1");
159 ASSERT_TRUE(arena.isEmpty())
160}
161
162MAKE_HELPER(ConExcep, 4)
163TEST(Arena, ConExcep) {
164 Arena arena;
165 ASSERT_EXCEPTION(arena.allocArray<ConExcepHelper>(10), size_t);
166 ASSERT_EQ(ConExcepHelper::getLog(), "+1+2+3T4-3-2-1");
167 ASSERT_TRUE(arena.isEmpty());
168}
169
170MAKE_HELPER(NoConDecon, 0)
171TEST(Arena, NoConDecon) {
172 Arena arena;
173 pair<NoConDeconHelper*, NoConDeconHelper*> p =
174 arena.allocArrayNoCon<NoConDeconHelper>(3);
175 p.first[0].setId(1);
176 p.first[1].setId(2);
177 p.first[2].setId(3);
178 arena.freeTopArray(p);
179
180 ASSERT_EQ(NoConDeconHelper::getLog(), "-3-2-1");
181 ASSERT_TRUE(arena.isEmpty())
182}
183
184MAKE_HELPER(ConNoDecon, 0)
185TEST(Arena, ConNoDecon) {
186 Arena arena;
187 arena.freeTop(arena.allocArray<ConNoDeconHelper>(3).first);
188 ASSERT_EQ(ConNoDeconHelper::getLog(), "+1+2+3");
189 ASSERT_TRUE(arena.isEmpty())
190}
#define MAKE_HELPER(NAME, THROW_AT)
#define ASSERT_NEQ(A, B)
Definition asserts.h:175
#define ASSERT_EXCEPTION(CODE, EXCEPTION_TYPE)
Definition asserts.h:66
#define ASSERT_TRUE(VALUE)
Definition asserts.h:72
#define ASSERT_EQ(A, B)
Definition asserts.h:147
#define ASSERT_FALSE_SILENT(VALUE)
Definition asserts.h:121
#define ASSERT_FALSE(VALUE)
Definition asserts.h:119
This is an arena allocator.
Definition Arena.h:53
void * alloc(size_t size)
Returns a pointer to a buffer of size bytes.
Definition Arena.h:180
bool isEmpty() const
Returns true if there are no live allocations for this Arena.
Definition Arena.h:117
pair< T *, T * > allocArrayNoCon(size_t elementCount)
As alloc(elementCount * sizeof(T)).
Definition Arena.h:250
void freeTop(void *ptr)
Frees the buffer pointed to by ptr.
Definition Arena.h:209
void freeTopArray(T *array, T *arrayEnd)
As freeTop(array) except that the elements of the array in the range (array, arrayEnd] are deconstruc...
Definition Arena.h:280
void freeAndAllAfter(void *ptr)
Frees the buffer pointed to by ptr and all not yet freed allocations that have happened since that bu...
Definition Arena.h:224
pair< T *, T * > allocArray(size_t elementCount)
As allocArrayNoCon except that constructors for the elements of the array are called.
Definition Arena.h:263
#define TEST(SUITE, TEST_NAME)
Definition macroes.h:41
#define TEST_SUITE(SUITE)
Definition macroes.h:26
This header file includes common definitions and is included as the first line of code in every imple...
#define ASSERT(X)
Definition stdinc.h:86