Macaulay2 Engine
Loading...
Searching...
No Matches
mem.cpp
Go to the documentation of this file.
1// (c) 1995 Michael E. Stillman
2
3#include "mem.hpp"
4#include "text-io.hpp"
5
6static int allocated_amount = 0;
7static int deleted_amount = 0;
8
9int slab::n_slabs = 0;
10
11// Array of stashes of 2^n powers.
12// This looks thread unsafe, but is actually thread safe because it is only
13// initialized once when the engine is setup.
15
16stash::stash(const char *s, size_t len)
17 : name(s),
18 slabs(nullptr),
19 free_list(nullptr),
20 n_allocs(0),
21 n_inuse(0),
22 highwater(0),
23 n_frees(0)
24{
25 // Make sure element_size is a multiple of the word size.
26 if (len <= 0) len = word_size;
27 element_size = word_size * ((len + word_size - 1) / word_size);
28 // number of elements per slab is the slab size divided by the element size
29 // rounded down.
30 n_per_slab = static_cast<int>((slab_size - sizeof(void *)) / element_size);
31 n_per_slab = 0;
32 initializeSpinLock(&list_spinlock);
33}
34
36{
37 acquireSpinLock(&list_spinlock);
38 while (slabs != nullptr)
39 {
40 slab *p = slabs;
41 slabs = slabs->next;
42 GC_FREE(p); // this dramatically improves our memory usage
43 // TODO: comment out all GC_FREE()s!?
44 // printf("removed %p\n", p);
45 }
46}
47
49{
50 // grab a new slab, and chop it into element_size pieces, placing them
51 // onto the free list.
52
53 slab *new_slab = new slab;
54 new_slab->next = slabs;
55 slabs = new_slab;
56
57 // Time to chop it up.
58
59 char *prev = nullptr;
60 char *current = slabs->s;
61 for (int i = 0; i < n_per_slab; i++)
62 {
63 *(reinterpret_cast<char **>(current)) = prev;
64 prev = current;
65 current += element_size;
66 }
67 free_list = prev;
68}
69
70void stash::text_out(buffer &o) const
71// Display statistics about this stash.
72{
73 const int N = 200;
74 char s[N];
75 snprintf(s, N,
76 "%16s %9dk %9dk %10zd %10zu %10zu %10zu %10zu%s",
77 name,
78 static_cast<int>((element_size * highwater + 1023) / 1024),
79 static_cast<int>((element_size * n_inuse + 1023) / 1024),
82 n_inuse,
84 n_frees,
85 newline);
86 o << s;
87}
88// TODO: MAKE THREADSAFE -- For statistics purposes only
90// TODO: MAKE THREADSAFE -- For statistics purposes only
92
94{
95 // o << "total space allocated from system = " << engine_allocated << endl;
96 // o << "number of global delete's = " << engine_dealloc << endl;
97 int n = (slab::n_slabs * slab_size) / 1024 +
99 o << "size of each slab = " << sizeof(slab) << newline;
100 o << "total engine stash space allocated = " << n << "k" << newline;
101
102 if (n > 0)
103 {
104 const int N = 200;
105 char s[N];
106 snprintf(s, N,
107 "%16s %10s %10s %10s %10s %10s %10s %10s%s",
108 "stash",
109 "k total",
110 "k in use",
111 "size",
112 "nalloc",
113 "inuse",
114 "highwater",
115 "freed",
116 newline);
117 o << s;
118 }
119}
120
121//--------- Doubling Stashes -----------------------------------------
122
124{
125 int size = 2;
126 for (int i = 0; i < NDOUBLES; i++)
127 {
128 size *= 2;
129 doubles[i] = new stash("double", sizeof(int) * (size + 1));
130 double_size[i] = sizeof(int) * size;
131 }
132}
133
135{
136 for (int i = 0; i < NDOUBLES; i++)
137 {
138 if (doubles[i] != nullptr)
139 emit("internal warning -- deleting a double stash");
140 freemem(doubles[i]);
141 }
142}
143
144void *doubling_stash::new_elem(size_t size)
145// size is in chars
146{
147 // first find the correct stash
148 int st = 0;
149 while (double_size[st] < size) st++;
150
151 int *result = reinterpret_cast<int *>(doubles[st]->new_elem());
152 result[0] = st;
153 result++;
154 return reinterpret_cast<void *>(result);
155}
156
158{
159 if (p == nullptr) return;
160 int *q = (int *)p;
161 q--;
162 doubles[*q]->delete_elem(q);
163}
164
166{
167 int *q = reinterpret_cast<int *>(p);
168 assert(q[-1] >= 0);
169 assert(q[-1] <= NDOUBLES);
170 return double_size[q[-1]];
171}
172
173// Local Variables:
174// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
175// indent-tabs-mode: nil
176// End:
void * new_elem(size_t size)
Definition mem.cpp:144
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
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
size_t highwater
Definition mem.hpp:111
spinLock list_spinlock
Definition mem.hpp:118
void text_out(buffer &o) const
Definition mem.cpp:70
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)
char newline[]
Definition m2-types.cpp:49
doubling_stash * doubles
Definition mem.cpp:14
static int deleted_amount
Definition mem.cpp:7
size_t engine_allocated
Definition mem.cpp:89
static int allocated_amount
Definition mem.cpp:6
size_t engine_highwater
Definition mem.cpp:91
const int slab_size
Definition mem.hpp:44
const int NDOUBLES
Definition mem.hpp:42
const int word_size
Definition mem.hpp:47
stash and doubling_stash — legacy size-class allocator interfaces, now stubbed to plain GC allocation...
void emit(const char *s)
Definition text-io.cpp:41
Text-formatting helpers layered on buffer: bignum print, line wrapping, M2_gbTrace-gated emit.