source: git/Singular/mmalloc.c @ d18870

fieker-DuValspielwiese
Last change on this file since d18870 was 760042e, checked in by Hans Schönemann <hannes@…>, 24 years ago
*hannes: 64bit fixes git-svn-id: file:///usr/local/Singular/svn/trunk@4174 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 14.9 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: mmalloc.c,v 1.22 2000-03-02 17:43:49 Singular Exp $ */
5
6/*
7* ABSTRACT: implementation of alloc/free routines
8*/
9
10#ifndef MM_ALLOC_C
11#define MM_ALLOC_C
12
13#include <string.h>
14#include <stdio.h>
15#include <stdlib.h>
16#include "mod2.h"
17#ifdef HAVE_MALLOC_H
18#include "malloc.h"
19#endif
20#include "structs.h"
21#include "febase.h"
22#include "tok.h"
23#include "mmemory.h"
24#include "mmprivate.h"
25#include "mmpage.h"
26#ifdef MTRACK
27#include "mmbt.h"
28#endif
29
30#undef HAVE_ASSUME
31#define HAVE_ASSUME
32
33#ifndef MDEBUG
34
35/**********************************************************************
36 *
37 * Block Routines
38 *
39 **********************************************************************/
40
41void* mmAllocBlock(size_t size)
42{
43  int i;
44  assume(size > 0);
45 
46  i = mmGetIndex(size);
47 
48  if (i < 0)
49  {
50    return mmMallocFromSystem(size);
51  }
52  else
53  {
54    return AllocHeap(&mm_theList[i]);
55  }
56}
57
58void mmFreeBlock(void* adr, size_t size)
59{
60  int i;
61  if (adr == NULL ||  size == 0) return;
62 
63  i = mmGetIndex(size);
64 
65  if (i < 0)
66  {
67    mmFreeToSystem(adr, size);
68  }
69  else
70  {
71    FreeHeap(adr, &(mm_theList[i]));
72  }
73}
74
75void * mmAllocBlock0( size_t size )
76{
77  void *result=mmAllocBlock(size);
78  memset(result,0,size);
79  return result;
80}
81
82void * mmReallocBlock( void* adr, size_t oldsize, size_t newsize )
83{
84  int i = (oldsize == 0 ? -1: mmGetIndex( oldsize ));
85  int j = mmGetIndex( newsize );
86
87  if ( ( i < 0 ) && ( j < 0 ) )
88  {
89    return mmReallocFromSystem(adr, newsize, oldsize);
90  }
91  else if ( i == j )
92    return adr;
93  else
94  {
95    /* since we know i and j this can be done better, this is the quick way */
96    void *newadr = mmAllocBlock( newsize );
97    memcpy( newadr, adr, (oldsize < newsize) ? oldsize : newsize );
98    mmFreeBlock( adr, oldsize );
99    return newadr;
100  }
101}
102
103void * mmReallocBlock0( void* adr, size_t oldsize, size_t newsize )
104{
105  void* result = mmReallocBlock(adr, oldsize, newsize);
106  if (oldsize < newsize)
107    memset(&(((char*)result)[oldsize]), 0, newsize-oldsize);
108
109  return result;
110}
111
112/**********************************************************************
113 *
114 * Routines for chunks of memory
115 *
116 **********************************************************************/
117   
118void * mmAlloc( size_t size )
119{
120  size_t thesize = size + sizeof( ADDRESS );
121  size_t * dummy = (size_t*)mmAllocBlock( thesize );
122  *dummy = thesize;
123  return (void*)(dummy+1);
124}
125
126void mmFree( void* adr )
127{
128  if (adr!=NULL)
129  {
130    adr = (size_t*)adr-1;
131    mmFreeBlock( adr, *(size_t*)adr );
132  }
133}
134
135void * mmRealloc( void* adr, size_t newsize )
136{
137  size_t *aadr=(size_t*)(adr)-1;
138  size_t oldsize = *aadr;
139  void* newadr = mmAlloc( newsize );
140  memcpy( newadr, adr, min(oldsize-sizeof(ADDRESS),newsize) );
141  mmFreeBlock( aadr,oldsize );
142  return newadr;
143}
144
145char * mmStrdup( const char * s)
146{
147  if (s==NULL) return NULL;
148  {
149    char * rc = (char*)mmAlloc( 1 + strlen( s ));
150    strcpy( rc, s );
151    return rc;
152  }
153}
154
155#else /* MDEBUG */
156
157/**********************************************************************
158 *
159 * Heap routines
160 *
161 **********************************************************************/
162static void * mmDBAllocHeapS(memHeap heap, size_t size,
163                             char* fname, int lineno)
164{
165  DBMCB* result;
166
167#ifdef HEAP_DEBUG
168  result = mmDebugAllocHeap(heap, fname, lineno);
169#else
170  mmAllocHeap((void*) result, heap);
171#endif 
172   
173#ifdef MTRACK
174  mmTrack(result->bt_allocated_stack);
175#endif
176
177  mmMoveDBMCB( &mm_theDBfree, &mm_theDBused, result );
178  mmFillDBMCB(result, size, heap, MM_USEDFLAG, fname, lineno);
179  return (void*) &(result->data);
180}
181
182static void mmDBFreeHeapS(void* addr, memHeap heap, size_t size,
183                          char* fname, int lineno)
184{
185  DBMCB *what = (DBMCB*) ((char*) addr - DebugOffsetFront);
186
187#if MDEBUG >= 0
188  if ( ! mmCheckDBMCB(what, size, MM_USEDFLAG))
189  {
190    mmPrintFL( fname, lineno );
191    return;
192  }
193#endif
194
195#ifdef HEAP_DEBUG
196  mmDebugFreeHeap(what, heap, fname, lineno);
197#else
198  assume(heap != NULL);
199  mmFreeHeap(what, heap);
200#endif
201 
202  mmMoveDBMCB( &mm_theDBused, &mm_theDBfree, what );
203  mmFillDBMCB(what, SizeFromRealSize(heap->size),
204              heap, MM_FREEFLAG, fname, lineno);
205 
206#ifdef MTRACK_FREE
207  mmTrack(what->bt_freed_stack);
208#endif 
209}
210
211void * mmDBAllocHeap(memHeap heap, char* f, int l)
212{
213  return mmDBAllocHeapS(heap, SizeFromRealSize(heap->size),f,l);
214}
215
216void * mmDBAlloc0Heap(memHeap heap, char* f, int l)
217{
218  void* ptr = mmDBAllocHeapS(heap, SizeFromRealSize(heap->size),f,l);
219  memsetW(ptr, 0, (SizeFromRealSize(heap->size)) >> LOG_SIZEOF_LONG);
220  return ptr;
221}
222
223                 
224void   mmDBFreeHeap(void* addr, memHeap heap, char*f, int l)
225{
226  mmDBFreeHeapS(addr, heap, SizeFromRealSize(heap->size),f,l);
227}
228
229
230/**********************************************************************
231 *
232 * Block Routines
233 *
234 **********************************************************************/
235 
236void * mmDBAllocBlock( size_t size,  char * fname, int lineno)
237{
238  int i;
239
240  if (size==0)
241  {
242    fprintf(stderr,"alloc(0) in %s:%d\n",fname,lineno);
243    size = 1;
244  }
245
246  i = mmGetIndex( size );
247  if ( i < 0 )
248  {
249    int tmpsize=RealSizeFromSize(size);
250    DBMCB * result = (DBMCB *) mmMallocFromSystem(tmpsize);
251    memset(result, 0, sizeof(DBMCB));
252   
253    mmMoveDBMCBInto( &mm_theDBused, result );
254     
255    if ( mm_minAddr == NULL )
256    {
257      mm_minAddr = (void*)result;
258      mm_maxAddr = (void*)result;
259    }
260    else if ( (void*)result < mm_minAddr )
261      mm_minAddr = (void*)result;
262    else if ( (void*)result > mm_maxAddr )
263      mm_maxAddr = (void*)result;
264
265    mmFillDBMCB(result, size, NULL, MM_USEDFLAG, fname, lineno);
266 
267#ifdef MTRACK
268    mmTrack(result->bt_allocated_stack);
269#endif
270    return (void*) &(result->data);
271  }
272  else
273  {
274    return mmDBAllocHeapS(&(mm_theList[i]), size, fname, lineno);
275  }
276}
277
278void mmDBFreeBlock(void* adr, size_t size, char * fname, int lineno)
279{
280  int i;
281 
282  if ( ( adr == NULL ) || ( size == 0 ) ) return;
283
284  i = mmGetIndex( size );
285  if ( i < 0 )
286  {
287    DBMCB * what = (DBMCB*) ((char*) adr - DebugOffsetFront);
288    int tmpsize=RealSizeFromSize(size);
289
290#if MDEBUG >= 0
291    if ( ! mmCheckDBMCB(what, size, MM_USEDFLAG))
292    {
293      mmPrintFL( fname, lineno );
294      return;
295    }
296#endif
297
298    mmTakeOutDBMCB(what);
299    mmFreeToSystem(what, tmpsize);
300  }
301  else
302  {
303    mmDBFreeHeapS(adr, &(mm_theList[i]), size, fname, lineno);
304  }
305}
306
307void * mmDBAllocBlock0( size_t size, char * fname, int lineno )
308{
309  void *result=mmDBAllocBlock(size, fname,lineno);
310  memset(result,0,size);
311  return result;
312}
313
314void * mmDBReallocBlock( void* adr, size_t oldsize, size_t newsize, 
315                         char * fname, int lineno )
316{
317  void* newadr;
318  mmTest(adr, oldsize);
319  newadr = mmDBAllocBlock( newsize, fname, lineno);
320  memcpy( newadr, adr, (oldsize < newsize) ? oldsize : newsize );
321  mmDBFreeBlock( adr, oldsize, fname, lineno);
322
323  return newadr;
324}
325
326void * mmDBReallocBlock0( void* adr, size_t oldsize, size_t newsize, 
327                          char * fname, int lineno )
328{
329  void* newadr;
330
331  newadr = mmDBAllocBlock0( newsize, fname, lineno);
332  memcpy( newadr, adr, (oldsize < newsize) ? oldsize : newsize );
333  mmDBFreeBlock( adr, oldsize, fname, lineno);
334
335  return newadr;
336}
337
338
339/**********************************************************************
340 *
341 * Routines for chunks of memory
342 *
343 **********************************************************************/
344
345void * mmDBAlloc( size_t size, char* fname, int lineno )
346{
347  size_t thesize = size + sizeof( ADDRESS );
348  size_t * dummy = (size_t*)mmDBAllocBlock( thesize, fname, lineno);
349  *dummy = thesize;
350  return (void*)(dummy+1);
351}
352
353void mmDBFree( void* adr, char* fname, int lineno )
354{
355  if (adr!=NULL)
356  {
357    adr = (size_t*)adr-1;
358    mmDBFreeBlock( adr,*(size_t *)adr, fname, lineno);
359  }
360}
361
362void * mmDBRealloc( void* adr, size_t newsize, char* fname, int lineno )
363{
364  size_t *aadr=(size_t*)(adr)-1;
365  size_t oldsize = *aadr;
366  void* newadr = mmDBAlloc( newsize, fname, lineno );
367  memcpy( newadr, adr, min(oldsize-sizeof(ADDRESS), newsize) );
368  mmDBFreeBlock( aadr, oldsize, fname, lineno);
369  return newadr;
370}
371
372char * mmDBStrdup( const char * s, char *fname, int lineno)
373{
374  if (s==NULL) return NULL;
375  {
376    char * rc = (char*)mmDBAlloc( 1 + strlen( s ),fname,lineno );
377    strcpy( rc, s );
378    return rc;
379  }
380}
381
382#endif /* MDEBUG */
383
384/**********************************************************************
385 *
386 * Routines to debug ASO
387 *
388 **********************************************************************/
389#if defined(ASO_DEBUG) || defined(MDEBUG)
390void* mmDBAllocHeapSizeOf(memHeap heap, size_t size, char* file, int line)
391{
392  if (&(mm_theList[mmGetIndex(size)]) != heap)
393  {
394    fprintf(stderr, "ASO Error: Got heap %d:%ld but should be from heap %d:%d occured in %s:%d\n", 
395            mmGetIndex(SizeFromRealSize(heap->size)), SizeFromRealSize(heap->size), 
396            mmGetIndex(size), (int)size, file, line);
397    fflush(stderr);
398    heap = &(mm_theList[mmGetIndex(size)]);
399  }
400
401#ifdef MDEBUG
402  return mmDBAllocHeapS(heap, size, file, line);
403#else
404  return AllocHeap(heap);
405#endif
406}
407
408void* mmDBAlloc0HeapSizeOf(memHeap heap, size_t size, char* file, int line)
409{
410  void* res;
411  if (&(mm_theList[mmGetIndex(size)]) != heap)
412  {
413    fprintf(stderr, "ASO Error: Got heap %d:%ld but should be from heap %d:%d occured in %s:%d\n", 
414            mmGetIndex(SizeFromRealSize(heap->size)), SizeFromRealSize(heap->size), 
415            mmGetIndex(size), (int)size, file, line);
416    fflush(stderr);
417    heap = &(mm_theList[mmGetIndex(size)]);
418  }
419#ifdef MDEBUG
420  res = mmDBAllocHeapS(heap, size, file, line);
421  memset(res, 0, size);
422  return res;
423#else
424  return Alloc0Heap(heap);
425#endif
426}
427
428void  mmDBFreeHeapSizeOf(void* addr, memHeap heap, size_t size, 
429                         char* file, int line)
430{
431  if (&(mm_theList[mmGetIndex(size)]) != heap)
432  {
433    fprintf(stderr, "ASO Error: Got heap %d:%ld but should be from heap %d:%d occured in %s:%d\n", 
434            mmGetIndex(SizeFromRealSize(heap->size)), SizeFromRealSize(heap->size), 
435            mmGetIndex(size), (int)size, file, line);
436    fflush(stderr);
437    heap = &(mm_theList[mmGetIndex(size)]);
438  }
439#ifdef MDEBUG
440  mmDBFreeHeapS(addr, heap, size, file, line);
441#else
442  mmFreeHeap(addr, heap);
443#endif
444}
445
446#endif /* ASO_DEBUG || MDEBUG */
447
448/**********************************************************************
449 *
450 * Routines for aligned memory allocation
451 *
452 **********************************************************************/
453   
454#if SIZEOF_DOUBLE == SIZEOF_VOIDP + SIZEOF_VOIDP
455
456#ifdef MDEBUG
457void * mmDBAllocAlignedBlock( size_t size, char* f, int l)   
458#else
459void * mmAllocAlignedBlock( size_t size)
460#endif
461{
462  int i = mmGetIndex(size);
463 
464  if (i < 0)
465  {
466#ifdef MDEBUG
467    unsigned long ret = 
468      (unsigned long) mmDBAllocBlock(size + SIZEOF_DOUBLE + 1, f, l);
469#else
470    unsigned long ret = 
471      (unsigned long) mmAllocBlock(size+SIZEOF_DOUBLE+1);
472#endif
473    unsigned char shift = (ret + 1) & (SIZEOF_DOUBLE - 1);
474    *((unsigned char*) ret) = (unsigned char) shift;
475
476    assume(ret != 0);
477    ret = ((ret + 1) & ~(SIZEOF_DOUBLE - 1));
478
479    assume(ret % SIZEOF_DOUBLE == 0);
480
481    return (void*) ret;
482  }
483  else
484  {
485    void *garbage = NULL, *good, *temp;
486
487    while (1)
488    {
489#ifdef MDEBUG
490      good = mmDBAllocHeapS(&(mm_theList[i]), size, f, l);
491#else
492      good = AllocHeap(&(mm_theList[i]));
493#endif
494      assume(good != NULL);
495
496      if (((unsigned long) good) & (SIZEOF_DOUBLE - 1))
497      {
498        *((void**) good) = garbage;
499        garbage = good;
500      }
501      else
502      {
503        break;
504      }
505    }
506 
507    while (garbage != NULL)
508    {
509      temp = garbage;
510      garbage = *((void**) garbage);
511#ifdef MDEBUG
512      mmDBFreeHeapS(temp, &(mm_theList[i]), size, f, l);
513#else
514      FreeHeap(temp, &(mm_theList[i]));
515#endif
516    }
517    assume(((unsigned long) good) % SIZEOF_DOUBLE == 0);
518   
519    return good;
520  }
521}
522
523
524#ifdef MDEBUG
525void * mmDBAllocAlignedBlock0( size_t size, char* f, int l)   
526#else
527void * mmAllocAlignedBlock0( size_t size)
528#endif
529{
530  void* good;
531#ifdef MDEBUG
532  good = mmDBAllocAlignedBlock(size, f, l);
533#else
534  good = mmAllocAlignedBlock(size);
535#endif
536 
537  memset(good, 0, size);
538 
539  return good;
540}
541
542#ifdef MDEBUG
543void  mmDBFreeAlignedBlock( void* addr, size_t size, char* f, int l)   
544#else
545void  mmFreeAlignedBlock( void* addr, size_t size)
546#endif
547{
548  int i = mmGetIndex(size);
549
550  assume((unsigned long) addr % SIZEOF_DOUBLE == 0);
551 
552  if (i < 0)
553  {
554    unsigned char* adj_addr = ((unsigned char*) addr) - 1;
555    unsigned char shift = *adj_addr;
556
557#ifdef MDEBUG   
558    mmDBFreeBlock(adj_addr - shift, size + SIZEOF_DOUBLE + 1, f, l);
559#else
560    mmFreeBlock(adj_addr - shift, size + SIZEOF_DOUBLE + 1);
561#endif
562  }
563  else
564  {
565#ifdef MDEBUG
566    mmDBFreeHeapS(addr, &(mm_theList[i]), size, f, l);
567#else
568    FreeHeap(addr, &(mm_theList[i]));
569#endif
570  }
571}
572
573#endif /* SIZEOF_DOUBLE == SIZEOF_VOIDP + SIZEOF_VOIDP */
574   
575
576/**********************************************************************
577 *
578 * malloc/free routine from/to system
579 *
580 **********************************************************************/
581void* mmMallocFromSystem(size_t size)
582{
583  void* ptr;
584#ifdef ALIGN_8
585  if (size % 8 != 0) size = size + 8 - (size % 8);
586#endif
587  ptr = malloc(size);
588  if (ptr == NULL)
589  {
590    mmGarbageCollectHeaps(4);
591    ptr = malloc(size);
592    if (ptr == NULL)
593    {
594      WerrorS("out of memory");
595      m2_end(99);
596      /* should never get here */
597      exit(1);
598    }
599  }
600  mm_bytesMalloc += size;
601  if (BVERBOSE(V_SHOW_MEM)) mmCheckPrint();
602  return ptr;
603}
604
605void* mmReallocFromSystem(void* addr, size_t newsize, size_t oldsize)
606{
607  void* res;
608#ifdef ALIGN_8
609  if (newsize % 8 != 0) newsize = newsize + 8 - (newsize % 8);
610  if (oldsize % 8 != 0) oldsize = oldsize + 8 - (oldsize % 8);
611#endif
612 
613  res = realloc(addr, newsize);
614  if (res == NULL)
615  {
616    mmGarbageCollectHeaps(4);
617    /* Can do a realloc again: manpage reads:
618       "If realloc() fails the original block is left untouched -
619       it is not freed or moved." */
620    res = realloc(addr, newsize); 
621    if (res == NULL)
622    {
623      WerrorS("out of memory");
624      m2_end(99);
625      /* should never get here */
626      exit(1);
627    }
628  }
629  mm_bytesMalloc += ( (int)newsize - (int)oldsize );
630  if (BVERBOSE(V_SHOW_MEM)) mmCheckPrint();
631  return res;
632}
633 
634void mmFreeToSystem(void* addr, size_t size)
635{
636#ifdef ALIGN_8
637  if (size % 8 != 0) size = size + 8 - (size % 8);
638#endif
639  free( addr );
640  mm_bytesMalloc -= size;
641  if (BVERBOSE(V_SHOW_MEM)) mmCheckPrint();
642}
643
644void* mmVallocFromSystem(size_t size)
645{
646  void* page = PALLOC(SIZE_OF_PAGE);
647  if (page == NULL)
648  {
649    mmGarbageCollectHeaps(4);
650    page = PALLOC(SIZE_OF_PAGE);
651    if (page == NULL)
652    {
653      (void)fprintf( stderr, "\nerror: no more memory\n" );
654      m2_end(14);
655      /* should never get here */
656      exit(1);
657    }
658  }
659  mm_bytesValloc += SIZE_OF_PAGE;
660  if (BVERBOSE(V_SHOW_MEM)) mmCheckPrint();
661  return page;
662}
663
664void mmVfreeToSystem(void* page, size_t size)
665{
666  PFREE(page);
667  mm_bytesValloc -= size;
668  if (BVERBOSE(V_SHOW_MEM)) mmCheckPrint();
669}
670 
671
672#endif /* MM_ALLOC_C */
673
674     
Note: See TracBrowser for help on using the repository browser.