source: git/Singular/mmheap.c @ 3551b68

spielwiese
Last change on this file since 3551b68 was 3551b68, checked in by Hans Schönemann <hannes@…>, 25 years ago
*hannes: 8k-page change git-svn-id: file:///usr/local/Singular/svn/trunk@3230 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 8.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: mmheap.c,v 1.9 1999-07-05 14:13:16 Singular Exp $ */
5
6#include "mod2.h"
7
8#include <stdio.h>
9
10#include "mmheap.h"
11#include "mmpage.h"
12#include "mmprivate.h"
13#include "mmemory.h"
14
15
16
17memHeap mmCreateHeap(size_t size)
18{
19  memHeap heap = (memHeap) Alloc(sizeof(struct sip_memHeap));
20  mmInitHeap(heap, size);
21  return heap;
22}
23
24void mmDestroyHeap(memHeap *heap)
25{
26  mmClearHeap(*heap);
27  Free(*heap, sizeof(struct sip_memHeap));
28  *heap = NULL;
29}
30 
31void mmInitHeap(memHeap heap, size_t size)
32{
33  heap->current = NULL;
34  heap->pages = NULL;
35  heap->size = size;
36}
37
38void mmClearHeap(memHeap heap)
39{
40  memHeapPage page, next_page;
41
42  mmCheckHeap(heap);
43 
44  page = heap->pages;
45 
46  while(page != NULL)
47  {
48    next_page = page->next;
49    mmFreePage((void*) page);
50    page = next_page;
51  }
52  heap->current = NULL;
53  heap->pages = NULL;
54}
55
56void mmAllocNewHeapPage(memHeap heap)
57{
58  memHeapPage newpage = (memHeapPage) mmGetPage();
59  int i = 1, n = SIZE_OF_HEAP_PAGE / heap->size;
60  void* tmp;
61  assume(heap != NULL && newpage != NULL);
62  assume(mmIsAddrPageAligned((void*) newpage));
63
64  newpage->next = heap->pages;
65  newpage->counter = 0;
66  heap->pages = newpage;
67 
68  heap->current = (void*) (((char*)newpage) + SIZE_OF_HEAP_PAGE_HEADER);
69  tmp = heap->current;
70
71  while (i < n)
72  {
73    *((void**)tmp) = (void*) (((char*)tmp) + heap->size);
74    tmp = *((void**)tmp);
75    i++;
76  }
77  *((void**)tmp) = NULL;
78#ifdef MDEBUG
79  mmDBInitNewHeapPage(heap);
80#endif
81}
82
83void mmMergeHeap(memHeap into, memHeap what)
84{
85  void* last;
86 
87  assume(into != NULL && what != NULL && into->size == what->size);
88
89  if (into == what) return;
90#ifdef MDEBUG
91  mmDBSetHeapsOfBlocks(what, into);
92#endif 
93
94  if (what->pages != NULL)
95  {
96    last = mmListLast(what->pages);
97    *((void**) last) = into->pages;
98    into->pages = what->pages;
99
100    if (what->current != NULL)
101    {
102      last = mmListLast(what->current);
103      *((void**) last) = into->current;
104      into->current = what->current;
105    }
106  }
107 
108  what->pages = NULL;
109  what->current = NULL;
110
111  mmCheckHeap(into);
112}
113
114#ifdef HAVE_PAGE_ALIGNMENT
115#if 1
116void mmRemoveHeapBlocksOfPage(memHeap heap, memHeapPage hpage)
117{
118  void *prev = NULL, *new_current = NULL, *current = heap->current;
119  int nblocks = SIZE_OF_HEAP_PAGE / heap->size;
120 
121#ifdef HAVE_ASSUME
122  int l = mmListLength(current);
123#endif
124
125  while (mmIsAddrOnPage(current, hpage))
126  {
127#ifdef MDEBUG
128    mmTakeOutDBMCB((DBMCB*) current);
129#endif   
130    if (--(nblocks) == 0) 
131    {
132      new_current = *((void**) current);
133      goto Finish;
134    }
135    current = *((void**) current);
136  }
137 
138  new_current = current;
139 
140  while (1)
141  {
142    assume(mmListLength(new_current) == 
143           l - (SIZE_OF_HEAP_PAGE / heap->size) + nblocks);
144    prev = current;
145    current = *((void**) current);
146   
147    while (! mmIsAddrOnPage(current, hpage))
148    {
149      prev = current;
150      current = *((void**) current);
151    }
152   
153#ifdef MDEBUG
154    mmTakeOutDBMCB((DBMCB*) current);
155#endif   
156    if (--(nblocks) == 0) goto Finish;
157
158    current = *((void**) current);
159    while (mmIsAddrOnPage(current, hpage))
160    {
161#ifdef MDEBUG
162      mmTakeOutDBMCB((DBMCB*) current);
163#endif   
164      if (--(nblocks) == 0) goto Finish;
165      current = *((void**) current);
166    }
167    *((void**) prev) = current;
168  }
169
170  Finish:
171  heap->current = new_current;
172  if (prev != NULL)
173    *((void**) prev) = *((void**) current);
174  heap->pages = mmRemoveFromList(heap->pages, hpage);
175  mmFreePage(hpage);
176  assume(mmListLength(heap->current) == l -  (SIZE_OF_HEAP_PAGE / heap->size));
177  mmCheckHeap(heap);
178}
179#else
180void mmRemoveHeapBlocksOfPage(memHeap heap, memHeapPage hpage)
181{}
182#endif
183
184#ifdef HAVE_AUTOMATIC_HEAP_COLLECTION
185void _mmCleanHeap(memHeap heap)
186#else
187void mmCleanHeap(memHeap heap)
188#endif
189{
190  memHeapPage hpage = heap->pages;
191  void* current = heap->current;
192  int nblocks = SIZE_OF_HEAP_PAGE / (heap->size);
193 
194  assume(heap != NULL);
195  mmCheckHeap(heap);
196
197  while (hpage != NULL)
198  {
199    hpage->counter = nblocks;
200    hpage = hpage->next;
201  }
202
203  while (current != NULL)
204  {
205    hpage = mmGetHeapPageOfAddr(current);
206    current = *((void**) current);
207    if (--(hpage->counter) == 0)
208      mmRemoveHeapBlocksOfPage(heap, hpage);
209  }
210
211}
212#else
213void mmCleanHeap(memHeap heap)
214{
215  assume(heap != NULL);
216  mmCheckHeap(heap);
217 
218  if (mmListLength(heap->current) == 
219      mmListLength(heap->pages) * (SIZE_OF_HEAP_PAGE / heap->size))
220    mmClearHeap(heap);
221  mmCheckHeap(heap);
222}
223#endif
224
225#ifdef HEAP_DEBUG
226int mm_HEAP_DEBUG = HEAP_DEBUG;
227
228static int mmPrintHeapError(char* msg, void* addr, memHeap heap,
229                            const char* fn, int l)
230{
231  fprintf(stderr, "\n%s: occured for addr:%p heap:%p of size %d in %s:%d\n",
232          msg, addr, (void*) heap, heap->size, fn, l);
233  assume(0);
234  return 0;
235}
236
237static int mmDebugCheckSingleHeapAddr(void* addr, memHeap heap,
238                                      const char* fn, int l)
239{
240  void* page;
241  memHeapPage hpage;
242 
243  if (heap == NULL)
244  {
245    fprintf(stderr, "NULL heap in %s:%d\n", fn, l);
246    assume(0);
247    return 0;
248  }
249
250  if (addr == NULL)
251    return mmPrintHeapError("NULL addr", addr, heap, fn, l);
252
253  if (! mmIsNotAddrOnFreePage(addr))
254    return mmPrintHeapError("Addr on freed page", addr, heap, fn, l);
255 
256#ifdef HAVE_PAGE_ALIGNMENT
257  page = mmGetPageOfAddr(addr);
258 
259  if (! mmIsAddrOnList(page, heap->pages))
260    return mmPrintHeapError("addr not on heap page", addr, heap, fn, l);
261
262  if ( (((long) (((char*) addr) - ((char*) page + SIZE_OF_HEAP_PAGE_HEADER)))
263        % heap->size) != 0)
264    return mmPrintHeapError("addr unaligned within heap", addr, heap, fn, l);
265  hpage = (memHeapPage) page;
266#ifdef HAVE_AUTOMATIC_HEAP_COLLECTION
267  if (hpage->counter < 1)
268    return  mmPrintHeapError("heap counter too small", addr, heap, fn, l);
269#else
270  if (hpage->counter < 0)
271    return  mmPrintHeapError("heap counter too small", addr, heap, fn, l);
272#endif
273#endif
274  return 1;
275}
276
277
278static int mmDebugCheckHeapAddrContainment(void* addr, memHeap heap, int flag,
279                                           const char* fn, int l)
280{
281  if (flag == MM_HEAP_ADDR_FREE_FLAG)
282  {
283    if (! mmIsAddrOnList(addr, heap->current))
284      return mmPrintHeapError("addr not on heap free list",
285                              addr, heap, fn, l);
286  }
287  else if (flag == MM_HEAP_ADDR_USED_FLAG)
288  {
289    if (mmIsAddrOnList(addr, heap->current))
290      return mmPrintHeapError("used addr on heap free list",
291                              addr, heap, fn, l);
292  }
293  return 1;
294}
295
296int mmDebugCheckHeap(memHeap heap, const char* fn, int l)
297{
298  void* p;
299 
300  if (mmListHasCycle(heap->pages))
301    return mmPrintHeapError("heap pages list has cycles",
302                            NULL, heap, fn, l);
303
304  if (mmListHasCycle(heap->current))
305    return mmPrintHeapError("heap current list has cycles",
306                            NULL, heap, fn, l);
307   
308  p = heap->current;
309  while (p != NULL)
310  {
311    if (!mmDebugCheckSingleHeapAddr(p, heap, fn, l)  ||
312        !mmDebugCheckHeapAddrContainment(p, heap, MM_HEAP_ADDR_FREE_FLAG,
313                                         fn, l))
314      return 0;
315    p = *((void**) p);
316  }
317  return 1;
318}
319
320int mmDebugCheckHeapAddr(void* addr, memHeap heap, int flag,
321                         const char* fn, int l)
322{
323  if (! mmDebugCheckSingleHeapAddr(addr, heap, fn, l)) return 0;
324
325  if (mm_HEAP_DEBUG > 1)
326  {
327    if (! mmDebugCheckHeap(heap, fn, l)) return 0;
328  }
329
330  if (mm_HEAP_DEBUG > 0)
331    return mmDebugCheckHeapAddrContainment(addr, heap, flag, fn, l);
332  else
333    return 1;
334}
335 
336void * mmDebugAllocHeap(memHeap heap, const char* fn, int l)
337{
338  void* res;
339
340  if (mm_HEAP_DEBUG > 1 && ! mmDebugCheckHeap(heap, fn, l))
341    return NULL;
342#if 0 
343  _mmAllocHeap(res, heap);
344#else
345  {
346    register memHeap _heap =   heap ; 
347    if ((_heap)->current == ((void *)0) ) mmAllocNewHeapPage(_heap); 
348    do { register memHeapPage page = (memHeapPage) ((void*) ((long) (   (_heap)->current   ) & ~(SIZE_OF_SYSTEM_PAGE  -1)))  ; 
349    (page->counter)++; } while (0) ; 
350    ((void*) ( res )) = (_heap)->current; 
351    (_heap)->current =  *((void**)(_heap)->current); 
352  }
353#endif 
354
355
356  mmDebugCheckSingleHeapAddr(res, heap, fn, l);
357 
358  if (mm_HEAP_DEBUG > 0)
359    mmDebugCheckHeapAddrContainment(res, heap, MM_HEAP_ADDR_USED_FLAG,
360                                    fn, l);
361  return res;
362}
363 
364void  mmDebugFreeHeap(void* addr, memHeap heap, const char* fn, int l)
365{
366  mmDebugCheckHeapAddr(addr, heap, MM_HEAP_ADDR_USED_FLAG, fn, l);
367
368  _mmFreeHeap(addr, heap);
369}
370
371#endif
Note: See TracBrowser for help on using the repository browser.