Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
6.4 kB · 266 lines
C++
at develop
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/* * Main authors: * Guido Tack <guido.tack@monash.edu> */
/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef __MINIZINC_GC_HH__#define __MINIZINC_GC_HH__
#include <minizinc/config.hh>#include <minizinc/timer.hh>
#include <cassert>#include <cstdlib>#include <new>#include <unordered_map>
namespace MiniZinc {
/** * \brief Base class for abstract syntax tree nodes */class ASTNode { friend class GC;
protected: /// Mark for garbage collection mutable unsigned int _gc_mark : 1; /// Id of the node unsigned int _id : 7; /// Secondary id unsigned int _sec_id : 7; /// Flag unsigned int _flag_1 : 1; /// Flag unsigned int _flag_2 : 1; /// Flag unsigned int _flag_3 : 1; /// Flag unsigned int _flag_4 : 1;
enum BaseNodes { NID_FL, NID_CHUNK, NID_VEC, NID_END = NID_VEC };
/// Constructor ASTNode(unsigned int id) : _gc_mark(0), _id(id), _flag_1(0), _flag_2(0), _flag_3(0), _flag_4(0) {}
public: /// Allocate node void* operator new(size_t size);
/// Placement-new void* operator new(size_t, void* n) throw() { return n; }
/// Delete node (no-op) void operator delete(void*, size_t) throw() {} /// Delete node (no-op) void operator delete(void*, void*) throw() {}
/// Delete node (no-op) void operator delete(void*) throw() {}
/// Return state of first user-defined flag bool user_flag0(void) const { return _flag_3; } /// Set state of first user-defined flag void user_flag0(bool b) { _flag_3 = b; } /// Return state of second user-defined flag bool user_flag1(void) const { return _flag_4; } /// Set state of second user-defined flag void user_flag1(bool b) { _flag_4 = b; }};
/** * \brief Base class for unstructured garbage collected data */class ASTChunk : public ASTNode { friend class GC;
protected: /// Allocated size size_t _size; /// Storage char _data[4]; /// Constructor ASTChunk(size_t size); /// Actual size of object in memory size_t memsize(void) const { size_t s = sizeof(ASTChunk) + (_size <= 4 ? 0 : _size - 4) * sizeof(char); s += ((8 - (s & 7)) & 7); return s; } /// Allocate raw memory static void* alloc(size_t size);};
/** * \brief Base class for structured garbage collected data */class ASTVec : public ASTNode { friend class GC;
protected: /// Allocated size size_t _size; /// Storage void* _data[2]; /// Constructor ASTVec(size_t size); /// Actual size of object in memory size_t memsize(void) const { size_t s = sizeof(ASTVec) + (_size <= 2 ? 0 : _size - 2) * sizeof(void*); s += ((8 - (s & 7)) & 7); return s; } /// Allocate raw memory static void* alloc(size_t size);};
class Model;class Expression;
class KeepAlive;class WeakRef;
class ASTNodeWeakMap;
/// Garbage collectorclass GC { friend class ASTNode; friend class ASTVec; friend class ASTChunk; friend class KeepAlive; friend class WeakRef; friend class ASTNodeWeakMap;
private: class Heap; /// The memory controlled by the collector Heap* _heap; /// Count how many locks are currently active unsigned int _lock_count; /// Timeout in milliseconds unsigned long long int _timeout; /// Counter for timeout int _timeout_counter; /// Timer for timeout Timer _timeout_timer; /// Return thread-local GC object static GC*& gc(void); /// Constructor GC(void);
/// Allocate garbage collected memory void* alloc(size_t size);
static void addKeepAlive(KeepAlive* e); static void removeKeepAlive(KeepAlive* e); static void addWeakRef(WeakRef* e); static void removeWeakRef(WeakRef* e); static void addNodeWeakMap(ASTNodeWeakMap* m); static void removeNodeWeakMap(ASTNodeWeakMap* m);
public: /// Acquire garbage collector lock for this thread static void lock(void); /// Release garbage collector lock for this thread static void unlock(void); /// Manually trigger garbage collector (must be unlocked) static void trigger(void); /// Test if garbage collector is locked static bool locked(void); /// Add model \a m to root set static void add(Model* m); /// Remove model \a m from root set static void remove(Model* m);
/// Put a mark on the trail static void mark(void); /// Add a trail entry static void trail(Expression**, Expression*); /// Untrail to previous mark static void untrail(void);
/// Set timeout of \a t milliseconds, 0 means disable static void setTimeout(unsigned long long int t);
/// Return maximum allocated memory (high water mark) static size_t maxMem(void);};
/// Automatic garbage collection lockclass GCLock {public: /// Acquire lock GCLock(void); /// Release lock upon destruction ~GCLock(void);};
/// Expression wrapper that is a member of the root setclass KeepAlive { friend class GC;
private: Expression* _e; KeepAlive* _p; KeepAlive* _n;
public: KeepAlive(Expression* e = NULL); ~KeepAlive(void); KeepAlive(const KeepAlive& e); KeepAlive& operator=(const KeepAlive& e); Expression* operator()(void) { return _e; } Expression* operator()(void) const { return _e; } KeepAlive* next(void) const { return _n; }};
/// Expression wrapper that is a member of the root setclass WeakRef { friend class GC;
private: Expression* _e; WeakRef* _p; WeakRef* _n; bool _valid;
public: WeakRef(Expression* e = NULL); ~WeakRef(void); WeakRef(const WeakRef& e); WeakRef& operator=(const WeakRef& e); Expression* operator()(void) { return _valid ? _e : NULL; } Expression* operator()(void) const { return _valid ? _e : NULL; } WeakRef* next(void) const { return _n; }};
class ASTNodeWeakMap { friend class GC;
private: ASTNodeWeakMap(const WeakRef& e); ASTNodeWeakMap& operator=(const ASTNodeWeakMap& e);
protected: typedef std::unordered_map<ASTNode*, ASTNode*> NodeMap; ASTNodeWeakMap* _p; ASTNodeWeakMap* _n; ASTNodeWeakMap* next(void) const { return _n; } NodeMap _m;
public: ASTNodeWeakMap(void); ~ASTNodeWeakMap(void); void insert(ASTNode* n0, ASTNode* n1); ASTNode* find(ASTNode* n); void clear() { _m.clear(); }};} // namespace MiniZinc
#endif