Changes in libcfa/src/heap.cfa [ad2dced:b4aa1ab]
- File:
-
- 1 edited
-
libcfa/src/heap.cfa (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/heap.cfa
rad2dced rb4aa1ab 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Dec 15 21:37:54202013 // Update Count : 101312 // Last Modified On : Sun Dec 13 22:04:10 2020 13 // Update Count : 984 14 14 // 15 15 16 16 #include <unistd.h> // sbrk, sysconf 17 #include <stdlib.h> // EXIT_FAILURE18 17 #include <stdbool.h> // true, false 19 18 #include <stdio.h> // snprintf, fileno … … 72 71 // Define the default extension heap amount in units of bytes. When the uC++ supplied heap reaches the brk address, 73 72 // the brk address is extended by the extension amount. 74 __CFA_DEFAULT_HEAP_EXPANSION__ = (1 0* 1024 * 1024),73 __CFA_DEFAULT_HEAP_EXPANSION__ = (1 * 1024 * 1024), 75 74 76 75 // Define the mmap crossover point during allocation. Allocations less than this amount are allocated from buckets; … … 116 115 117 116 // statically allocated variables => zero filled. 118 size_t __page_size; // architecture pagesize 119 int __map_prot; // common mmap/mprotect protection 117 static size_t pageSize; // architecture pagesize 120 118 static size_t heapExpand; // sbrk advance 121 119 static size_t mmapStart; // cross over point for mmap … … 251 249 #endif // FASTLOOKUP 252 250 253 static const off_t mmapFd = -1;// fake or actual fd for anonymous file251 static int mmapFd = -1; // fake or actual fd for anonymous file 254 252 #ifdef __CFA_DEBUG__ 255 253 static bool heapBoot = 0; // detect recursion during boot … … 376 374 377 375 static inline bool setMmapStart( size_t value ) { // true => mmapped, false => sbrk 378 if ( value < __page_size || bucketSizes[NoBucketSizes - 1] < value ) return false;376 if ( value < pageSize || bucketSizes[NoBucketSizes - 1] < value ) return false; 379 377 mmapStart = value; // set global 380 378 … … 486 484 #define NO_MEMORY_MSG "insufficient heap memory available for allocating %zd new bytes." 487 485 488 #include <unistd.h>489 486 static inline void * extend( size_t size ) with( heapManager ) { 490 487 lock( extlock __cfaabi_dbg_ctx2 ); … … 493 490 // If the size requested is bigger than the current remaining storage, increase the size of the heap. 494 491 495 size_t increase = ceiling2( size > heapExpand ? size : heapExpand, __page_size ); 496 // Do not call abort or strerror( errno ) as they may call malloc. 492 size_t increase = ceiling2( size > heapExpand ? size : heapExpand, pageSize ); 497 493 if ( sbrk( increase ) == (void *)-1 ) { // failed, no memory ? 498 494 unlock( extlock ); 499 __cfaabi_bits_print_nolock( STDERR_FILENO, NO_MEMORY_MSG, size ); 500 _exit( EXIT_FAILURE ); 501 } // if 502 if ( mprotect( (char *)heapEnd + heapRemaining, increase, __map_prot ) ) { 503 unlock( extlock ); 504 __cfaabi_bits_print_nolock( STDERR_FILENO, "extend() : internal error, mprotect failure, heapEnd:%p size:%zd, errno:%d.\n", heapEnd, increase, errno ); 505 _exit( EXIT_FAILURE ); 495 abort( NO_MEMORY_MSG, size ); // give up 496 } // if 497 if ( mprotect( (char *)heapEnd + heapRemaining, increase, PROT_READ | PROT_WRITE | PROT_EXEC ) ) { 498 enum { BufferSize = 128 }; 499 char helpText[BufferSize]; 500 // Do not call strerror( errno ) as it may call malloc. 501 int len = snprintf( helpText, BufferSize, "internal error, extend(), mprotect failure, heapEnd:%p size:%zd, errno:%d.", heapEnd, increase, errno ); 502 __cfaabi_bits_write( STDERR_FILENO, helpText, len ); 506 503 } // if 507 504 #ifdef __STATISTICS__ … … 511 508 #ifdef __CFA_DEBUG__ 512 509 // Set new memory to garbage so subsequent uninitialized usages might fail. 513 memset( (char *)heapEnd + heapRemaining, '\hde', increase );514 //Memset( (char *)heapEnd + heapRemaining, increase );510 //memset( (char *)heapEnd + heapRemaining, '\377', increase ); 511 Memset( (char *)heapEnd + heapRemaining, increase ); 515 512 #endif // __CFA_DEBUG__ 516 513 rem = heapRemaining + increase - size; … … 571 568 block->header.kind.real.home = freeElem; // pointer back to free list of apropriate size 572 569 } else { // large size => mmap 573 if ( unlikely( size > ULONG_MAX - __page_size ) ) return 0p;574 tsize = ceiling2( tsize, __page_size ); // must be multiple of page size570 if ( unlikely( size > ULONG_MAX - pageSize ) ) return 0p; 571 tsize = ceiling2( tsize, pageSize ); // must be multiple of page size 575 572 #ifdef __STATISTICS__ 576 573 __atomic_add_fetch( &mmap_calls, 1, __ATOMIC_SEQ_CST ); … … 578 575 #endif // __STATISTICS__ 579 576 580 block = (HeapManager.Storage *)mmap( 0, tsize, __map_prot, MAP_PRIVATE | MAP_ANONYMOUS, mmapFd, 0 );577 block = (HeapManager.Storage *)mmap( 0, tsize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, mmapFd, 0 ); 581 578 if ( block == (HeapManager.Storage *)MAP_FAILED ) { // failed ? 582 579 if ( errno == ENOMEM ) abort( NO_MEMORY_MSG, tsize ); // no memory … … 586 583 #ifdef __CFA_DEBUG__ 587 584 // Set new memory to garbage so subsequent uninitialized usages might fail. 588 memset( block, '\hde', tsize );589 //Memset( block, tsize );585 //memset( block, '\377', tsize ); 586 Memset( block, tsize ); 590 587 #endif // __CFA_DEBUG__ 591 588 block->header.kind.real.blockSize = tsize; // storage size for munmap … … 627 624 #endif // __STATISTICS__ 628 625 if ( munmap( header, size ) == -1 ) { 626 #ifdef __CFA_DEBUG__ 629 627 abort( "Attempt to deallocate storage %p not allocated or with corrupt header.\n" 630 628 "Possible cause is invalid pointer.", 631 629 addr ); 630 #endif // __CFA_DEBUG__ 632 631 } // if 633 632 } else { 634 633 #ifdef __CFA_DEBUG__ 635 634 // Set free memory to garbage so subsequent usages might fail. 636 memset( ((HeapManager.Storage *)header)->data, '\hde', freeElem->blockSize - sizeof( HeapManager.Storage ) );637 //Memset( ((HeapManager.Storage *)header)->data, freeElem->blockSize - sizeof( HeapManager.Storage ) );635 //memset( ((HeapManager.Storage *)header)->data, '\377', freeElem->blockSize - sizeof( HeapManager.Storage ) ); 636 Memset( ((HeapManager.Storage *)header)->data, freeElem->blockSize - sizeof( HeapManager.Storage ) ); 638 637 #endif // __CFA_DEBUG__ 639 638 … … 704 703 705 704 static void ?{}( HeapManager & manager ) with( manager ) { 706 __page_size = sysconf( _SC_PAGESIZE ); 707 __map_prot = PROT_READ | PROT_WRITE | PROT_EXEC; 705 pageSize = sysconf( _SC_PAGESIZE ); 708 706 709 707 for ( unsigned int i = 0; i < NoBucketSizes; i += 1 ) { // initialize the free lists … … 725 723 726 724 char * end = (char *)sbrk( 0 ); 727 heapBegin = heapEnd = sbrk( (char *)ceiling2( (long unsigned int)end, __page_size ) - end ); // move start of heap to multiple of alignment725 heapBegin = heapEnd = sbrk( (char *)ceiling2( (long unsigned int)end, pageSize ) - end ); // move start of heap to multiple of alignment 728 726 } // HeapManager 729 727 … … 743 741 #ifdef __CFA_DEBUG__ 744 742 if ( heapBoot ) { // check for recursion during system boot 743 // DO NOT USE STREAMS AS THEY MAY BE UNAVAILABLE AT THIS POINT. 745 744 abort( "boot() : internal error, recursively invoked during system boot." ); 746 745 } // if … … 1049 1048 // page size. It is equivalent to memalign(sysconf(_SC_PAGESIZE),size). 1050 1049 void * valloc( size_t size ) { 1051 return memalign( __page_size, size );1050 return memalign( pageSize, size ); 1052 1051 } // valloc 1053 1052 … … 1055 1054 // Same as valloc but rounds size to multiple of page size. 1056 1055 void * pvalloc( size_t size ) { 1057 return memalign( __page_size, ceiling2( size, __page_size ) );1056 return memalign( pageSize, ceiling2( size, pageSize ) ); 1058 1057 } // pvalloc 1059 1058 … … 1194 1193 choose( option ) { 1195 1194 case M_TOP_PAD: 1196 heapExpand = ceiling2( value, __page_size ); return 1;1195 heapExpand = ceiling2( value, pageSize ); return 1; 1197 1196 case M_MMAP_THRESHOLD: 1198 1197 if ( setMmapStart( value ) ) return 1;
Note:
See TracChangeset
for help on using the changeset viewer.