A set of benchmarks to compare a new prototype MiniZinc implementation
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
3/*
4 * Main authors:
5 * Guido Tack <guido.tack@monash.edu>
6 */
7
8/* This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
11
12#ifndef __MINIZINC_GC_HH__
13#define __MINIZINC_GC_HH__
14
15#include <minizinc/config.hh>
16#include <minizinc/timer.hh>
17
18#include <cassert>
19#include <cstdlib>
20#include <new>
21#include <unordered_map>
22
23namespace MiniZinc {
24
25/**
26 * \brief Base class for abstract syntax tree nodes
27 */
28class ASTNode {
29 friend class GC;
30
31protected:
32 /// Mark for garbage collection
33 mutable unsigned int _gc_mark : 1;
34 /// Id of the node
35 unsigned int _id : 7;
36 /// Secondary id
37 unsigned int _sec_id : 7;
38 /// Flag
39 unsigned int _flag_1 : 1;
40 /// Flag
41 unsigned int _flag_2 : 1;
42 /// Flag
43 unsigned int _flag_3 : 1;
44 /// Flag
45 unsigned int _flag_4 : 1;
46
47 enum BaseNodes { NID_FL, NID_CHUNK, NID_VEC, NID_END = NID_VEC };
48
49 /// Constructor
50 ASTNode(unsigned int id) : _gc_mark(0), _id(id), _flag_1(0), _flag_2(0), _flag_3(0), _flag_4(0) {}
51
52public:
53 /// Allocate node
54 void* operator new(size_t size);
55
56 /// Placement-new
57 void* operator new(size_t, void* n) throw() { return n; }
58
59 /// Delete node (no-op)
60 void operator delete(void*, size_t) throw() {}
61 /// Delete node (no-op)
62 void operator delete(void*, void*) throw() {}
63
64 /// Delete node (no-op)
65 void operator delete(void*) throw() {}
66
67 /// Return state of first user-defined flag
68 bool user_flag0(void) const { return _flag_3; }
69 /// Set state of first user-defined flag
70 void user_flag0(bool b) { _flag_3 = b; }
71 /// Return state of second user-defined flag
72 bool user_flag1(void) const { return _flag_4; }
73 /// Set state of second user-defined flag
74 void user_flag1(bool b) { _flag_4 = b; }
75};
76
77/**
78 * \brief Base class for unstructured garbage collected data
79 */
80class ASTChunk : public ASTNode {
81 friend class GC;
82
83protected:
84 /// Allocated size
85 size_t _size;
86 /// Storage
87 char _data[4];
88 /// Constructor
89 ASTChunk(size_t size);
90 /// Actual size of object in memory
91 size_t memsize(void) const {
92 size_t s = sizeof(ASTChunk) + (_size <= 4 ? 0 : _size - 4) * sizeof(char);
93 s += ((8 - (s & 7)) & 7);
94 return s;
95 }
96 /// Allocate raw memory
97 static void* alloc(size_t size);
98};
99
100/**
101 * \brief Base class for structured garbage collected data
102 */
103class ASTVec : public ASTNode {
104 friend class GC;
105
106protected:
107 /// Allocated size
108 size_t _size;
109 /// Storage
110 void* _data[2];
111 /// Constructor
112 ASTVec(size_t size);
113 /// Actual size of object in memory
114 size_t memsize(void) const {
115 size_t s = sizeof(ASTVec) + (_size <= 2 ? 0 : _size - 2) * sizeof(void*);
116 s += ((8 - (s & 7)) & 7);
117 return s;
118 }
119 /// Allocate raw memory
120 static void* alloc(size_t size);
121};
122
123class Model;
124class Expression;
125
126class KeepAlive;
127class WeakRef;
128
129class ASTNodeWeakMap;
130
131/// Garbage collector
132class GC {
133 friend class ASTNode;
134 friend class ASTVec;
135 friend class ASTChunk;
136 friend class KeepAlive;
137 friend class WeakRef;
138 friend class ASTNodeWeakMap;
139
140private:
141 class Heap;
142 /// The memory controlled by the collector
143 Heap* _heap;
144 /// Count how many locks are currently active
145 unsigned int _lock_count;
146 /// Timeout in milliseconds
147 unsigned long long int _timeout;
148 /// Counter for timeout
149 int _timeout_counter;
150 /// Timer for timeout
151 Timer _timeout_timer;
152 /// Return thread-local GC object
153 static GC*& gc(void);
154 /// Constructor
155 GC(void);
156
157 /// Allocate garbage collected memory
158 void* alloc(size_t size);
159
160 static void addKeepAlive(KeepAlive* e);
161 static void removeKeepAlive(KeepAlive* e);
162 static void addWeakRef(WeakRef* e);
163 static void removeWeakRef(WeakRef* e);
164 static void addNodeWeakMap(ASTNodeWeakMap* m);
165 static void removeNodeWeakMap(ASTNodeWeakMap* m);
166
167public:
168 /// Acquire garbage collector lock for this thread
169 static void lock(void);
170 /// Release garbage collector lock for this thread
171 static void unlock(void);
172 /// Manually trigger garbage collector (must be unlocked)
173 static void trigger(void);
174 /// Test if garbage collector is locked
175 static bool locked(void);
176 /// Add model \a m to root set
177 static void add(Model* m);
178 /// Remove model \a m from root set
179 static void remove(Model* m);
180
181 /// Put a mark on the trail
182 static void mark(void);
183 /// Add a trail entry
184 static void trail(Expression**, Expression*);
185 /// Untrail to previous mark
186 static void untrail(void);
187
188 /// Set timeout of \a t milliseconds, 0 means disable
189 static void setTimeout(unsigned long long int t);
190
191 /// Return maximum allocated memory (high water mark)
192 static size_t maxMem(void);
193};
194
195/// Automatic garbage collection lock
196class GCLock {
197public:
198 /// Acquire lock
199 GCLock(void);
200 /// Release lock upon destruction
201 ~GCLock(void);
202};
203
204/// Expression wrapper that is a member of the root set
205class KeepAlive {
206 friend class GC;
207
208private:
209 Expression* _e;
210 KeepAlive* _p;
211 KeepAlive* _n;
212
213public:
214 KeepAlive(Expression* e = NULL);
215 ~KeepAlive(void);
216 KeepAlive(const KeepAlive& e);
217 KeepAlive& operator=(const KeepAlive& e);
218 Expression* operator()(void) { return _e; }
219 Expression* operator()(void) const { return _e; }
220 KeepAlive* next(void) const { return _n; }
221};
222
223/// Expression wrapper that is a member of the root set
224class WeakRef {
225 friend class GC;
226
227private:
228 Expression* _e;
229 WeakRef* _p;
230 WeakRef* _n;
231 bool _valid;
232
233public:
234 WeakRef(Expression* e = NULL);
235 ~WeakRef(void);
236 WeakRef(const WeakRef& e);
237 WeakRef& operator=(const WeakRef& e);
238 Expression* operator()(void) { return _valid ? _e : NULL; }
239 Expression* operator()(void) const { return _valid ? _e : NULL; }
240 WeakRef* next(void) const { return _n; }
241};
242
243class ASTNodeWeakMap {
244 friend class GC;
245
246private:
247 ASTNodeWeakMap(const WeakRef& e);
248 ASTNodeWeakMap& operator=(const ASTNodeWeakMap& e);
249
250protected:
251 typedef std::unordered_map<ASTNode*, ASTNode*> NodeMap;
252 ASTNodeWeakMap* _p;
253 ASTNodeWeakMap* _n;
254 ASTNodeWeakMap* next(void) const { return _n; }
255 NodeMap _m;
256
257public:
258 ASTNodeWeakMap(void);
259 ~ASTNodeWeakMap(void);
260 void insert(ASTNode* n0, ASTNode* n1);
261 ASTNode* find(ASTNode* n);
262 void clear() { _m.clear(); }
263};
264} // namespace MiniZinc
265
266#endif