source: git/Singular/mmalloc.c @ 0e760d0

spielwiese
Last change on this file since 0e760d0 was 6e5833, checked in by Olaf Bachmann <obachman@…>, 25 years ago
* some improvements to mmbt git-svn-id: file:///usr/local/Singular/svn/trunk@2963 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 11.5 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: mmalloc.c,v 1.14 1999-03-19 17:42:27 obachman Exp $ */
5
6/*
7* ABSTRACT:
8*/
9
10
11#include <string.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include "mod2.h"
15#ifdef HAVE_MALLOC_H
16#include "malloc.h"
17#endif
18#include "structs.h"
19#include "febase.h"
20#include "tok.h"
21#include "mmemory.h"
22#include "mmprivate.h"
23#ifdef MTRACK
24#include "mmbt.h"
25#endif
26
27#undef HAVE_ASSUME
28#define HAVE_ASSUME
29
30#ifndef MDEBUG
31
32/**********************************************************************
33 *
34 * Block Routines
35 *
36 **********************************************************************/
37
38void* mmAllocBlock(size_t size)
39{
40  int i;
41  assume(size > 0);
42 
43  i = mmGetIndex(size);
44 
45  if (i < 0)
46  {
47    void *res=(void*)malloc( size );
48    if (res==NULL)
49    {
50      WerrorS("out of memory");
51      m2_end(99);
52    }
53    mm_bytesMalloc += size;
54    if (BVERBOSE(V_SHOW_MEM)) mmCheckPrint();
55    return res;
56  }
57  else
58  {
59    void* res;
60    AllocHeap(res, &mm_theList[i]);
61    return res;
62  }
63}
64
65void mmFreeBlock(void* adr, size_t size)
66{
67  int i;
68  if (adr == NULL ||  size == 0) return;
69 
70  i = mmGetIndex(size);
71 
72  if (i < 0)
73  {
74    mm_bytesMalloc -= size;
75    if (BVERBOSE(V_SHOW_MEM)) mmCheckPrint();
76    free( adr );
77  }
78  else
79  {
80    FreeHeap(adr, &(mm_theList[i]));
81  }
82}
83
84void * mmAllocBlock0( size_t size )
85{
86  void *result=mmAllocBlock(size);
87  memset(result,0,size);
88  return result;
89}
90
91void * mmReallocBlock( void* adr, size_t oldsize, size_t newsize )
92{
93  int i = (oldsize == 0 ? -1: mmGetIndex( oldsize ));
94  int j = mmGetIndex( newsize );
95
96  if ( ( i < 0 ) && ( j < 0 ) )
97  {
98    void *res=(void *)realloc( adr, newsize );
99    if (res==NULL)
100    {
101      WerrorS("out of memory");
102      m2_end(99);
103    }
104    mm_bytesMalloc += ( (int)newsize - (int)oldsize );
105    if (BVERBOSE(V_SHOW_MEM)) mmCheckPrint();
106    return res;
107  }
108  else if ( i == j )
109    return adr;
110  else
111  {
112    /* since we know i and j this can be done better, this is the quick way */
113    void *newadr = mmAllocBlock( newsize );
114    memcpy( newadr, adr, (oldsize < newsize) ? oldsize : newsize );
115    mmFreeBlock( adr, oldsize );
116    return newadr;
117  }
118}
119
120void * mmReallocBlock0( void* adr, size_t oldsize, size_t newsize )
121{
122  void* result = mmReallocBlock(adr, oldsize, newsize);
123  if (oldsize < newsize)
124    memset(&(((char*)result)[oldsize]), 0, newsize-oldsize);
125
126  return result;
127}
128
129/**********************************************************************
130 *
131 * Routines for chunks of memory
132 *
133 **********************************************************************/
134   
135void * mmAlloc( size_t size )
136{
137  size_t thesize = size + sizeof( ADDRESS );
138  size_t * dummy = (size_t*)mmAllocBlock( thesize );
139  *dummy = thesize;
140  return (void*)(dummy+1);
141}
142
143void mmFree( void* adr )
144{
145  if (adr!=NULL)
146  {
147    adr = (size_t*)adr-1;
148    mmFreeBlock( adr, *(size_t*)adr );
149  }
150}
151
152void * mmRealloc( void* adr, size_t newsize )
153{
154  size_t *aadr=(size_t*)(adr)-1;
155  size_t oldsize = *aadr;
156  void* newadr = mmAlloc( newsize );
157  memcpy( newadr, adr, min(oldsize-sizeof(ADDRESS),newsize) );
158  mmFreeBlock( aadr,oldsize );
159  return newadr;
160}
161
162char * mmStrdup( const char * s)
163{
164  if (s==NULL) return NULL;
165  {
166    char * rc = (char*)mmAlloc( 1 + strlen( s ));
167    strcpy( rc, s );
168    return rc;
169  }
170}
171
172#else /* MDEBUG */
173
174/**********************************************************************
175 *
176 * Heap routines
177 *
178 **********************************************************************/
179static void * mmDBAllocHeapS(memHeap heap, size_t size,
180                             char* fname, int lineno)
181{
182  DBMCB* result;
183
184#ifdef HEAP_DEBUG
185  result = mmDebugAllocHeap(heap, fname, lineno);
186#else
187  mmAllocHeap((void*) result, heap);
188#endif 
189
190#ifdef MTRACK
191  mmTrack(result->bt_stack);
192#endif
193
194  if (! mmCheckDBMCB(result, SizeFromRealSize(mmGetHeapBlockSize(heap)),
195                     MM_FREEFLAG))
196  {
197    mmPrintFL( fname, lineno );
198    return result;
199  }
200   
201  mmMoveDBMCB( &mm_theDBfree, &mm_theDBused, result );
202  mmFillDBMCB(result, size, heap, MM_USEDFLAG, fname, lineno);
203
204  return (void*) &(result->data);
205}
206
207static void mmDBFreeHeapS(void* addr, memHeap heap, size_t size,
208                          char* fname, int lineno)
209{
210  DBMCB *what = (DBMCB*) ((char*) addr - DebugOffsetFront);
211
212  if ( ! mmCheckDBMCB(what, size, MM_USEDFLAG))
213  {
214    mmPrintFL( fname, lineno );
215    return;
216  }
217
218 
219#ifdef HEAP_DEBUG
220  mmDebugFreeHeap(what, heap, fname, lineno);
221#else
222  assume(heap != NULL);
223  mmFreeHeap(what, heap);
224#endif
225 
226  mmMoveDBMCB( &mm_theDBused, &mm_theDBfree, what );
227  mmFillDBMCB(what, SizeFromRealSize(mmGetHeapBlockSize(heap)),
228              heap, MM_FREEFLAG, fname, lineno);
229
230#ifdef MTRACK
231  mmTrack(what->bt_stack);
232#endif 
233}
234
235void * mmDBAllocHeap(memHeap heap, char* f, int l)
236{
237  return mmDBAllocHeapS(heap, SizeFromRealSize(mmGetHeapBlockSize(heap)),f,l);
238}
239
240                 
241void   mmDBFreeHeap(void* addr, memHeap heap, char*f, int l)
242{
243  mmDBFreeHeapS(addr, heap, SizeFromRealSize(mmGetHeapBlockSize(heap)),f,l);
244}
245
246
247/**********************************************************************
248 *
249 * Block Routines
250 *
251 **********************************************************************/
252 
253void * mmDBAllocBlock( size_t size,  char * fname, int lineno)
254{
255  int i;
256
257  if (size==0)
258  {
259    fprintf(stderr,"alloc(0) in %s:%d\n",fname,lineno);
260    size = 1;
261  }
262
263  i = mmGetIndex( size );
264  if ( i < 0 )
265  {
266    DBMCB * result=NULL;
267    int tmpsize=RealSizeFromSize(size);
268    if ((result = (DBMCB*)malloc(tmpsize))!=NULL)
269    {
270      mm_bytesMalloc += tmpsize;
271      if (BVERBOSE(V_SHOW_MEM)) mmCheckPrint();
272
273      mmMoveDBMCBInto( &mm_theDBused, result );
274     
275      if ( mm_minAddr == NULL )
276      {
277        mm_minAddr = (void*)result;
278        mm_maxAddr = (void*)result;
279      }
280      else if ( (void*)result < mm_minAddr )
281        mm_minAddr = (void*)result;
282      else if ( (void*)result > mm_maxAddr )
283        mm_maxAddr = (void*)result;
284
285      mmFillDBMCB(result, size, NULL, MM_USEDFLAG, fname, lineno);
286 
287      #ifdef MTRACK
288      mmTrack(result->bt_stack);
289      #endif
290     
291      return (void*) &(result->data);
292    }
293    else
294    {
295      WerrorS("out of memory");
296      m2_end(99);
297      return NULL;
298    }
299  }
300  else
301  {
302    return mmDBAllocHeapS(&(mm_theList[i]), size, fname, lineno);
303  }
304}
305
306void mmDBFreeBlock(void* adr, size_t size, char * fname, int lineno)
307{
308  int i;
309 
310  if ( ( adr == NULL ) || ( size == 0 ) ) return;
311
312  i = mmGetIndex( size );
313  if ( i < 0 )
314  {
315    DBMCB * what = (DBMCB*) ((char*) adr - DebugOffsetFront);
316    int tmpsize=RealSizeFromSize(size);
317
318    if ( ! mmCheckDBMCB(what, size, MM_USEDFLAG))
319    {
320      mmPrintFL( fname, lineno );
321      return;
322    }
323    mm_bytesMalloc -= tmpsize;
324    mmTakeOutDBMCB(what );
325    free( what );
326    if (BVERBOSE(V_SHOW_MEM)) mmCheckPrint();
327  }
328  else
329  {
330    mmDBFreeHeapS(adr, &(mm_theList[i]), size, fname, lineno);
331  }
332}
333
334void * mmDBAllocBlock0( size_t size, char * fname, int lineno )
335{
336  void *result=mmDBAllocBlock(size, fname,lineno);
337  memset(result,0,size);
338  return result;
339}
340
341
342void * mmDBReallocBlock( void* adr, size_t oldsize, size_t newsize, 
343                         char * fname, int lineno )
344{
345  void* newadr;
346
347  newadr = mmDBAllocBlock( newsize, fname, lineno);
348  memcpy( newadr, adr, (oldsize < newsize) ? oldsize : newsize );
349  mmDBFreeBlock( adr, oldsize, fname, lineno);
350
351  return newadr;
352}
353
354void * mmDBReallocBlock0( void* adr, size_t oldsize, size_t newsize, 
355                          char * fname, int lineno )
356{
357  void* newadr;
358
359  newadr = mmDBAllocBlock0( newsize, fname, lineno);
360  memcpy( newadr, adr, (oldsize < newsize) ? oldsize : newsize );
361  mmDBFreeBlock( adr, oldsize, fname, lineno);
362
363  return newadr;
364}
365
366
367/**********************************************************************
368 *
369 * Routines for chunks of memory
370 *
371 **********************************************************************/
372
373void * mmDBAlloc( size_t size, char* fname, int lineno )
374{
375  size_t thesize = size + sizeof( ADDRESS );
376  size_t * dummy = (size_t*)mmDBAllocBlock( thesize, fname, lineno);
377  *dummy = thesize;
378  return (void*)(dummy+1);
379}
380
381void mmDBFree( void* adr, char* fname, int lineno )
382{
383  if (adr!=NULL)
384  {
385    adr = (size_t*)adr-1;
386    mmDBFreeBlock( adr,*(size_t *)adr, fname, lineno);
387  }
388}
389
390void * mmDBRealloc( void* adr, size_t newsize, char* fname, int lineno )
391{
392  size_t *aadr=(size_t*)(adr)-1;
393  size_t oldsize = *aadr;
394  void* newadr = mmDBAlloc( newsize, fname, lineno );
395  memcpy( newadr, adr, min(oldsize-sizeof(ADDRESS), newsize) );
396  mmDBFreeBlock( aadr, oldsize, fname, lineno);
397  return newadr;
398}
399
400char * mmDBStrdup( const char * s, char *fname, int lineno)
401{
402  if (s==NULL) return NULL;
403  {
404    char * rc = (char*)mmDBAlloc( 1 + strlen( s ),fname,lineno );
405    strcpy( rc, s );
406    return rc;
407  }
408}
409
410#endif /* MDEBUG */
411
412
413/**********************************************************************
414 *
415 * Routines for aligned memory allocation
416 *
417 **********************************************************************/
418   
419#if SIZEOF_DOUBLE == SIZEOF_VOIDP + SIZEOF_VOIDP
420
421#ifdef MDEBUG
422void * mmDBAllocAlignedBlock( size_t size, char* f, int l)   
423#else
424void * mmAllocAlignedBlock( size_t size)
425#endif
426{
427  int i = mmGetIndex(size);
428 
429  if (i < 0)
430  {
431#ifdef MDEBUG
432    unsigned long ret = 
433      (unsigned long) mmDBAllocBlock(size + SIZEOF_DOUBLE + 1, f, l);
434#else
435    unsigned long ret = 
436      (unsigned long) mmAllocBlock(size+SIZEOF_DOUBLE+1);
437#endif
438    unsigned char shift = (ret + 1) & (SIZEOF_DOUBLE - 1);
439    *((unsigned char*) ret) = (unsigned char) shift;
440
441    assume(ret != 0);
442    ret = ((ret + 1) & ~(SIZEOF_DOUBLE - 1));
443
444    assume(ret % SIZEOF_DOUBLE == 0);
445
446    return (void*) ret;
447  }
448  else
449  {
450#if SIZEOF_DOUBLE != SIZEOF_VOIDP
451    void *garbage = NULL, *good, *temp;
452
453    while (1)
454    {
455#endif /* SIZEOF_DOUBLE != SIZEOF_VOIDP */
456
457#ifdef MDEBUG
458      good = mmDBAllocHeapS(&(mm_theList[i]), size, f, l);
459#else
460      AllocHeap(good, &(mm_theList[i]));
461#endif
462      assume(good != NULL);
463
464#if SIZEOF_DOUBLE != SIZEOF_VOIDP
465   
466      if (((unsigned long) good) & (SIZEOF_DOUBLE - 1))
467      {
468        *((void**) good) = garbage;
469        garbage = good;
470      }
471      else
472      {
473        break;
474      }
475    }
476 
477    while (garbage != NULL)
478    {
479      temp = garbage;
480      garbage = *((void**) garbage);
481#ifdef MDEBUG
482      mmDBFreeHeapS(temp, &(mm_theList[i]), size, f, l);
483#else
484      FreeHeap(temp, &(mm_theList[i]));
485#endif
486    }
487#endif /* SIZEOF_DOUBLE != SIZEOF_VOIDP */
488
489    assume(((unsigned long) good) % SIZEOF_DOUBLE == 0);
490   
491    return good;
492  }
493}
494
495
496#ifdef MDEBUG
497void * mmDBAllocAlignedBlock0( size_t size, char* f, int l)   
498#else
499void * mmAllocAlignedBlock0( size_t size)
500#endif
501{
502  void* good;
503#ifdef MDEBUG
504  good = mmDBAllocAlignedBlock(size, f, l);
505#else
506  good = mmAllocAlignedBlock(size);
507#endif
508 
509  memset(good, 0, size);
510 
511  return good;
512}
513
514#ifdef MDEBUG
515void  mmDBFreeAlignedBlock( void* addr, size_t size, char* f, int l)   
516#else
517void  mmFreeAlignedBlock( void* addr, size_t size)
518#endif
519{
520  int i = mmGetIndex(size);
521
522  assume((unsigned long) addr % SIZEOF_DOUBLE == 0);
523 
524  if (i < 0)
525  {
526    unsigned char* adj_addr = ((unsigned char*) addr) - 1;
527    unsigned char shift = *adj_addr;
528
529#ifdef MDEBUG   
530    mmDBFreeBlock(adj_addr - shift, size + SIZEOF_DOUBLE + 1, f, l);
531#else
532    mmFreeBlock(adj_addr - shift, size + SIZEOF_DOUBLE + 1);
533#endif
534  }
535  else
536  {
537#ifdef MDEBUG
538    mmDBFreeHeapS(addr, &(mm_theList[i]), size, f, l);
539#else
540    FreeHeap(addr, &(mm_theList[i]));
541#endif
542  }
543}
544
545#endif /* SIZEOF_DOUBLE == SIZEOF_VOIDP + SIZEOF_VOIDP */
546   
547
548
549 
550 
551 
552
Note: See TracBrowser for help on using the repository browser.