Macaulay2 Engine
Loading...
Searching...
No Matches
mem.hpp
Go to the documentation of this file.
1// (c) 1995 Michael E. Stillman
2#ifndef _mem_hh_
3#define _mem_hh_
4
34
35#include <cassert>
36#include "newdelete.hpp"
37// for spinLock:
38#include "../system/mutex.h"
39class buffer;
40
41// 2*2^NDOUBLES = Largest stash size.
42const int NDOUBLES = 25;
43// const int slab_size = 2040;
44const int slab_size = 2032;
45// const int slab_size = 262134;
46const char bad_pattern = '\245';
47const int word_size =
48 static_cast<int>(sizeof(void *)); // g++-4.8.0 complains without the cast.
49
50extern size_t engine_allocated;
51extern size_t engine_highwater;
52
53// Each type should include something like the following:
54#if 0
55// // in .hpp file:
56// friend void i_stashes();
57// static stash *mystash;
58// void *operator new(size_t size) { return mystash->new_elem(); }
59// void operator delete(void *p) { mystash->delete_elem(p); }
60// // in .cc file
61// stash *matrix_rec::mystash;
62// // in object.cc in i_stashes:
63// matrix_rec::mystash = new stash("matrix", sizeof(matrix_rec));
64#endif
65
66class slab : public our_new_delete
67{
68 friend class stash;
69 static int n_slabs;
71 char s[slab_size];
72
73 slab() : next(nullptr) { n_slabs++; }
74 ~slab() { n_slabs--; }
75};
76
77class stash : public our_new_delete
78{
79 public:
80 stash(const char *s, size_t len);
81 ~stash();
82
83 void *new_elem();
84 void delete_elem(void *p);
85
86 void text_out(buffer &o) const; // Display statistics about this stash.
87 static void stats(buffer &o);
88
89 private:
90 const char *name;
91 size_t element_size; // In bytes
92 // n_per_slab provides the number of elements of element_size in each slab.
93 // If 0, elements are new'ed directly.
95
96 // List of slabs
97 // Uses slab::next to indicate next element in list
98 // This will be 0 if n_per_slab is 0.
100
101 // Free list for this stash.
102 // Currently: if n_per_slab is 0, then elements are deleted'd directly.
103 // Note that this essentially a list of the elements from various slabs.
104 // a pointer to the next element in the list is in the first sizeof(void*)
105 // bytes.
107
108 // statistics
109 size_t n_allocs;
110 size_t n_inuse;
111 size_t highwater;
112 size_t n_frees;
113
114 // private routines
115 void chop_slab();
116
117 // spinlock for modifying member lists
119};
120
121inline void *stash::new_elem()
122// Allocate space for an object from this stash.
123{
124 return newarray_clear(char, element_size);
125 acquireSpinLock(&list_spinlock);
126 n_allocs++;
127 n_inuse++;
129 if (free_list == nullptr)
130 {
131 if (n_per_slab == 0)
132 {
133 void *result = newarray_clear(char, element_size);
134 // allocated_amount += element_size;
135 releaseSpinLock(&list_spinlock);
136 return result;
137 }
138 chop_slab();
139 }
140 assert(free_list != NULL); // chop_slab should not let this happen.
141 void *result = free_list;
142 free_list = *(reinterpret_cast<void **>(free_list));
143 releaseSpinLock(&list_spinlock);
144 return result;
145}
146
147inline void stash::delete_elem(void *p)
148// Delete the object 'p', placing it on the free list for this stash.
149{
150 if (p == nullptr) return;
151 freemem(p);
152 return;
153 // if (trace_bad_deletes)
154 // {
155 // for (void *q = free_list; q != NULL; q = *(reinterpret_cast<void
156 // **>(q)))
157 // if (q == p)
158 // assert(0);
159 // }
160
161 n_inuse--;
162 n_frees++;
163 if (n_per_slab == 0)
164 {
165 // deleted_amount += element_size;
166 char *q = reinterpret_cast<char *>(p);
167 freemem(q);
168 return;
169 }
170 acquireSpinLock(&list_spinlock);
171 memset(p, 0, element_size); // we clear this element because it's free, and
172 // it may contain words that look like pointers
173 // to gc
174 *(reinterpret_cast<void **>(p)) = free_list;
175 free_list = p;
176 releaseSpinLock(&list_spinlock);
177}
178
183
185{
186 doubling_stash(const doubling_stash &) { assert(0); }
187 void operator=(const doubling_stash &) { assert(0); }
188 public:
191 // Get a new element of given size. Essentially this just dispatches to the
192 // correct stash
193 void *new_elem(size_t size);
194 // Delete an element of a given size. Essentially this just deletes an
195 // element
196 void delete_elem(void *p);
197 // return the allocated size.
198 size_t allocated_size(void *p);
199
200 private:
203};
204
205extern doubling_stash *doubles;
206
207static inline void engine_alloc(size_t n)
208{
209 engine_allocated += n;
211}
212
213static inline void engine_dealloc(size_t n) { engine_allocated -= n; }
214#endif
215
216// Local Variables:
217// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
218// indent-tabs-mode: nil
219// End:
void * new_elem(size_t size)
Definition mem.cpp:144
void operator=(const doubling_stash &)
Definition mem.hpp:187
doubling_stash(const doubling_stash &)
Definition mem.hpp:186
size_t double_size[NDOUBLES]
Definition mem.hpp:202
stash * doubles[NDOUBLES]
Definition mem.hpp:201
void delete_elem(void *p)
Definition mem.cpp:157
~doubling_stash()
Definition mem.cpp:134
size_t allocated_size(void *p)
Definition mem.cpp:165
slab * next
Definition mem.hpp:70
static int n_slabs
Definition mem.hpp:69
char s[slab_size]
Definition mem.hpp:71
~slab()
Definition mem.hpp:74
slab()
Definition mem.hpp:73
friend class stash
Definition mem.hpp:68
Definition mem.hpp:67
~stash()
Definition mem.cpp:35
int n_per_slab
Definition mem.hpp:94
const char * name
Definition mem.hpp:90
stash(const char *s, size_t len)
Definition mem.cpp:16
static void stats(buffer &o)
Definition mem.cpp:93
slab * slabs
Definition mem.hpp:99
void chop_slab()
Definition mem.cpp:48
void * free_list
Definition mem.hpp:106
void * new_elem()
Definition mem.hpp:121
size_t highwater
Definition mem.hpp:111
spinLock list_spinlock
Definition mem.hpp:118
void text_out(buffer &o) const
Definition mem.cpp:70
void delete_elem(void *p)
Definition mem.hpp:147
size_t n_allocs
Definition mem.hpp:109
size_t n_frees
Definition mem.hpp:112
size_t element_size
Definition mem.hpp:91
size_t n_inuse
Definition mem.hpp:110
Definition mem.hpp:78
int p
void freemem(void *s)
Definition m2-mem.cpp:103
void size_t s
Definition m2-mem.cpp:271
VALGRIND_MAKE_MEM_DEFINED & result(result)
doubling_stash * doubles
Definition mem.cpp:14
size_t engine_allocated
Definition mem.cpp:89
size_t engine_highwater
Definition mem.cpp:91
static void engine_dealloc(size_t n)
Definition mem.hpp:213
const int slab_size
Definition mem.hpp:44
const int NDOUBLES
Definition mem.hpp:42
static void engine_alloc(size_t n)
Definition mem.hpp:207
const int word_size
Definition mem.hpp:47
const char bad_pattern
Definition mem.hpp:46
#define newarray_clear(T, len)
Definition newdelete.hpp:83
our_new_delete — per-class opt-in routing of new / delete through bdwgc.