source: git/omalloc/omCheck.c @ e36e3a

spielwiese
Last change on this file since e36e3a was e36e3a, checked in by Olaf Bachmann <obachman@…>, 24 years ago
* .. git-svn-id: file:///usr/local/Singular/svn/trunk@3903 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 11.7 KB
Line 
1/*******************************************************************
2 *  File:    omCheck.c
3 *  Purpose: implementation of omCheck functions
4 *  Author:  obachman@mathematik.uni-kl.de (Olaf Bachmann)
5 *  Created: 11/99
6 *  Version: $Id: omCheck.c,v 1.1 1999-11-23 20:40:12 obachman Exp $
7 *******************************************************************/
8#include "omConfig.h"
9#include "omPrivate.h"
10#include "omLocal.h"
11#include "omList.h"
12#include "omCheck.h"
13
14
15int om_Check = 0;
16/*******************************************************************
17 * 
18 *   Static functions
19 * 
20 *******************************************************************/
21static int omCheckBinAddrSize(void* addr, size_t size, int level);
22static int omCheckPrintBinError(const char* msg, void* addr, size_t size,
23                            omBin bin);
24static const char* omCheckTestBinAddrSize(void* addr, size_t size, int level, 
25                                      omBin *bin);
26static const char* omCheckTestBin(omBin bin, int level);
27static const char* omCheckTestBinPage(omBinPage page, int level);
28static int   omCheckIsKnownTopBin(omBin bin);
29
30/*******************************************************************
31 * 
32 *   Checking addresses
33 * 
34 *******************************************************************/
35int omCheckBinAddr(void* addr, int level)
36{
37  return omCheckBinAddrSize(addr, 0, level);
38}
39
40int omCheckBlockAddr(void* addr, size_t size, int level)
41{
42  if (size == 0)
43  {
44    omError("0 size");
45    return 0;
46  }
47  if (size <= OM_MAX_BLOCK_SIZE)
48    return omCheckBinAddrSize(addr, size, level);
49  else
50    return 1;
51}
52
53int omCheckChunkAddr(void* addr, int level)
54{
55  omBinPage page;
56  addr = addr - SIZEOF_OM_ALIGNMENT;
57  page = *((omBinPage*) addr);
58  if (page != om_LargePage)
59    return omCheckBinAddrSize(addr, -1, level);
60  else
61    return 1;
62}
63   
64/*******************************************************************
65 * 
66 * Checking Bins
67 * 
68 *******************************************************************/
69static int omCheckIsKnownTopBin(omBin bin)
70{
71  int i = 0;
72  omSpecBin s_bin;
73 
74  for (i=0; i<= OM_MAX_BIN_INDEX; i++)
75  {
76    if (bin == &om_StaticBin[i]) return 1;
77  }
78 
79  s_bin = om_SpecBin;
80  while (s_bin != NULL)
81  {
82    if (bin == s_bin->bin) return 1;
83    s_bin = s_bin->next;
84  }
85 
86  return 0;
87}
88
89int omCheckBin(omBin bin, int level)
90{
91  const char* msg = omTestBin(bin, level);
92  if (msg != NULL) 
93  {
94    omPrintBinError(msg, NULL, 0, bin);
95    return 0;
96  }
97  return 1;
98}
99
100int omCheckBins(int level)
101{
102  if (level <= 0)
103  {
104    return 1;
105  }
106  else
107  {
108   
109    int i = 0;
110    omSpecBin s_bin;
111 
112    for (i=0; i<= OM_MAX_BIN_INDEX; i++)
113    {
114      if (! omCheckBin(&om_StaticBin[i], level)) return 0;
115    }
116    s_bin = om_SpecBin;
117    while (s_bin != NULL)
118    {
119      if (! omCheckBin(s_bin->bin, level)) return 0;
120      s_bin = s_bin->next;
121    }
122    return 1;
123  }
124}
125
126/*******************************************************************
127 * 
128 *  CheckAlloc CheckFree
129 * 
130 *******************************************************************/
131
132void* omCheckAllocBin(omBin bin, const int zero, int level)
133{
134  void* res;
135 
136  if (om_Check > level) level = om_Check;
137
138  omCheckBins(level-2);
139
140  if (zero)
141    __omTypeAlloc0Bin(void*, res, bin);
142  else
143    __omTypeAllocBin(void*, res, bin);
144
145  omCheckBinAddr(res, level-1);
146  omCheckBins(level-2);
147
148  return res;
149}
150 
151void  omCheckFreeBin(void* addr, int level)
152{
153  omCheckBins(level-2);
154
155  if (om_Check > level) level = om_Check;
156
157  if (omCheckBinAddr(addr, level))
158    __omFreeBin(addr);
159
160  omCheckBins(level - 2);
161}
162
163void* omCheckAllocBlock(size_t size, const int zero, int level)
164{
165  void* res;
166 
167  if (om_Check > level) level = om_Check;
168  if (size <= 0) 
169  {
170    omError("requested AllocBlock size <= 0");
171    size = 1;
172  }
173
174  omCheckBins(level-2);
175
176  if (zero)
177    __omTypeAlloc0Block(void*, res, size);
178  else
179    __omTypeAllocBlock(void*, res, size);
180 
181  omCheckBlockAddr(res, size, level - 1);
182  omCheckBins(level - 2);
183
184  return res;
185}
186
187void omCheckFreeBlock(void* addr, size_t size, int level)
188{
189  if (om_Check > level) level = om_Check;
190  omCheckBins(level - 2);
191  if (! omCheckBlockAddr(addr, size, level)) return;
192 
193  __omFreeBlock(addr, size);
194 
195  omCheckBins(level - 2);
196}
197
198
199void* omCheckAllocChunk(size_t size, const int zero, int level)
200{
201  void* res;
202 
203  if (om_Check > level) level = om_Check;
204  if (size <= 0) 
205  {
206    omError("requested AllocBlock size <= 0");
207    size = 1;
208  }
209  omCheckBins(level - 2);
210
211  if (zero)
212    __omTypeAlloc0Chunk(void*, res, size);
213  else
214    __omTypeAllocChunk(void*, res, size);
215 
216  omCheckChunkAddr(res, level - 1);
217  omCheckBins(level - 2);
218
219  return res;
220}
221
222void omCheckFreeChunk(void* addr, int level)
223{
224  if (om_Check > level) level = om_Check;
225  if (! omCheckChunkAddr(addr, level)) return;
226 
227  __omFreeChunk(addr);
228 
229  omCheckBins(level - 2);
230}
231
232
233/*******************************************************************
234 * 
235 *  Checking a bin address
236 * 
237 *******************************************************************/
238static int omCheckPrintBinError(const char* msg, 
239                                void* addr, size_t size,omBin bin)
240{
241  fprintf(stderr, 
242          "for addr:%p (%d) bin:%p (%ld:%ld)\n",
243          addr, size, (void*) bin, 
244          (bin != NULL ? bin->max_blocks : 0), 
245          (bin != NULL ? bin->sizeW : 0));
246  fflush(stderr);
247  return 0;
248}
249
250static int omCheckBinAddrSize(void* addr, size_t size, int level)
251{
252  omBin bin = NULL;
253  const char* msg = omTestBinAddrSize(addr, size, level, &bin);
254  if (msg != NULL)
255    return omPrintBinError(msg, addr, size, bin);
256  else
257    return 1;
258}
259
260
261/* Check that addr is activ (used) adr of bin */
262static const char* 
263omCheckTestBinAddrSize(void* addr, size_t size, int level, omBin* r_bin)
264{
265  omBin bin;
266  omBinPage page;
267  omBin h_bin;
268  const char* msg;
269 
270  if (level <= 0) return NULL;
271 
272  if (addr == NULL) return omError("NULL addr");
273
274  if (size > OM_MAX_BLOCK_SIZE) return NULL;
275
276  bin = omGetTopBinOfAddr(addr);
277 
278  if (bin == NULL) return omError("NULL Bin");
279
280  if (! omIsKnownTopBin(bin))
281    return omError("Addr not from Bin (Bin unknown)");
282  *r_bin = bin;
283 
284  if ((msg = omTestBin(bin, level - 1)) != NULL) return msg;
285
286  // check for right bin
287  if (size > 0)
288  {
289    if (omIsStaticBin(bin))
290      h_bin = omSize2Bin(size);
291    else
292      h_bin = omGetSpecBin(size);
293    if (bin != h_bin) return omError("size is wrong");
294    if (! omIsStaticBin(bin)) omUnGetSpecBin(&h_bin);
295  }
296
297  // check page
298  page = omGetPageOfAddr(addr);
299  if ((msg = omTestBinPage(page, level - 1)) != NULL) return msg;
300 
301  // look that page is in queue of pages of this Bin
302  h_bin = omGetBinOfPage(page);
303  *r_bin = h_bin;
304  if ( ! omIsOnGList(h_bin->last_page, prev, page))
305    return omError("page of addr not from this Bin");
306
307  // check that addr is aligned within bin
308  if (bin->max_blocks >= 1)
309  {
310    if ( ( ( (unsigned long) addr) 
311           - ((unsigned long) page) 
312           - SIZEOF_OM_BIN_PAGE_HEADER) 
313         % (bin->sizeW * SIZEOF_VOIDP)
314         != 0)
315      return omError("addr unaligned within page");
316  }
317 
318  // check that addr is not on current list of page
319  if (level > 0 && omIsOnList(page->current, addr))
320    return omError("used addr on free list of page");
321 
322  return NULL;
323}
324
325static const char* omCheckTestBinPage(omBinPage page, int level)
326{
327  omBin bin;
328 
329  if (level <= 0) return NULL;
330 
331  if (page == NULL) return omError("NULL page");
332  if (page != omGetPageOfAddr(page)) return omError("page unaligned");
333
334  bin = omGetTopBinOfPage(page);
335  if (bin->max_blocks > 1)
336  {
337    if (page->used_blocks > bin->max_blocks - 1)
338      return omError("used_blocks of page > max_blocks - 1");
339 
340    if (page->used_blocks == bin->max_blocks - 1 && 
341        page->current != NULL)
342      return omError("used_blocks and current out of sync");
343
344    if (page->used_blocks < 0)
345      return omError("used_blocks of page < 0");
346  }
347  else
348  {
349    if (page->used_blocks != 0)
350      return omError("used_blocks != 0 of with max_blocks <= 1");
351  }
352 
353  if (page->current == NULL &&
354      ( ! (page->used_blocks == 0 || 
355            page->used_blocks == bin->max_blocks - 1 ||
356           bin->max_blocks < 1)))
357    return omError("used_blocks and current out of sync");
358 
359  if (level > 2 && omListHasCycle(page->current))
360    return omError("current list has cycle");
361 
362  if (level > 1)
363  {
364    void* current = page->current;
365    int i = 1;
366    if (current != NULL &&
367        omListLength(current) != bin->max_blocks - page->used_blocks - 1)
368      return omError("used_blocks and current out of sync");
369
370    while (current != NULL)
371    {
372      if (omGetPageOfAddr(current) != page) 
373        return omError("current has address not from page");
374     
375      if ( ( ( (unsigned long) current) 
376             - ((unsigned long) page) 
377             - SIZEOF_OM_BIN_PAGE_HEADER) 
378           % (bin->sizeW * SIZEOF_LONG)
379           != 0)
380        return omError("current has unaligned adress");
381      current = *((void**) current);
382      i++;
383    }
384  }
385  return NULL;
386}
387
388static const char* omCheckTestBin(omBin bin, int level)
389{
390  int where;
391  omBinPage page;
392  omBin top_bin = bin;
393  const char* msg;
394 
395  if (level <= 0) return NULL;
396 
397  if (bin == NULL) return omError("NULL Bin");
398
399  if (! omIsKnownTopBin(bin)) return omError("TopBin unknown");
400 
401  if (level > 2 && 
402      omGListHasCycle(bin, next)) 
403    return omError("bin->next list has cycle");
404
405  do
406  {
407    if (bin->last_page == NULL || bin->current_page == om_ZeroPage)
408    {
409      if (! (bin->current_page == om_ZeroPage && bin->last_page == NULL))
410        return omError("current_page out of sync with last_page");
411      continue;
412    }
413
414    if ((msg = omTestBinPage(bin->current_page, level-1)) != NULL)
415      return msg;
416
417    if ((msg = omTestBinPage(bin->last_page, level- 1)) != NULL)
418      return msg;
419   
420    if (bin->last_page->next != NULL) 
421      return omError("last_page->next != NULL");
422
423    if (level == 0) continue;
424   
425    /* check page list for cycles */
426    if (level > 2)
427    {
428      if (omGListHasCycle(bin->last_page, prev))
429        return omError("prev chain of bin has cycles");
430      page = omGListLast(bin->last_page, prev);
431      if (omGListHasCycle(page, next))
432        return omError("next chain of bin has cycles");
433    }
434
435    /* check that current_page is on list of pages */
436    if (! omIsOnGList(bin->last_page, prev, bin->current_page))
437      return"current_page not in page list";
438
439    /* now check single pages */
440    page = bin->last_page;
441    where = 1;
442    while (page != NULL)
443    {
444      if (page != bin->last_page && page != bin->current_page &&
445          ((msg = omTestBinPage(page, level - 1)) != NULL))
446        return msg;
447
448      if (page != bin->last_page && 
449          (page->next == NULL || page->next->prev != page))
450        return omError("page->next wrong");
451      if (page->prev != NULL && page->prev->next != page)
452        return omError("page->prev wrong");
453
454      if (omGetTopBinOfPage(page) != top_bin)
455        return omError("TopBin of page wrong");
456
457      if (omGetStickyOfPage(page) != bin->sticky)
458        return omError("Sticky of page wrong");
459
460      if (omGetBinOfPage(page) != bin)
461        return omError("Bin of Page wrong");
462       
463      if (where == -1)
464      {
465        if (page->used_blocks != 0 || page->current != NULL)
466          return omError("used_blocks and current of fpage out of sync");
467      }
468      else
469      {
470        if (page == bin->current_page)
471        {
472          where = -1;
473        }
474        else
475        {
476          if (page->current == NULL ||
477              page->used_blocks < 0 ||
478              page->used_blocks == bin->max_blocks - 1)
479            return omError("used_blocks and current of upage out of sync");
480        }
481      }
482      page = page->prev;
483    }
484  }
485  while ((bin = bin->next) != NULL);
486 
487  return NULL;
488}
489
490
491   
492
493
494
Note: See TracBrowser for help on using the repository browser.