Changeset 472f39 in git
- Timestamp:
- Jul 6, 1999, 3:35:34 PM (24 years ago)
- Branches:
- (u'jengelh-datetime', 'ceac47cbc86fe4a15902392bdbb9bd2ae0ea02c6')(u'spielwiese', 'a800fe4b3e9d37a38c5a10cc0ae9dfa0c15a4ee6')
- Children:
- ce7ba606241efb95de4d1ab5581428b7143b3be2
- Parents:
- acfbb5a85f3eb92ffdb442a04348bd0186e1785b
- Location:
- Singular
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
Singular/gmalloc.c
racfbb5a r472f39 4 4 /* $Id: */ 5 5 6 /* gmalloc used by Singular to have a trusted malloc and valloc 6 /* gmalloc used by Singular to have a trusted malloc and valloc 7 7 slightly edited to include mod2.h and to only provide its functionality 8 8 if HAVE_GMALLOC is defined 9 */ 9 */ 10 10 11 11 #ifdef HAVE_CONFIG_H … … 24 24 /* Declarations for `malloc' and friends. 25 25 Copyright 1990, 1991, 1992, 1993, 1995 Free Software Foundation, Inc. 26 26 Written May 1989 by Mike Haertel. 27 27 28 28 This library is free software; you can redistribute it and/or … … 46 46 #ifndef _MALLOC_H 47 47 48 #define _MALLOC_H 48 #define _MALLOC_H 1 49 49 50 50 #ifdef _MALLOC_INTERNAL 51 51 52 #if 52 #if defined(_LIBC) || defined(STDC_HEADERS) || defined(USG) 53 53 #include <string.h> 54 54 #else 55 55 #ifndef memset 56 #define memset(s, zero, n)bzero ((s), (n))56 #define memset(s, zero, n) bzero ((s), (n)) 57 57 #endif 58 58 #ifndef memcpy 59 #define memcpy(d, s, n)bcopy ((s), (d), (n))60 #endif 61 #endif 62 63 #if 59 #define memcpy(d, s, n) bcopy ((s), (d), (n)) 60 #endif 61 #endif 62 63 #if defined (__GNU_LIBRARY__) || (defined (__STDC__) && __STDC__) 64 64 #include <limits.h> 65 65 #else 66 66 #ifndef CHAR_BIT 67 #define CHAR_BIT868 #endif 69 #endif 70 71 #ifdef 67 #define CHAR_BIT 8 68 #endif 69 #endif 70 71 #ifdef HAVE_UNISTD_H 72 72 #include <unistd.h> 73 73 #endif 74 74 75 #endif 76 77 78 #ifdef 75 #endif /* _MALLOC_INTERNAL. */ 76 77 78 #ifdef __cplusplus 79 79 extern "C" 80 80 { … … 82 82 83 83 #if defined (__cplusplus) || (defined (__STDC__) && __STDC__) 84 #undef 85 #define __P(args)args86 #undef 87 #define __ptr_tvoid *84 #undef __P 85 #define __P(args) args 86 #undef __ptr_t 87 #define __ptr_t void * 88 88 #else /* Not C++ or ANSI C. */ 89 #undef 90 #define __P(args)()91 #undef 92 #define 93 #undef 94 #define __ptr_tchar *89 #undef __P 90 #define __P(args) () 91 #undef const 92 #define const 93 #undef __ptr_t 94 #define __ptr_t char * 95 95 #endif /* C++ or ANSI C. */ 96 96 97 97 #if defined (__STDC__) && __STDC__ 98 98 #include <stddef.h> 99 #define __malloc_size_tsize_t100 #define __malloc_ptrdiff_tptrdiff_t99 #define __malloc_size_t size_t 100 #define __malloc_ptrdiff_t ptrdiff_t 101 101 #else 102 #define __malloc_size_t unsigned int103 #define __malloc_ptrdiff_t int104 #endif 105 106 #ifndef 107 #define NULL0102 #define __malloc_size_t unsigned long 103 #define __malloc_ptrdiff_t long 104 #endif 105 106 #ifndef NULL 107 #define NULL 0 108 108 #endif 109 109 … … 121 121 /* Allocate SIZE bytes allocated to ALIGNMENT bytes. */ 122 122 extern __ptr_t memalign __P ((__malloc_size_t __alignment, 123 123 __malloc_size_t __size)); 124 124 125 125 /* Allocate SIZE bytes on a page boundary. */ … … 134 134 and all fragments of a block are the same size. When all the 135 135 fragments in a block have been freed, the block itself is freed. */ 136 #define INT_BIT (CHAR_BIT * sizeof(int)) 137 #define BLOCKLOG (INT_BIT > 16 ? 12 : 9) 138 #define BLOCKSIZE (1 << BLOCKLOG) 139 #define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE) 136 #define INT_BIT (CHAR_BIT * sizeof(int)) 137 #ifdef __alpha 138 #define BLOCKLOG (13) 139 #else 140 #define BLOCKLOG (INT_BIT > 16 ? 12 : 9) 141 #endif 142 #define BLOCKSIZE (1 << BLOCKLOG) 143 #define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE) 140 144 141 145 /* Determine the amount of memory spanned by the initial heap table 142 146 (not an absolute limit). */ 143 #define HEAP 147 #define HEAP (INT_BIT > 16 ? 4194304 : 65536) 144 148 145 149 /* Number of contiguous free blocks allowed to build up at the end of 146 150 memory before they will be returned to the system. */ 147 #define FINAL_FREE_BLOCKS 151 #define FINAL_FREE_BLOCKS 8 148 152 149 153 /* Data structure giving per-block information. */ … … 152 156 /* Heap information for a busy block. */ 153 157 struct 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 158 { 159 /* Zero for a large (multiblock) object, or positive giving the 160 logarithm to the base two of the fragment size. */ 161 int type; 162 union 163 { 164 struct 165 { 166 __malloc_size_t nfree; /* Free frags in a fragmented block. */ 167 __malloc_size_t first; /* First free fragment of the block. */ 168 } frag; 169 /* For a large object, in its first block, this has the number 170 of blocks in the object. In the other blocks, this has a 171 negative number which says how far back the first block is. */ 172 __malloc_ptrdiff_t size; 173 } info; 174 } busy; 171 175 /* Heap information for a free block 172 176 (that may be the first of a free cluster). */ 173 177 struct 174 175 __malloc_size_t size;/* Size (in blocks) of a free cluster. */176 __malloc_size_t next;/* Index of next free cluster. */177 __malloc_size_t prev;/* Index of previous free cluster. */178 178 { 179 __malloc_size_t size; /* Size (in blocks) of a free cluster. */ 180 __malloc_size_t next; /* Index of next free cluster. */ 181 __malloc_size_t prev; /* Index of previous free cluster. */ 182 } free; 179 183 } malloc_info; 180 184 … … 186 190 187 191 /* Address to block number and vice versa. */ 188 #define BLOCK(A) 189 #define ADDRESS(B) 192 #define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1) 193 #define ADDRESS(B) ((__ptr_t) (((B) - 1) * BLOCKSIZE + _heapbase)) 190 194 191 195 /* Current search index for the heap table. */ … … 197 201 /* Doubly linked lists of free fragments. */ 198 202 struct list 199 200 201 202 203 { 204 struct list *next; 205 struct list *prev; 206 }; 203 207 204 208 /* Free list headers for each fragment size. */ … … 207 211 /* List of blocks allocated with `memalign' (or `valloc'). */ 208 212 struct alignlist 209 210 211 __ptr_t aligned;/* The address that memaligned returned. */212 __ptr_t exact;/* The address that malloc returned. */213 213 { 214 struct alignlist *next; 215 __ptr_t aligned; /* The address that memaligned returned. */ 216 __ptr_t exact; /* The address that malloc returned. */ 217 }; 214 218 extern struct alignlist *_aligned_blocks; 215 219 … … 249 253 extern __ptr_t (*__realloc_hook) __P ((__ptr_t __ptr, __malloc_size_t __size)); 250 254 extern __ptr_t (*__memalign_hook) __P ((__malloc_size_t __size, 251 255 __malloc_size_t __alignment)); 252 256 253 257 /* Return values for `mprobe': these are the kinds of inconsistencies that 254 258 `mcheck' enables detection of. */ 255 259 enum mcheck_status 256 257 MCHECK_DISABLED = -1,/* Consistency checking is not turned on. */258 MCHECK_OK,/* Block is fine. */259 MCHECK_FREE,/* Block freed twice. */260 MCHECK_HEAD,/* Memory before the block was clobbered. */261 MCHECK_TAIL/* Memory after the block was clobbered. */262 260 { 261 MCHECK_DISABLED = -1, /* Consistency checking is not turned on. */ 262 MCHECK_OK, /* Block is fine. */ 263 MCHECK_FREE, /* Block freed twice. */ 264 MCHECK_HEAD, /* Memory before the block was clobbered. */ 265 MCHECK_TAIL /* Memory after the block was clobbered. */ 266 }; 263 267 264 268 /* Activate a standard collection of debugging hooks. This must be called … … 279 283 /* Statistics available to the user. */ 280 284 struct mstats 281 282 283 284 __malloc_size_t bytes_used;/* Byte total of user-allocated chunks. */285 286 __malloc_size_t bytes_free; 287 285 { 286 __malloc_size_t bytes_total; /* Total size of the heap. */ 287 __malloc_size_t chunks_used; /* Chunks allocated by the user. */ 288 __malloc_size_t bytes_used; /* Byte total of user-allocated chunks. */ 289 __malloc_size_t chunks_free; /* Chunks in the free list. */ 290 __malloc_size_t bytes_free;/* Byte total of chunks in the free list. */ 291 }; 288 292 289 293 /* Pick up the current statistics. */ … … 292 296 /* Call WARNFUN with a warning message when memory usage is high. */ 293 297 extern void memory_warnings __P ((__ptr_t __start, 294 298 void (*__warnfun) __P ((const char *)))); 295 299 296 300 … … 307 311 308 312 309 #ifdef 313 #ifdef __cplusplus 310 314 } 311 315 #endif … … 378 382 379 383 /* obachman: undef , gnulibc6 conflict with unistd.h */ 380 #define __getpagesize()getpagesize()384 #define __getpagesize() getpagesize() 381 385 #endif /* if 0 */ 382 386 #endif 383 387 384 #ifndef 385 #define 388 #ifndef _MALLOC_INTERNAL 389 #define _MALLOC_INTERNAL 386 390 #include <malloc.h> 387 391 #endif … … 403 407 /* Memory allocator `malloc'. 404 408 Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. 405 409 Written May 1989 by Mike Haertel. 406 410 407 411 This library is free software; you can redistribute it and/or … … 423 427 or (US mail) as Mike Haertel c/o Free Software Foundation. */ 424 428 425 #ifndef 429 #ifndef _MALLOC_INTERNAL 426 430 #define _MALLOC_INTERNAL 427 431 #include <malloc.h> … … 475 479 result = (*__morecore) (size); 476 480 adj = (unsigned long int) ((unsigned long int) ((char *) result - 477 481 (char *) NULL)) % BLOCKSIZE; 478 482 if (adj != 0) 479 480 481 482 483 483 { 484 adj = BLOCKSIZE - adj; 485 (void) (*__morecore) (adj); 486 result = (char *) result + adj; 487 } 484 488 485 489 if (__after_morecore_hook) … … 532 536 /* Check if we need to grow the info table. */ 533 537 if ((__malloc_size_t) BLOCK ((char *) result + size) > heapsize) 538 { 539 newsize = heapsize; 540 while ((__malloc_size_t) BLOCK ((char *) result + size) > newsize) 541 newsize *= 2; 542 newinfo = (malloc_info *) align (newsize * sizeof (malloc_info)); 543 if (newinfo == NULL) 534 544 { 535 newsize = heapsize; 536 while ((__malloc_size_t) BLOCK ((char *) result + size) > newsize) 537 newsize *= 2; 538 newinfo = (malloc_info *) align (newsize * sizeof (malloc_info)); 539 if (newinfo == NULL) 540 { 541 (*__morecore) (-size); 542 return NULL; 543 } 544 memcpy (newinfo, _heapinfo, heapsize * sizeof (malloc_info)); 545 memset (&newinfo[heapsize], 0, 546 (newsize - heapsize) * sizeof (malloc_info)); 547 oldinfo = _heapinfo; 548 newinfo[BLOCK (oldinfo)].busy.type = 0; 549 newinfo[BLOCK (oldinfo)].busy.info.size 550 = BLOCKIFY (heapsize * sizeof (malloc_info)); 551 _heapinfo = newinfo; 552 /* Account for the _heapinfo block itself in the statistics. */ 553 _bytes_used += newsize * sizeof (malloc_info); 554 ++_chunks_used; 555 _free_internal (oldinfo); 556 heapsize = newsize; 545 (*__morecore) (-size); 546 return NULL; 557 547 } 548 memcpy (newinfo, _heapinfo, heapsize * sizeof (malloc_info)); 549 memset (&newinfo[heapsize], 0, 550 (newsize - heapsize) * sizeof (malloc_info)); 551 oldinfo = _heapinfo; 552 newinfo[BLOCK (oldinfo)].busy.type = 0; 553 newinfo[BLOCK (oldinfo)].busy.info.size 554 = BLOCKIFY (heapsize * sizeof (malloc_info)); 555 _heapinfo = newinfo; 556 /* Account for the _heapinfo block itself in the statistics. */ 557 _bytes_used += newsize * sizeof (malloc_info); 558 ++_chunks_used; 559 _free_internal (oldinfo); 560 heapsize = newsize; 561 } 558 562 559 563 _heaplimit = BLOCK ((char *) result + size); … … 578 582 Be compatible. */ 579 583 580 #if 584 #if 0 581 585 if (size == 0) 582 586 return NULL; … … 600 604 /* Determine the allocation policy based on the request size. */ 601 605 if (size <= BLOCKSIZE / 2) 606 { 607 /* Small allocation to receive a fragment of a block. 608 Determine the logarithm to base two of the fragment size. */ 609 register __malloc_size_t log = 1; 610 --size; 611 while ((size /= 2) != 0) 612 ++log; 613 614 /* Look in the fragment lists for a 615 free fragment of the desired size. */ 616 next = _fraghead[log].next; 617 if (next != NULL) 602 618 { 603 /* Small allocation to receive a fragment of a block. 604 Determine the logarithm to base two of the fragment size. */ 605 register __malloc_size_t log = 1; 606 --size; 607 while ((size /= 2) != 0) 608 ++log; 609 610 /* Look in the fragment lists for a 611 free fragment of the desired size. */ 612 next = _fraghead[log].next; 613 if (next != NULL) 614 { 615 /* There are free fragments of this size. 616 Pop a fragment out of the fragment list and return it. 617 Update the block's nfree and first counters. */ 618 result = (__ptr_t) next; 619 next->prev->next = next->next; 620 if (next->next != NULL) 621 next->next->prev = next->prev; 622 block = BLOCK (result); 623 if (--_heapinfo[block].busy.info.frag.nfree != 0) 624 _heapinfo[block].busy.info.frag.first = (unsigned long int) 625 ((unsigned long int) ((char *) next->next - (char *) NULL) 626 % BLOCKSIZE) >> log; 627 628 /* Update the statistics. */ 629 ++_chunks_used; 630 _bytes_used += 1 << log; 631 --_chunks_free; 632 _bytes_free -= 1 << log; 633 } 634 else 635 { 636 /* No free fragments of the desired size, so get a new block 637 and break it into fragments, returning the first. */ 638 result = malloc (BLOCKSIZE); 639 if (result == NULL) 640 return NULL; 641 642 /* Link all fragments but the first into the free list. */ 643 for (i = 1; i < (__malloc_size_t) (BLOCKSIZE >> log); ++i) 644 { 645 next = (struct list *) ((char *) result + (i << log)); 646 next->next = _fraghead[log].next; 647 next->prev = &_fraghead[log]; 648 next->prev->next = next; 649 if (next->next != NULL) 650 next->next->prev = next; 651 } 652 653 /* Initialize the nfree and first counters for this block. */ 654 block = BLOCK (result); 655 _heapinfo[block].busy.type = log; 656 _heapinfo[block].busy.info.frag.nfree = i - 1; 657 _heapinfo[block].busy.info.frag.first = i - 1; 658 659 _chunks_free += (BLOCKSIZE >> log) - 1; 660 _bytes_free += BLOCKSIZE - (1 << log); 661 _bytes_used -= BLOCKSIZE - (1 << log); 662 } 619 /* There are free fragments of this size. 620 Pop a fragment out of the fragment list and return it. 621 Update the block's nfree and first counters. */ 622 result = (__ptr_t) next; 623 next->prev->next = next->next; 624 if (next->next != NULL) 625 next->next->prev = next->prev; 626 block = BLOCK (result); 627 if (--_heapinfo[block].busy.info.frag.nfree != 0) 628 _heapinfo[block].busy.info.frag.first = (unsigned long int) 629 ((unsigned long int) ((char *) next->next - (char *) NULL) 630 % BLOCKSIZE) >> log; 631 632 /* Update the statistics. */ 633 ++_chunks_used; 634 _bytes_used += 1 << log; 635 --_chunks_free; 636 _bytes_free -= 1 << log; 663 637 } 638 else 639 { 640 /* No free fragments of the desired size, so get a new block 641 and break it into fragments, returning the first. */ 642 result = malloc (BLOCKSIZE); 643 if (result == NULL) 644 return NULL; 645 646 /* Link all fragments but the first into the free list. */ 647 for (i = 1; i < (__malloc_size_t) (BLOCKSIZE >> log); ++i) 648 { 649 next = (struct list *) ((char *) result + (i << log)); 650 next->next = _fraghead[log].next; 651 next->prev = &_fraghead[log]; 652 next->prev->next = next; 653 if (next->next != NULL) 654 next->next->prev = next; 655 } 656 657 /* Initialize the nfree and first counters for this block. */ 658 block = BLOCK (result); 659 _heapinfo[block].busy.type = log; 660 _heapinfo[block].busy.info.frag.nfree = i - 1; 661 _heapinfo[block].busy.info.frag.first = i - 1; 662 663 _chunks_free += (BLOCKSIZE >> log) - 1; 664 _bytes_free += BLOCKSIZE - (1 << log); 665 _bytes_used -= BLOCKSIZE - (1 << log); 666 } 667 } 664 668 else 669 { 670 /* Large allocation to receive one or more blocks. 671 Search the free list in a circle starting at the last place visited. 672 If we loop completely around without finding a large enough 673 space we will have to get more memory from the system. */ 674 blocks = BLOCKIFY (size); 675 start = block = _heapindex; 676 while (_heapinfo[block].free.size < blocks) 665 677 { 666 /* Large allocation to receive one or more blocks. 667 Search the free list in a circle starting at the last place visited. 668 If we loop completely around without finding a large enough 669 space we will have to get more memory from the system. */ 670 blocks = BLOCKIFY (size); 671 start = block = _heapindex; 672 while (_heapinfo[block].free.size < blocks) 673 { 674 block = _heapinfo[block].free.next; 675 if (block == start) 676 { 677 /* Need to get more from the system. Check to see if 678 the new core will be contiguous with the final free 679 block; if so we don't need to get as much. */ 680 block = _heapinfo[0].free.prev; 681 lastblocks = _heapinfo[block].free.size; 682 if (_heaplimit != 0 && block + lastblocks == _heaplimit && 683 (*__morecore) (0) == ADDRESS (block + lastblocks) && 684 (morecore ((blocks - lastblocks) * BLOCKSIZE)) != NULL) 685 { 686 /* Which block we are extending (the `final free 687 block' referred to above) might have changed, if 688 it got combined with a freed info table. */ 689 block = _heapinfo[0].free.prev; 690 _heapinfo[block].free.size += (blocks - lastblocks); 691 _bytes_free += (blocks - lastblocks) * BLOCKSIZE; 692 continue; 693 } 694 result = morecore (blocks * BLOCKSIZE); 695 if (result == NULL) 696 return NULL; 697 block = BLOCK (result); 698 _heapinfo[block].busy.type = 0; 699 _heapinfo[block].busy.info.size = blocks; 700 ++_chunks_used; 701 _bytes_used += blocks * BLOCKSIZE; 702 return result; 703 } 704 } 705 706 /* At this point we have found a suitable free list entry. 707 Figure out how to remove what we need from the list. */ 708 result = ADDRESS (block); 709 if (_heapinfo[block].free.size > blocks) 710 { 711 /* The block we found has a bit left over, 712 so relink the tail end back into the free list. */ 713 _heapinfo[block + blocks].free.size 714 = _heapinfo[block].free.size - blocks; 715 _heapinfo[block + blocks].free.next 716 = _heapinfo[block].free.next; 717 _heapinfo[block + blocks].free.prev 718 = _heapinfo[block].free.prev; 719 _heapinfo[_heapinfo[block].free.prev].free.next 720 = _heapinfo[_heapinfo[block].free.next].free.prev 721 = _heapindex = block + blocks; 722 } 723 else 724 { 725 /* The block exactly matches our requirements, 726 so just remove it from the list. */ 727 _heapinfo[_heapinfo[block].free.next].free.prev 728 = _heapinfo[block].free.prev; 729 _heapinfo[_heapinfo[block].free.prev].free.next 730 = _heapindex = _heapinfo[block].free.next; 731 --_chunks_free; 732 } 733 734 _heapinfo[block].busy.type = 0; 735 _heapinfo[block].busy.info.size = blocks; 736 ++_chunks_used; 737 _bytes_used += blocks * BLOCKSIZE; 738 _bytes_free -= blocks * BLOCKSIZE; 739 740 /* Mark all the blocks of the object just allocated except for the 741 first with a negative number so you can find the first block by 742 adding that adjustment. */ 743 while (--blocks > 0) 744 _heapinfo[block + blocks].busy.info.size = -blocks; 678 block = _heapinfo[block].free.next; 679 if (block == start) 680 { 681 /* Need to get more from the system. Check to see if 682 the new core will be contiguous with the final free 683 block; if so we don't need to get as much. */ 684 block = _heapinfo[0].free.prev; 685 lastblocks = _heapinfo[block].free.size; 686 if (_heaplimit != 0 && block + lastblocks == _heaplimit && 687 (*__morecore) (0) == ADDRESS (block + lastblocks) && 688 (morecore ((blocks - lastblocks) * BLOCKSIZE)) != NULL) 689 { 690 /* Which block we are extending (the `final free 691 block' referred to above) might have changed, if 692 it got combined with a freed info table. */ 693 block = _heapinfo[0].free.prev; 694 _heapinfo[block].free.size += (blocks - lastblocks); 695 _bytes_free += (blocks - lastblocks) * BLOCKSIZE; 696 continue; 697 } 698 result = morecore (blocks * BLOCKSIZE); 699 if (result == NULL) 700 return NULL; 701 block = BLOCK (result); 702 _heapinfo[block].busy.type = 0; 703 _heapinfo[block].busy.info.size = blocks; 704 ++_chunks_used; 705 _bytes_used += blocks * BLOCKSIZE; 706 return result; 707 } 745 708 } 709 710 /* At this point we have found a suitable free list entry. 711 Figure out how to remove what we need from the list. */ 712 result = ADDRESS (block); 713 if (_heapinfo[block].free.size > blocks) 714 { 715 /* The block we found has a bit left over, 716 so relink the tail end back into the free list. */ 717 _heapinfo[block + blocks].free.size 718 = _heapinfo[block].free.size - blocks; 719 _heapinfo[block + blocks].free.next 720 = _heapinfo[block].free.next; 721 _heapinfo[block + blocks].free.prev 722 = _heapinfo[block].free.prev; 723 _heapinfo[_heapinfo[block].free.prev].free.next 724 = _heapinfo[_heapinfo[block].free.next].free.prev 725 = _heapindex = block + blocks; 726 } 727 else 728 { 729 /* The block exactly matches our requirements, 730 so just remove it from the list. */ 731 _heapinfo[_heapinfo[block].free.next].free.prev 732 = _heapinfo[block].free.prev; 733 _heapinfo[_heapinfo[block].free.prev].free.next 734 = _heapindex = _heapinfo[block].free.next; 735 --_chunks_free; 736 } 737 738 _heapinfo[block].busy.type = 0; 739 _heapinfo[block].busy.info.size = blocks; 740 ++_chunks_used; 741 _bytes_used += blocks * BLOCKSIZE; 742 _bytes_free -= blocks * BLOCKSIZE; 743 744 /* Mark all the blocks of the object just allocated except for the 745 first with a negative number so you can find the first block by 746 adding that adjustment. */ 747 while (--blocks > 0) 748 _heapinfo[block + blocks].busy.info.size = -blocks; 749 } 746 750 747 751 return result; … … 779 783 /* Free a block of memory allocated by `malloc'. 780 784 Copyright 1990, 1991, 1992, 1994 Free Software Foundation, Inc. 781 785 Written May 1989 by Mike Haertel. 782 786 783 787 This library is free software; you can redistribute it and/or … … 799 803 or (US mail) as Mike Haertel c/o Free Software Foundation. */ 800 804 801 #ifndef 805 #ifndef _MALLOC_INTERNAL 802 806 #define _MALLOC_INTERNAL 803 807 #include <malloc.h> … … 825 829 type = _heapinfo[block].busy.type; 826 830 switch (type) 827 831 { 828 832 case 0: 829 833 /* Get as many statistics as early as we can. */ … … 833 837 834 838 /* Find the free cluster previous to this one in the free list. 835 836 839 Start searching at the last block referenced; this may benefit 840 programs with locality of allocation. */ 837 841 i = _heapindex; 838 842 if (i > block) 839 840 843 while (i > block) 844 i = _heapinfo[i].free.prev; 841 845 else 842 843 844 845 846 847 846 { 847 do 848 i = _heapinfo[i].free.next; 849 while (i > 0 && i < block); 850 i = _heapinfo[i].free.prev; 851 } 848 852 849 853 /* Determine how to link this block into the free list. */ 850 854 if (block == i + _heapinfo[i].free.size) 851 852 853 854 855 855 { 856 /* Coalesce this block with its predecessor. */ 857 _heapinfo[i].free.size += _heapinfo[block].busy.info.size; 858 block = i; 859 } 856 860 else 857 858 859 860 861 862 863 864 865 861 { 862 /* Really link this block back into the free list. */ 863 _heapinfo[block].free.size = _heapinfo[block].busy.info.size; 864 _heapinfo[block].free.next = _heapinfo[i].free.next; 865 _heapinfo[block].free.prev = i; 866 _heapinfo[i].free.next = block; 867 _heapinfo[_heapinfo[block].free.next].free.prev = block; 868 ++_chunks_free; 869 } 866 870 867 871 /* Now that the block is linked in, see if we can coalesce it 868 869 872 with its successor (by deleting its successor from the list 873 and adding in its size). */ 870 874 if (block + _heapinfo[block].free.size == _heapinfo[block].free.next) 871 872 873 874 875 876 877 878 875 { 876 _heapinfo[block].free.size 877 += _heapinfo[_heapinfo[block].free.next].free.size; 878 _heapinfo[block].free.next 879 = _heapinfo[_heapinfo[block].free.next].free.next; 880 _heapinfo[_heapinfo[block].free.next].free.prev = block; 881 --_chunks_free; 882 } 879 883 880 884 /* Now see if we can return stuff to the system. */ 881 885 blocks = _heapinfo[block].free.size; 882 886 if (blocks >= FINAL_FREE_BLOCKS && block + blocks == _heaplimit 883 884 885 886 887 888 889 890 891 892 893 894 895 887 && (*__morecore) (0) == ADDRESS (block + blocks)) 888 { 889 register __malloc_size_t bytes = blocks * BLOCKSIZE; 890 _heaplimit -= blocks; 891 (*__morecore) (-bytes); 892 _heapinfo[_heapinfo[block].free.prev].free.next 893 = _heapinfo[block].free.next; 894 _heapinfo[_heapinfo[block].free.next].free.prev 895 = _heapinfo[block].free.prev; 896 block = _heapinfo[block].free.prev; 897 --_chunks_free; 898 _bytes_free -= bytes; 899 } 896 900 897 901 /* Set the next search to begin at this block. */ … … 908 912 /* Get the address of the first free fragment in this block. */ 909 913 prev = (struct list *) ((char *) ADDRESS (block) + 910 914 (_heapinfo[block].busy.info.frag.first << type)); 911 915 912 916 if (_heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1) 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 917 { 918 /* If all fragments of this block are free, remove them 919 from the fragment list and free the whole block. */ 920 next = prev; 921 for (i = 1; i < (__malloc_size_t) (BLOCKSIZE >> type); ++i) 922 next = next->next; 923 prev->prev->next = next; 924 if (next != NULL) 925 next->prev = prev->prev; 926 _heapinfo[block].busy.type = 0; 927 _heapinfo[block].busy.info.size = 1; 928 929 /* Keep the statistics accurate. */ 930 ++_chunks_used; 931 _bytes_used += BLOCKSIZE; 932 _chunks_free -= BLOCKSIZE >> type; 933 _bytes_free -= BLOCKSIZE; 934 935 free (ADDRESS (block)); 936 } 933 937 else if (_heapinfo[block].busy.info.frag.nfree != 0) 934 935 936 937 938 939 940 941 942 943 944 945 938 { 939 /* If some fragments of this block are free, link this 940 fragment into the fragment list after the first free 941 fragment of this block. */ 942 next = (struct list *) ptr; 943 next->next = prev->next; 944 next->prev = prev; 945 prev->next = next; 946 if (next->next != NULL) 947 next->next->prev = next; 948 ++_heapinfo[block].busy.info.frag.nfree; 949 } 946 950 else 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 951 { 952 /* No fragments of this block are free, so link this 953 fragment into the fragment list and announce that 954 it is the first free fragment of this block. */ 955 prev = (struct list *) ptr; 956 _heapinfo[block].busy.info.frag.nfree = 1; 957 _heapinfo[block].busy.info.frag.first = (unsigned long int) 958 ((unsigned long int) ((char *) ptr - (char *) NULL) 959 % BLOCKSIZE >> type); 960 prev->next = _fraghead[type].next; 961 prev->prev = &_fraghead[type]; 962 prev->prev->next = prev; 963 if (prev->next != NULL) 964 prev->next->prev = prev; 965 } 962 966 break; 963 967 } … … 976 980 for (l = _aligned_blocks; l != NULL; l = l->next) 977 981 if (l->aligned == ptr) 978 979 l->aligned = NULL;/* Mark the slot in the list as free. */980 981 982 982 { 983 l->aligned = NULL; /* Mark the slot in the list as free. */ 984 ptr = l->exact; 985 break; 986 } 983 987 984 988 if (__free_hook != NULL) … … 1005 1009 Cambridge, MA 02139, USA. */ 1006 1010 1007 #ifndef 1011 #ifndef _MALLOC_INTERNAL 1008 1012 #define _MALLOC_INTERNAL 1009 1013 #include <malloc.h> … … 1015 1019 #include <gnu-stabs.h> 1016 1020 1017 #undef 1021 #undef cfree 1018 1022 1019 1023 function_alias(cfree, free, void, (ptr), 1020 1024 DEFUN(cfree, (ptr), PTR ptr)) 1021 1025 1022 1026 #else … … 1032 1036 /* Change the size of a block allocated by `malloc'. 1033 1037 Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. 1034 1038 Written May 1989 by Mike Haertel. 1035 1039 1036 1040 This library is free software; you can redistribute it and/or … … 1052 1056 or (US mail) as Mike Haertel c/o Free Software Foundation. */ 1053 1057 1054 #ifndef 1058 #ifndef _MALLOC_INTERNAL 1055 1059 #define _MALLOC_INTERNAL 1056 1060 #include <malloc.h> … … 1082 1086 /* Otherwise, we'll copy from the end. */ 1083 1087 else 1088 { 1089 register char *endf = from + size; 1090 register char *endt = to + size; 1091 1092 /* If TO - FROM is large, then we should break the copy into 1093 nonoverlapping chunks of TO - FROM bytes each. However, if 1094 TO - FROM is small, then the bcopy function call overhead 1095 makes this not worth it. The crossover point could be about 1096 anywhere. Since I don't think the obvious copy loop is too 1097 bad, I'm trying to err in its favor. */ 1098 if (to - from < 64) 1084 1099 { 1085 register char *endf = from + size; 1086 register char *endt = to + size; 1087 1088 /* If TO - FROM is large, then we should break the copy into 1089 nonoverlapping chunks of TO - FROM bytes each. However, if 1090 TO - FROM is small, then the bcopy function call overhead 1091 makes this not worth it. The crossover point could be about 1092 anywhere. Since I don't think the obvious copy loop is too 1093 bad, I'm trying to err in its favor. */ 1094 if (to - from < 64) 1095 { 1096 do 1097 *--endt = *--endf; 1098 while (endf != from); 1099 } 1100 else 1101 { 1102 for (;;) 1103 { 1104 endt -= (to - from); 1105 endf -= (to - from); 1106 1107 if (endt < to) 1108 break; 1109 1110 bcopy (endf, endt, to - from); 1111 } 1112 1113 /* If SIZE wasn't a multiple of TO - FROM, there will be a 1114 little left over. The amount left over is 1115 (endt + (to - from)) - to, which is endt - from. */ 1116 bcopy (from, to, endt - from); 1117 } 1100 do 1101 *--endt = *--endf; 1102 while (endf != from); 1118 1103 } 1119 } 1120 #endif /* Not emacs. */ 1104 else 1105 { 1106 for (;;) 1107 { 1108 endt -= (to - from); 1109 endf -= (to - from); 1110 1111 if (endt < to) 1112 break; 1113 1114 bcopy (endf, endt, to - from); 1115 } 1116 1117 /* If SIZE wasn't a multiple of TO - FROM, there will be a 1118 little left over. The amount left over is 1119 (endt + (to - from)) - to, which is endt - from. */ 1120 bcopy (from, to, endt - from); 1121 } 1122 } 1123 } 1124 #endif /* Not emacs. */ 1121 1125 1122 1126 #define memmove(to, from, size) safe_bcopy ((from), (to), (size)) … … 1146 1150 1147 1151 if (size == 0) 1148 1149 1150 1151 1152 { 1153 free (ptr); 1154 return malloc (0); 1155 } 1152 1156 else if (ptr == NULL) 1153 1157 return malloc (size); … … 1160 1164 type = _heapinfo[block].busy.type; 1161 1165 switch (type) 1162 1166 { 1163 1167 case 0: 1164 1168 /* Maybe reallocate a large block to a small fragment. */ 1165 1169 if (size <= BLOCKSIZE / 2) 1166 1167 1168 1169 1170 1171 1172 1173 1174 1170 { 1171 result = malloc (size); 1172 if (result != NULL) 1173 { 1174 memcpy (result, ptr, size); 1175 _free_internal (ptr); 1176 return result; 1177 } 1178 } 1175 1179 1176 1180 /* The new size is a large allocation as well; 1177 1181 see if we can hold it in place. */ 1178 1182 blocks = BLOCKIFY (size); 1179 1183 if (blocks < _heapinfo[block].busy.info.size) 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1184 { 1185 /* The new size is smaller; return 1186 excess memory to the free list. */ 1187 _heapinfo[block + blocks].busy.type = 0; 1188 _heapinfo[block + blocks].busy.info.size 1189 = _heapinfo[block].busy.info.size - blocks; 1190 _heapinfo[block].busy.info.size = blocks; 1191 /* We have just created a new chunk by splitting a chunk in two. 1192 Now we will free this chunk; increment the statistics counter 1193 so it doesn't become wrong when _free_internal decrements it. */ 1194 ++_chunks_used; 1195 _free_internal (ADDRESS (block + blocks)); 1196 result = ptr; 1197 } 1194 1198 else if (blocks == _heapinfo[block].busy.info.size) 1195 1196 1199 /* No size change necessary. */ 1200 result = ptr; 1197 1201 else 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1202 { 1203 /* Won't fit, so allocate a new region that will. 1204 Free the old region first in case there is sufficient 1205 adjacent free space to grow without moving. */ 1206 blocks = _heapinfo[block].busy.info.size; 1207 /* Prevent free from actually returning memory to the system. */ 1208 oldlimit = _heaplimit; 1209 _heaplimit = 0; 1210 _free_internal (ptr); 1211 _heaplimit = oldlimit; 1212 result = malloc (size); 1213 if (result == NULL) 1214 { 1215 /* Now we're really in trouble. We have to unfree 1216 the thing we just freed. Unfortunately it might 1217 have been coalesced with its neighbors. */ 1218 if (_heapindex == block) 1219 (void) malloc (blocks * BLOCKSIZE); 1220 else 1221 { 1222 __ptr_t previous = malloc ((block - _heapindex) * BLOCKSIZE); 1223 (void) malloc (blocks * BLOCKSIZE); 1224 _free_internal (previous); 1225 } 1226 return NULL; 1227 } 1228 if (ptr != result) 1229 memmove (result, ptr, blocks * BLOCKSIZE); 1230 } 1227 1231 break; 1228 1232 1229 1233 default: 1230 1234 /* Old size is a fragment; type is logarithm 1231 1235 to base two of the fragment size. */ 1232 1236 if (size > (__malloc_size_t) (1 << (type - 1)) && 1233 1234 1235 1237 size <= (__malloc_size_t) (1 << type)) 1238 /* The new size is the same kind of fragment. */ 1239 result = ptr; 1236 1240 else 1237 1238 1239 1240 1241 1242 1243 1244 1245 1241 { 1242 /* The new size is different; allocate a new space, 1243 and copy the lesser of the new size and the old. */ 1244 result = malloc (size); 1245 if (result == NULL) 1246 return NULL; 1247 memcpy (result, ptr, min (size, (__malloc_size_t) 1 << type)); 1248 free (ptr); 1249 } 1246 1250 break; 1247 1251 } … … 1269 1273 or (US mail) as Mike Haertel c/o Free Software Foundation. */ 1270 1274 1271 #ifndef 1272 #define 1275 #ifndef _MALLOC_INTERNAL 1276 #define _MALLOC_INTERNAL 1273 1277 #include <malloc.h> 1274 1278 #endif … … 1305 1309 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 1306 1310 1307 #ifndef 1308 #define 1311 #ifndef _MALLOC_INTERNAL 1312 #define _MALLOC_INTERNAL 1309 1313 #include <malloc.h> 1310 1314 #endif 1311 1315 1312 #ifndef 1313 #define __sbrksbrk1316 #ifndef __GNU_LIBRARY__ 1317 #define __sbrk sbrk 1314 1318 #endif 1315 1319 … … 1359 1363 Cambridge, MA 02139, USA. */ 1360 1364 1361 #ifndef 1365 #ifndef _MALLOC_INTERNAL 1362 1366 #define _MALLOC_INTERNAL 1363 1367 #include <malloc.h> … … 1383 1387 return NULL; 1384 1388 adj = (unsigned long int) ((unsigned long int) ((char *) result - 1385 1389 (char *) NULL)) % alignment; 1386 1390 if (adj != 0) 1391 { 1392 struct alignlist *l; 1393 for (l = _aligned_blocks; l != NULL; l = l->next) 1394 if (l->aligned == NULL) 1395 /* This slot is free. Use it. */ 1396 break; 1397 if (l == NULL) 1387 1398 { 1388 struct alignlist *l; 1389 for (l = _aligned_blocks; l != NULL; l = l->next) 1390 if (l->aligned == NULL) 1391 /* This slot is free. Use it. */ 1392 break; 1399 l = (struct alignlist *) malloc (sizeof (struct alignlist)); 1393 1400 if (l == NULL) 1394 { 1395 l = (struct alignlist *) malloc (sizeof (struct alignlist)); 1396 if (l == NULL) 1397 { 1398 free (result); 1399 return NULL; 1400 } 1401 l->next = _aligned_blocks; 1402 _aligned_blocks = l; 1403 } 1404 l->exact = result; 1405 result = l->aligned = (char *) result + alignment - adj; 1401 { 1402 free (result); 1403 return NULL; 1404 } 1405 l->next = _aligned_blocks; 1406 _aligned_blocks = l; 1406 1407 } 1408 l->exact = result; 1409 result = l->aligned = (char *) result + alignment - adj; 1410 } 1407 1411 1408 1412 return result; 1409 1413 } 1410 1411 1414 #endif /* HAVE_GMALLOC */ -
Singular/ipid.cc
racfbb5a r472f39 2 2 * Computer Algebra System SINGULAR * 3 3 ****************************************/ 4 /* $Id: ipid.cc,v 1.3 2 1999-05-06 16:53:24Singular Exp $ */4 /* $Id: ipid.cc,v 1.33 1999-07-06 13:35:32 Singular Exp $ */ 5 5 6 6 /* … … 202 202 } 203 203 204 char * idrec::String() 205 { 206 sleftv tmp; 207 memset(&tmp,0,sizeof(sleftv)); 208 tmp.rtyp=IDTYP(this); 209 tmp.data=IDDATA(this); 210 tmp.name=IDID(this); 211 return tmp.String(); 212 } 213 214 204 215 //#define KAI 205 216 idhdl enterid(char * s, int lev, idtyp t, idhdl* root, BOOLEAN init) -
Singular/ipid.h
racfbb5a r472f39 4 4 * Computer Algebra System SINGULAR * 5 5 ****************************************/ 6 /* $Id: ipid.h,v 1.2 5 1999-02-26 15:32:05Singular Exp $ */6 /* $Id: ipid.h,v 1.26 1999-07-06 13:35:32 Singular Exp $ */ 7 7 /* 8 8 * ABSTRACT: identfier handling … … 63 63 char * id; 64 64 utypes data; 65 attr attribute; 65 66 BITSET flag; 66 attr attribute;67 67 idtyp typ; 68 68 … … 95 95 idhdl get(const char * s, int lev); 96 96 idhdl set(char * s, int lev, idtyp t, BOOLEAN init=TRUE); 97 char * String(); 97 98 // ~idrec(); 98 99 }; -
Singular/silink.cc
racfbb5a r472f39 2 2 * Computer Algebra System SINGULAR * 3 3 ****************************************/ 4 /* $Id: silink.cc,v 1.2 7 1999-04-17 12:30:24Singular Exp $ */4 /* $Id: silink.cc,v 1.28 1999-07-06 13:35:33 Singular Exp $ */ 5 5 6 6 /* … … 389 389 } 390 390 391 leftv slReadAscii (si_link l)391 leftv slReadAscii2(si_link l, leftv pr) 392 392 { 393 393 FILE * fp=(FILE *)l->data; … … 415 415 #endif 416 416 { 417 //PrintS("? "); mflush(); 418 buf=(char *)AllocL(80); 419 fe_fgets_stdin("? ",buf,80); 417 if (pr->Typ()==STRING_CMD) 418 { 419 buf=(char *)AllocL(80); 420 fe_fgets_stdin(pr->Data(),buf,80); 421 } 422 else 423 { 424 WerrorS("read(<link>,<string>) expected"); 425 buf=mstrdup(""); 426 } 420 427 } 421 428 } … … 425 432 return v; 426 433 } 434 435 leftv slReadAscii(si_link l) 436 { 437 sleftv tmp; 438 memset(&tmp,0,sizeof(sleftv)); 439 tmp.rtyp=STRING_CMD; 440 tmp.data="? "; 441 return slReadAscii2(l,&tmp); 442 } 443 427 444 BOOLEAN slWriteAscii(si_link l, leftv v) 428 445 { … … 524 541 char *rhs; 525 542 rSetHdl(rhdl, TRUE); 526 rhs = ((leftv) h)->String();543 rhs = h->String(); 527 544 528 545 #ifdef HAVE_NAMESPACES 529 if (fprintf(fd, "setring %s::%s;\n", 546 if (fprintf(fd, "setring %s::%s;\n", 530 547 namespaceroot->name, IDID(rhdl)) == EOF) return TRUE; 531 if (fprintf(fd, "%s %s::%s = %s, %s;\n", Tok2Cmdname(MAP_CMD), 548 if (fprintf(fd, "%s %s::%s = %s, %s;\n", Tok2Cmdname(MAP_CMD), 532 549 namespaceroot->name, IDID(h), 533 550 IDMAP(h)->preimage, rhs) == EOF) … … 555 572 idtyp type_id = IDTYP(h); 556 573 557 if (type_id == PACKAGE_CMD && strcmp(IDID(h), "Top") == 0) return FALSE; 558 574 #ifdef HAVE_NAMESPACES 575 if ((type_id == PACKAGE_CMD) &&(strcmp(IDID(h), "Top") == 0)) 576 return FALSE; 577 #endif 578 559 579 // we do not throw an error if a wrong type was attempted to be dumped 560 if (type_str == NULL) return FALSE; 580 if (type_str == NULL) 581 return FALSE; 561 582 562 583 // handle qrings separately 563 if (type_id == QRING_CMD) return DumpQring(fd, h, type_str); 584 if (type_id == QRING_CMD) 585 return DumpQring(fd, h, type_str); 564 586 565 587 // do not dump LIB string 566 588 if (type_id == STRING_CMD && strcmp("LIB", IDID(h)) == 0) 567 {568 589 return FALSE; 569 } 570 590 591 // put type and name 571 592 #ifdef HAVE_NAMESPACES 572 // put type and name573 if (fprintf(fd, "%s %s::%s", type_str, namespaceroot->name, IDID(h)) == EOF) return TRUE;593 if (fprintf(fd, "%s %s::%s", type_str, namespaceroot->name, IDID(h)) == EOF) 594 return TRUE; 574 595 #else 575 // put type and name576 if (fprintf(fd, "%s %s", type_str, IDID(h)) == EOF)return TRUE;596 if (fprintf(fd, "%s %s", type_str, IDID(h)) == EOF) 597 return TRUE; 577 598 #endif 578 599 // for matricies, append the dimension … … 588 609 } 589 610 590 if (type_id == PACKAGE_CMD) { 611 #ifdef HAVE_NAMESPACES 612 if (type_id == PACKAGE_CMD) 613 { 591 614 if (fprintf(fd, ";\n") == EOF) return TRUE; 592 615 else return FALSE; 593 616 } 594 617 #endif 618 595 619 // write the equal sign 596 620 if (fprintf(fd, " = ") == EOF) return TRUE; … … 648 672 static BOOLEAN DumpQring(FILE *fd, idhdl h, char *type_str) 649 673 { 650 char *ring_str = ((leftv) h)->String();674 char *ring_str = h->String(); 651 675 if (fprintf(fd, "%s temp_ring = %s;\n", Tok2Cmdname(RING_CMD), ring_str) 652 676 == EOF) return TRUE; … … 656 680 if (fprintf(fd, "attrib(temp_ideal, \"isSB\", 1);\n") == EOF) return TRUE; 657 681 #ifdef HAVE_NAMESPACES 658 if (fprintf(fd, "%s %s::%s = temp_ideal;\n", 682 if (fprintf(fd, "%s %s::%s = temp_ideal;\n", 659 683 type_str, namespaceroot->name, IDID(h)) == EOF) 660 684 #else … … 722 746 else 723 747 { 724 char *rhs = ((leftv) h)->String();748 char *rhs = h->String(); 725 749 726 750 if (rhs == NULL) return EOF; … … 796 820 si_link_root->Kill=slCloseAscii; 797 821 si_link_root->Read=slReadAscii; 822 si_link_root->Read2=slReadAscii2; 798 823 si_link_root->Write=slWriteAscii; 799 824 si_link_root->Dump=slDumpAscii; -
Singular/subexpr.h
racfbb5a r472f39 4 4 * Computer Algebra System SINGULAR * 5 5 ****************************************/ 6 /* $Id: subexpr.h,v 1.1 7 1999-04-17 14:58:54 obachmanExp $ */6 /* $Id: subexpr.h,v 1.18 1999-07-06 13:35:34 Singular Exp $ */ 7 7 /* 8 8 * ABSTRACT: handling of leftv … … 34 34 char * name; 35 35 void * data; 36 attr attribute; 36 37 BITSET flag; 37 attr attribute;38 38 int rtyp; 39 39 /* the type of the expression, describes the data field
Note: See TracChangeset
for help on using the changeset viewer.