source: git/Singular/mmalloc.c @ a2583d3

fieker-DuValspielwiese
Last change on this file since a2583d3 was a2583d3, checked in by Wilfred Pohl <pohl@…>, 24 years ago
trick from olaf git-svn-id: file:///usr/local/Singular/svn/trunk@4436 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 15.0 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: mmalloc.c,v 1.23 2000-06-07 13:36:13 pohl 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      /* this is relaly dirty and breaks oon the HP */
492      return good;
493#else
494      good = AllocHeap(&(mm_theList[i]));
495#endif
496      assume(good != NULL);
497
498      if (((unsigned long) good) & (SIZEOF_DOUBLE - 1))
499      {
500        *((void**) good) = garbage;
501        garbage = good;
502      }
503      else
504      {
505        break;
506      }
507    }
508 
509    while (garbage != NULL)
510    {
511      temp = garbage;
512      garbage = *((void**) garbage);
513#ifdef MDEBUG
514      mmDBFreeHeapS(temp, &(mm_theList[i]), size, f, l);
515#else
516      FreeHeap(temp, &(mm_theList[i]));
517#endif
518    }
519    assume(((unsigned long) good) % SIZEOF_DOUBLE == 0);
520   
521    return good;
522  }
523}
524
525
526#ifdef MDEBUG
527void * mmDBAllocAlignedBlock0( size_t size, char* f, int l)   
528#else
529void * mmAllocAlignedBlock0( size_t size)
530#endif
531{
532  void* good;
533#ifdef MDEBUG
534  good = mmDBAllocAlignedBlock(size, f, l);
535#else
536  good = mmAllocAlignedBlock(size);
537#endif
538 
539  memset(good, 0, size);
540 
541  return good;
542}
543
544#ifdef MDEBUG
545void  mmDBFreeAlignedBlock( void* addr, size_t size, char* f, int l)   
546#else
547void  mmFreeAlignedBlock( void* addr, size_t size)
548#endif
549{
550  int i = mmGetIndex(size);
551
552  assume((unsigned long) addr % SIZEOF_DOUBLE == 0);
553 
554  if (i < 0)
555  {
556    unsigned char* adj_addr = ((unsigned char*) addr) - 1;
557    unsigned char shift = *adj_addr;
558
559#ifdef MDEBUG   
560    mmDBFreeBlock(adj_addr - shift, size + SIZEOF_DOUBLE + 1, f, l);
561#else
562    mmFreeBlock(adj_addr - shift, size + SIZEOF_DOUBLE + 1);
563#endif
564  }
565  else
566  {
567#ifdef MDEBUG
568    mmDBFreeHeapS(addr, &(mm_theList[i]), size, f, l);
569#else
570    FreeHeap(addr, &(mm_theList[i]));
571#endif
572  }
573}
574
575#endif /* SIZEOF_DOUBLE == SIZEOF_VOIDP + SIZEOF_VOIDP */
576   
577
578/**********************************************************************
579 *
580 * malloc/free routine from/to system
581 *
582 **********************************************************************/
583void* mmMallocFromSystem(size_t size)
584{
585  void* ptr;
586#ifdef ALIGN_8
587  if (size % 8 != 0) size = size + 8 - (size % 8);
588#endif
589  ptr = malloc(size);
590  if (ptr == NULL)
591  {
592    mmGarbageCollectHeaps(4);
593    ptr = malloc(size);
594    if (ptr == NULL)
595    {
596      WerrorS("out of memory");
597      m2_end(99);
598      /* should never get here */
599      exit(1);
600    }
601  }
602  mm_bytesMalloc += size;
603  if (BVERBOSE(V_SHOW_MEM)) mmCheckPrint();
604  return ptr;
605}
606
607void* mmReallocFromSystem(void* addr, size_t newsize, size_t oldsize)
608{
609  void* res;
610#ifdef ALIGN_8
611  if (newsize % 8 != 0) newsize = newsize + 8 - (newsize % 8);
612  if (oldsize % 8 != 0) oldsize = oldsize + 8 - (oldsize % 8);
613#endif
614 
615  res = realloc(addr, newsize);
616  if (res == NULL)
617  {
618    mmGarbageCollectHeaps(4);
619    /* Can do a realloc again: manpage reads:
620       "If realloc() fails the original block is left untouched -
621       it is not freed or moved." */
622    res = realloc(addr, newsize); 
623    if (res == NULL)
624    {
625      WerrorS("out of memory");
626      m2_end(99);
627      /* should never get here */
628      exit(1);
629    }
630  }
631  mm_bytesMalloc += ( (int)newsize - (int)oldsize );
632  if (BVERBOSE(V_SHOW_MEM)) mmCheckPrint();
633  return res;
634}
635 
636void mmFreeToSystem(void* addr, size_t size)
637{
638#ifdef ALIGN_8
639  if (size % 8 != 0) size = size + 8 - (size % 8);
640#endif
641  free( addr );
642  mm_bytesMalloc -= size;
643  if (BVERBOSE(V_SHOW_MEM)) mmCheckPrint();
644}
645
646void* mmVallocFromSystem(size_t size)
647{
648  void* page = PALLOC(SIZE_OF_PAGE);
649  if (page == NULL)
650  {
651    mmGarbageCollectHeaps(4);
652    page = PALLOC(SIZE_OF_PAGE);
653    if (page == NULL)
654    {
655      (void)fprintf( stderr, "\nerror: no more memory\n" );
656      m2_end(14);
657      /* should never get here */
658      exit(1);
659    }
660  }
661  mm_bytesValloc += SIZE_OF_PAGE;
662  if (BVERBOSE(V_SHOW_MEM)) mmCheckPrint();
663  return page;
664}
665
666void mmVfreeToSystem(void* page, size_t size)
667{
668  PFREE(page);
669  mm_bytesValloc -= size;
670  if (BVERBOSE(V_SHOW_MEM)) mmCheckPrint();
671}
672 
673
674#endif /* MM_ALLOC_C */
675
676     
Note: See TracBrowser for help on using the repository browser.