@@ -97,12 +97,144 @@ vstring g_qsortKey; /* Used by qsortStringCmp; pointer only, do not deallocate *
97
97
long poolAbsoluteMax = 1000000 ; /* Pools will be purged when this is reached */
98
98
long poolTotalFree = 0 ; /* Total amount of free space allocated in pool */
99
99
/*E*/ long i1 ,j1_ ,k1 ; /* 'j1' is a built-in function */
100
+ /*!
101
+ * \var void** memUsedPool
102
+ * \brief pointer to the pool of fragmented memory blocks
103
+ * Memory fragmentation is kept simple in Metamath. If a block contains both
104
+ * consumed and free space, all of the free space is at the end. Fragmented
105
+ * blocks with free space are kept in the used block array, that memUsedPool
106
+ * points to. For the notion of block, suballocator see \a memFreePool. This
107
+ * scheme supports in particular stack like memory, where data is pushed at and
108
+ * popped off the end.
109
+ *
110
+ * The used blocks array does initially not exist. This is indicated by a
111
+ * null value. Once this array is needed, space for it it is allocated from
112
+ * the system.
113
+ *
114
+ * The used block array may only be partially occupied, in which case elements
115
+ * at the end of the array are unused. Its current usage is given by
116
+ * \a memUsedPoolSize. Its current size including unused elements, is given by
117
+ * \a memUsedPoolMax.
118
+ *
119
+ * \invariant Each block in the used blocks array has its index noted in its
120
+ * hidden header, for backward reference.
121
+ *
122
+ * \attention Desite the name of this variable fully occupied blocks are never
123
+ * kept in the used block array.
124
+ */
100
125
void * * memUsedPool = NULL ;
126
+ /*!
127
+ * \var long memUsedPoolSize
128
+ * \attention this is the number of individual blocks, not the accumulated
129
+ * (unused) bytes contained.
130
+ *
131
+ * The Metamath suballocator holds fragmented blocks in a used block array.
132
+ * The number of occupied entries is kept in this variable. Elements at the
133
+ * end of the used block array may be unused. The fill size is given by this
134
+ * variable. For further information see \a memUsedPool.
135
+ *
136
+ * \invariant memUsedPoolSize <= \a memUsedPoolMax.
137
+ */
101
138
long memUsedPoolSize = 0 ; /* Current # of partially filled arrays in use */
139
+ /*!
140
+ * \var long memUsedPoolMax
141
+ * \attention this is the number of individual free blocks, not the accumulated
142
+ * bytes contained.
143
+ *
144
+ * The Metamath suballocator holds fragmented blocks in the used block
145
+ * array. This array may only partially be occupied. Its total capacity is
146
+ * kept in this variable. For further information see \a memUsedPool.
147
+ *
148
+ * This variable may grow during a reallocation process.
149
+ *
150
+ * \invariant (memUsedPoolMax > 0) == (\a memUsedPool != 0)
151
+ */
102
152
long memUsedPoolMax = 0 ; /* Maximum # of entries in 'in use' table (grows
103
153
as nec.) */
154
+ /*!
155
+ * \var void** memFreePool
156
+ * \brief pointer to the pool of completely free memory blocks
157
+ *
158
+ * **suballocator**
159
+ *
160
+ * Metamath does not free memory by returning it to the operating system again.
161
+ * Instead it has a suballocator that marks them as unused. During execution
162
+ * chunks of memory become unused, either completely, or through fragmentation.
163
+ * The suballocator keeps track of these by entering them either into a free
164
+ * block array, or into a used block array. The idea behind this suballocation
165
+ * scheme is to reduce the number of system malloc and alloc calls.
166
+ *
167
+ * Although the suballocator tries to avoid returning memory to the system, it
168
+ * can do so under extreme memory constraints.
169
+ *
170
+ * The suballocator is initially neither equipped with a free block array,
171
+ * pointed to by memFreePool, or a used block array, see \a memUsedPool. Both
172
+ * are null then, but once memory is returned to the suballocator again, it
173
+ * allocates some space for the needed array.
174
+ *
175
+ * The free block array contains totally unused blocks. The array may only
176
+ * partially be occupied, in which case The elements at the end are the unused
177
+ * ones. Its current fill size is given by \a memFreePoolSize. Its capacity
178
+ * is given by \a memFreePoolMax.
179
+ *
180
+ * Fragmented blocks are kept in a separate \a memUsedPool. The suballocator
181
+ * never tracks fully used blocks.
182
+ *
183
+ * **block of memory**
184
+ *
185
+ * Each block used by the suballocater is formally treated as an array of
186
+ * pointer (void*). It is divided into an administrative header, followed by
187
+ * elements reserved for application data. The header is assigned elements -3
188
+ * to -1 in the formal array, so that application data starts with element 0.
189
+ * A pointer to the block always refers to element 0, so the header appears
190
+ * somewhat hidden.
191
+ *
192
+ * The header elements are reinterpreted as long integer. The values support
193
+ * a stack, where data is pushed at and popped off the end during the course of
194
+ * execution. The semantics of the header elements are:
195
+ *
196
+ * offset -1:\n
197
+ * is the current size of the stack (in bytes, not elements!),
198
+ * without header data. When interpreted as an offset into the stack, it
199
+ * references the first element past the top of the stack.
200
+ *
201
+ * offset -2:\n
202
+ * the allocated size of the array, in bytes, not counting the
203
+ * header. When used as a stack, it marks the limit where the stack
204
+ * overflows.
205
+ *
206
+ * offset -3:\n
207
+ * If this block has free space at the end (is fragmented), then it contains
208
+ * its index in the used blocks array, see \a memUsedPool. A value of -1
209
+ * indicates it has no free space left, hence is not held in this pool.
210
+ */
104
211
void * * memFreePool = NULL ;
212
+ /*!
213
+ * \var long memFreePoolSize
214
+ * \attention this is the number of individual free blocks, not the accumulated
215
+ * bytes contained.
216
+ *
217
+ * The Metamath suballocator holds free blocks in a free block array. The
218
+ * number of occupied entries is kept in this variable. Elements at the end of
219
+ * the free block array may not be used. The fill size is given by this
220
+ * variable. For further information see \a memFreePool.
221
+ *
222
+ * \invariant memFreePoolSize <= \a memFreePoolMax.
223
+ */
105
224
long memFreePoolSize = 0 ; /* Current # of available, allocated arrays */
225
+ /*!
226
+ * \var long memFreePoolMax
227
+ * \attention this is the number of individual free blocks, not the accumulated
228
+ * bytes contained.
229
+ *
230
+ * The Metamath suballocator holds free blocks in a free block array. It may
231
+ * only partially be occupied. Its total capacity is kept in this variable. For
232
+ * further information see \a memFreePool.
233
+ *
234
+ * This variable may grow during a reallocation process.
235
+ *
236
+ * \invariant (memFreePoolMax > 0) == (\a memFreePool != 0)
237
+ */
106
238
long memFreePoolMax = 0 ; /* Maximum # of entries in 'free' table (grows
107
239
as nec.) */
108
240
0 commit comments