Changes in / [335d81f:884f1409]
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/heap.cfa
r335d81f r884f1409 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu May 9 16:29:12201913 // Update Count : 5 1612 // Last Modified On : Fri Jul 19 16:07:46 2019 13 // Update Count : 548 14 14 // 15 15 … … 31 31 32 32 33 enum {34 __CFA_DEFAULT_MMAP_START__ = (512 * 1024 + 1),35 __CFA_DEFAULT_HEAP_EXPANSION__ = (1 * 1024 * 1024),36 };37 38 size_t default_mmap_start() __attribute__(( weak )) {39 return __CFA_DEFAULT_MMAP_START__;40 } // default_mmap_start41 42 size_t default_heap_expansion() __attribute__(( weak )) {43 return __CFA_DEFAULT_HEAP_EXPANSION__;44 } // default_heap_expansion45 46 47 // supported mallopt options48 #ifndef M_MMAP_THRESHOLD49 #define M_MMAP_THRESHOLD (-1)50 #endif // M_TOP_PAD51 #ifndef M_TOP_PAD52 #define M_TOP_PAD (-2)53 #endif // M_TOP_PAD54 55 #define FASTLOOKUP56 #define __STATISTICS__57 58 #define SPINLOCK 059 #define LOCKFREE 160 #define BUCKETLOCK SPINLOCK61 #if BUCKETLOCK == LOCKFREE62 #include <uStackLF.h>63 #endif // LOCKFREE64 65 // #comment TD : This defined is significantly different from the __ALIGN__ define from locks.hfa66 #define ALIGN 1667 68 // enum { NoBucketSizes = 93, // number of buckets sizes69 // #ifdef FASTLOOKUP70 // LookupSizes = 65536, // number of fast lookup sizes71 // #endif // FASTLOOKUP72 // };73 #define NoBucketSizes 93 // number of buckets sizes74 #ifdef FASTLOOKUP75 #define LookupSizes 65536 // number of fast lookup sizes76 #endif // FASTLOOKUP77 78 79 33 static bool traceHeap = false; 80 34 … … 132 86 // return temp; 133 87 // } // traceHeapTermOff 88 89 90 enum { 91 __CFA_DEFAULT_MMAP_START__ = (512 * 1024 + 1), 92 __CFA_DEFAULT_HEAP_EXPANSION__ = (1 * 1024 * 1024), 93 }; 94 95 size_t default_mmap_start() __attribute__(( weak )) { 96 return __CFA_DEFAULT_MMAP_START__; 97 } // default_mmap_start 98 99 size_t default_heap_expansion() __attribute__(( weak )) { 100 return __CFA_DEFAULT_HEAP_EXPANSION__; 101 } // default_heap_expansion 134 102 135 103 … … 160 128 #endif // __CFA_DEBUG__ 161 129 130 // statically allocated variables => zero filled. 131 static size_t pageSize; // architecture pagesize 132 static size_t heapExpand; // sbrk advance 133 static size_t mmapStart; // cross over point for mmap 134 static unsigned int maxBucketsUsed; // maximum number of buckets in use 135 136 137 // #comment TD : This defined is significantly different from the __ALIGN__ define from locks.hfa 138 #define ALIGN 16 139 140 #define SPINLOCK 0 141 #define LOCKFREE 1 142 #define BUCKETLOCK SPINLOCK 143 #if BUCKETLOCK == LOCKFREE 144 #include <uStackLF.h> 145 #endif // LOCKFREE 146 147 // Recursive definitions: HeapManager needs size of bucket array and bucket area needs sizeof HeapManager storage. 148 // Break recusion by hardcoding number of buckets and statically checking number is correct after bucket array defined. 149 enum { NoBucketSizes = 93 }; // number of buckets sizes 162 150 163 151 struct HeapManager { … … 234 222 }; // HeapManager 235 223 236 237 224 static inline size_t getKey( const HeapManager.FreeHeader & freeheader ) { return freeheader.blockSize; } 238 225 239 // statically allocated variables => zero filled. 240 static size_t pageSize; // architecture pagesize 241 static size_t heapExpand; // sbrk advance 242 static size_t mmapStart; // cross over point for mmap 243 static unsigned int maxBucketsUsed; // maximum number of buckets in use 226 227 #define FASTLOOKUP 228 #define __STATISTICS__ 244 229 245 230 // Powers of 2 are common allocation sizes, so make powers of 2 generate the minimum required size. 246 static const unsigned int bucketSizes[ NoBucketSizes] @= {// different bucket sizes231 static const unsigned int bucketSizes[] @= { // different bucket sizes 247 232 16, 32, 48, 64, 248 233 64 + sizeof(HeapManager.Storage), 96, 112, 128, 128 + sizeof(HeapManager.Storage), 160, 192, 224, … … 259 244 4_194_304 + sizeof(HeapManager.Storage) 260 245 }; 246 247 static_assert( NoBucketSizes == sizeof(bucketSizes) / sizeof(bucketSizes[0]), "size of bucket array wrong" ); 248 261 249 #ifdef FASTLOOKUP 250 static_assert( 16 == sizeof(HeapManager.Storage), "size of HeapManager Storage wrong" ); // FIX ME 251 enum { LookupSizes = 65_536 + 16 }; // number of fast lookup sizes 262 252 static unsigned char lookup[LookupSizes]; // O(1) lookup for small sizes 263 253 #endif // FASTLOOKUP … … 532 522 533 523 524 size_t Bsearchl( unsigned int key, const unsigned int * vals, size_t dim ) { 525 size_t l = 0, m, h = dim; 526 while ( l < h ) { 527 m = (l + h) / 2; 528 if ( (unsigned int &)(vals[m]) < key ) { // cast away const 529 l = m + 1; 530 } else { 531 h = m; 532 } // if 533 } // while 534 return l; 535 } // Bsearchl 536 537 534 538 static inline void * doMalloc( size_t size ) with ( heapManager ) { 535 539 HeapManager.Storage * block; // pointer to new block of storage … … 540 544 size_t tsize = size + sizeof(HeapManager.Storage); 541 545 if ( likely( tsize < mmapStart ) ) { // small size => sbrk 542 HeapManager.FreeHeader * freeElem = 543 #ifdef FASTLOOKUP 544 tsize < LookupSizes ? &freeLists[lookup[tsize]] : 545 #endif // FASTLOOKUP 546 bsearchl( tsize, freeLists, (size_t)maxBucketsUsed ); // binary search 546 size_t posn; 547 #ifdef FASTLOOKUP 548 if ( tsize < LookupSizes ) posn = lookup[tsize]; 549 else 550 #endif // FASTLOOKUP 551 posn = Bsearchl( (unsigned int)tsize, bucketSizes, (size_t)maxBucketsUsed ); 552 HeapManager.FreeHeader * freeElem = &freeLists[posn]; 553 // #ifdef FASTLOOKUP 554 // if ( tsize < LookupSizes ) 555 // freeElem = &freeLists[lookup[tsize]]; 556 // else 557 // #endif // FASTLOOKUP 558 // freeElem = bsearchl( tsize, freeLists, (size_t)maxBucketsUsed ); // binary search 559 // HeapManager.FreeHeader * freeElem = 560 // #ifdef FASTLOOKUP 561 // tsize < LookupSizes ? &freeLists[lookup[tsize]] : 562 // #endif // FASTLOOKUP 563 // bsearchl( tsize, freeLists, (size_t)maxBucketsUsed ); // binary search 547 564 assert( freeElem <= &freeLists[maxBucketsUsed] ); // subscripting error ? 548 565 assert( tsize <= freeElem->blockSize ); // search failure ? … … 745 762 return user; 746 763 } // memalignNoStats 764 765 766 // supported mallopt options 767 #ifndef M_MMAP_THRESHOLD 768 #define M_MMAP_THRESHOLD (-1) 769 #endif // M_TOP_PAD 770 #ifndef M_TOP_PAD 771 #define M_TOP_PAD (-2) 772 #endif // M_TOP_PAD 747 773 748 774 -
tests/.expect/copyfile.txt
r335d81f r884f1409 10 10 // Created On : Tue Jul 16 16:47:22 2019 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jul 16 16:48:16201913 // Update Count : 112 // Last Modified On : Wed Jul 17 18:04:44 2019 13 // Update Count : 26 14 14 // 15 15 16 16 #include <fstream.hfa> 17 #include <stdlib.hfa> // new/delete 17 18 18 19 int main( int argc, char * argv[] ) { 19 ifstream & in = stdin;// default files20 ofstream & out =stdout;21 22 choose ( argc ) {23 case 2, 3:24 open( in, argv[1] );// open input file first as output creates file25 if ( argc == 3 ) open( out, argv[2] );// only open output if input opens as output created if nonexistent26 case 1: ; // use default files27 default:28 29 } // choose20 ifstream * in = &stdin; // default files 21 ofstream * out = &stdout; 22 try { 23 choose ( argc ) { 24 case 2, 3: 25 in = new( (const char *)argv[1] ); // open input file first as output creates file 26 if ( argc == 3 ) out = new( (const char *)argv[2] ); // only open output if input opens as output created if nonexistent 27 case 1: ; // use default files 28 default: 29 exit | "Usage [ input-file (default stdin) [ output-file (default stdout) ] ]"; 30 } // choose 30 31 31 char ch;32 out | nlOff;// turn off auto newline33 in | nlOn;// turn on reading newline32 char ch; 33 *out | nlOff; // turn off auto newline 34 *in | nlOn; // turn on reading newline 34 35 35 for () {// read all characters36 37 if ( eof( in ) ) break;// eof ?38 39 } // for40 41 close( in ); // stdin, stdout are never closed42 close( out );43 36 for () { // read all characters 37 *in | ch; 38 if ( eof( *in ) ) break; // eof ? 39 *out | ch; 40 } // for 41 } finally { 42 if ( in != &stdin ) delete( in ); // close file, do not delete stdin! 43 if ( out != &stdout ) delete( out ); // close file, do not delete stdout! 44 } // try 44 45 } // main 45 46 -
tests/.in/copyfile.txt
r335d81f r884f1409 10 10 // Created On : Tue Jul 16 16:47:22 2019 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jul 16 16:48:16201913 // Update Count : 112 // Last Modified On : Wed Jul 17 18:04:44 2019 13 // Update Count : 26 14 14 // 15 15 16 16 #include <fstream.hfa> 17 #include <stdlib.hfa> // new/delete 17 18 18 19 int main( int argc, char * argv[] ) { 19 ifstream & in = stdin;// default files20 ofstream & out =stdout;21 22 choose ( argc ) {23 case 2, 3:24 open( in, argv[1] );// open input file first as output creates file25 if ( argc == 3 ) open( out, argv[2] );// only open output if input opens as output created if nonexistent26 case 1: ; // use default files27 default:28 29 } // choose20 ifstream * in = &stdin; // default files 21 ofstream * out = &stdout; 22 try { 23 choose ( argc ) { 24 case 2, 3: 25 in = new( (const char *)argv[1] ); // open input file first as output creates file 26 if ( argc == 3 ) out = new( (const char *)argv[2] ); // only open output if input opens as output created if nonexistent 27 case 1: ; // use default files 28 default: 29 exit | "Usage [ input-file (default stdin) [ output-file (default stdout) ] ]"; 30 } // choose 30 31 31 char ch;32 out | nlOff;// turn off auto newline33 in | nlOn;// turn on reading newline32 char ch; 33 *out | nlOff; // turn off auto newline 34 *in | nlOn; // turn on reading newline 34 35 35 for () {// read all characters36 37 if ( eof( in ) ) break;// eof ?38 39 } // for40 41 close( in ); // stdin, stdout are never closed42 close( out );43 36 for () { // read all characters 37 *in | ch; 38 if ( eof( *in ) ) break; // eof ? 39 *out | ch; 40 } // for 41 } finally { 42 if ( in != &stdin ) delete( in ); // close file, do not delete stdin! 43 if ( out != &stdout ) delete( out ); // close file, do not delete stdout! 44 } // try 44 45 } // main 45 46 -
tests/copyfile.cfa
r335d81f r884f1409 10 10 // Created On : Tue Jul 16 16:47:22 2019 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jul 16 16:48:16201913 // Update Count : 112 // Last Modified On : Wed Jul 17 18:04:44 2019 13 // Update Count : 26 14 14 // 15 15 16 16 #include <fstream.hfa> 17 #include <stdlib.hfa> // new/delete 17 18 18 19 int main( int argc, char * argv[] ) { 19 ifstream & in = stdin;// default files20 ofstream & out =stdout;21 22 choose ( argc ) {23 case 2, 3:24 open( in, argv[1] );// open input file first as output creates file25 if ( argc == 3 ) open( out, argv[2] );// only open output if input opens as output created if nonexistent26 case 1: ; // use default files27 default:28 29 } // choose20 ifstream * in = &stdin; // default files 21 ofstream * out = &stdout; 22 try { 23 choose ( argc ) { 24 case 2, 3: 25 in = new( (const char *)argv[1] ); // open input file first as output creates file 26 if ( argc == 3 ) out = new( (const char *)argv[2] ); // only open output if input opens as output created if nonexistent 27 case 1: ; // use default files 28 default: 29 exit | "Usage [ input-file (default stdin) [ output-file (default stdout) ] ]"; 30 } // choose 30 31 31 char ch;32 out | nlOff;// turn off auto newline33 in | nlOn;// turn on reading newline32 char ch; 33 *out | nlOff; // turn off auto newline 34 *in | nlOn; // turn on reading newline 34 35 35 for () {// read all characters36 37 if ( eof( in ) ) break;// eof ?38 39 } // for40 41 close( in ); // stdin, stdout are never closed42 close( out );43 36 for () { // read all characters 37 *in | ch; 38 if ( eof( *in ) ) break; // eof ? 39 *out | ch; 40 } // for 41 } finally { 42 if ( in != &stdin ) delete( in ); // close file, do not delete stdin! 43 if ( out != &stdout ) delete( out ); // close file, do not delete stdout! 44 } // try 44 45 } // main 45 46 -
tests/heap.cfa
r335d81f r884f1409 10 10 // Created On : Tue Nov 6 17:54:56 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Dec 11 21:52:40 201813 // Update Count : 1 812 // Last Modified On : Fri Jul 19 08:22:34 2019 13 // Update Count : 19 14 14 // 15 15 … … 29 29 #define __U_DEFAULT_MMAP_START__ (512 * 1024 + 1) 30 30 size_t default_mmap_start() __attribute__(( weak )) { 31 31 return __U_DEFAULT_MMAP_START__; 32 32 } // default_mmap_start 33 33 … … 36 36 37 37 void main( Worker & ) { 38 39 40 41 42 43 44 38 enum { NoOfAllocs = 5000, NoOfMmaps = 10 }; 39 char * locns[NoOfAllocs]; 40 int i; 41 42 // check alloc/free 43 44 for ( j; 40 ) { 45 45 for ( i; NoOfAllocs ) { 46 46 locns[i] = alloc( i ); … … 67 67 free( locns[i] ); 68 68 } // for 69 70 71 72 73 69 } // for 70 71 // check malloc/free (sbrk) 72 73 for ( i; NoOfAllocs ) { 74 74 size_t s = (i + 1) * 20; 75 75 char * area = (char *)malloc( s ); … … 78 78 area[malloc_usable_size( area ) - 1] = '\345'; // fill ultimate byte 79 79 free( area ); 80 81 82 80 } // for 81 82 for ( i; NoOfAllocs ) { 83 83 size_t s = i + 1; // +1 to make initialization simpler 84 84 locns[i] = (char *)malloc( s ); … … 86 86 locns[i][0] = '\345'; locns[i][s - 1] = '\345'; // fill first/last 87 87 locns[i][malloc_usable_size( locns[i] ) - 1] = '\345'; // fill ultimate byte 88 89 88 } // for 89 for ( i; NoOfAllocs ) { 90 90 size_t s = i + 1; 91 91 if ( locns[i][0] != '\345' || locns[i][s - 1] != '\345' || 92 92 locns[i][malloc_usable_size( locns[i] ) - 1] != '\345' ) abort( "malloc/free corrupt storage" ); 93 93 free( locns[i] ); 94 95 96 97 98 94 } // for 95 96 // check malloc/free (mmap) 97 98 for ( i; NoOfMmaps ) { 99 99 size_t s = i + default_mmap_start(); // cross over point 100 100 char * area = (char *)malloc( s ); … … 103 103 area[malloc_usable_size( area ) - 1] = '\345'; // fill ultimate byte 104 104 free( area ); 105 106 107 105 } // for 106 107 for ( i; NoOfMmaps ) { 108 108 size_t s = i + default_mmap_start(); // cross over point 109 109 locns[i] = (char *)malloc( s ); … … 111 111 locns[i][0] = '\345'; locns[i][s - 1] = '\345'; // fill first/last 112 112 locns[i][malloc_usable_size( locns[i] ) - 1] = '\345'; // fill ultimate byte 113 114 113 } // for 114 for ( i; NoOfMmaps ) { 115 115 size_t s = i + default_mmap_start(); // cross over point 116 116 if ( locns[i][0] != '\345' || locns[i][s - 1] != '\345' || 117 117 locns[i][malloc_usable_size( locns[i] ) - 1] != '\345' ) abort( "malloc/free corrupt storage" ); 118 118 free( locns[i] ); 119 120 121 122 123 119 } // for 120 121 // check calloc/free (sbrk) 122 123 for ( i; NoOfAllocs ) { 124 124 size_t s = (i + 1) * 20; 125 125 char * area = (char *)calloc( 5, s ); … … 131 131 area[malloc_usable_size( area ) - 1] = '\345'; // fill ultimate byte 132 132 free( area ); 133 134 135 133 } // for 134 135 for ( i; NoOfAllocs ) { 136 136 size_t s = i + 1; 137 137 locns[i] = (char *)calloc( 5, s ); … … 142 142 locns[i][0] = '\345'; locns[i][s - 1] = '\345'; // fill first/last 143 143 locns[i][malloc_usable_size( locns[i] ) - 1] = '\345'; // fill ultimate byte 144 145 144 } // for 145 for ( i; NoOfAllocs ) { 146 146 size_t s = i + 1; 147 147 if ( locns[i][0] != '\345' || locns[i][s - 1] != '\345' || 148 148 locns[i][malloc_usable_size( locns[i] ) - 1] != '\345' ) abort( "calloc/free corrupt storage3" ); 149 149 free( locns[i] ); 150 151 152 153 154 150 } // for 151 152 // check calloc/free (mmap) 153 154 for ( i; NoOfMmaps ) { 155 155 size_t s = i + default_mmap_start(); // cross over point 156 156 char * area = (char *)calloc( 1, s ); … … 162 162 area[malloc_usable_size( area ) - 1] = '\345'; // fill ultimate byte 163 163 free( area ); 164 165 166 164 } // for 165 166 for ( i; NoOfMmaps ) { 167 167 size_t s = i + default_mmap_start(); // cross over point 168 168 locns[i] = (char *)calloc( 1, s ); … … 173 173 locns[i][0] = '\345'; locns[i][s - 1] = '\345'; // fill first/last 174 174 locns[i][malloc_usable_size( locns[i] ) - 1] = '\345'; // fill ultimate byte 175 176 175 } // for 176 for ( i; NoOfMmaps ) { 177 177 size_t s = i + default_mmap_start(); // cross over point 178 178 if ( locns[i][0] != '\345' || locns[i][s - 1] != '\345' || 179 179 locns[i][malloc_usable_size( locns[i] ) - 1] != '\345' ) abort( "calloc/free corrupt storage6" ); 180 180 free( locns[i] ); 181 182 183 184 185 181 } // for 182 183 // check memalign/free (sbrk) 184 185 enum { limit = 64 * 1024 }; // check alignments up to here 186 186 187 187 for ( a; libAlign() ~= limit ~ a ) { // generate powers of 2 … … 198 198 free( area ); 199 199 } // for 200 201 202 200 } // for 201 202 // check memalign/free (mmap) 203 203 204 204 for ( a; libAlign() ~= limit ~ a ) { // generate powers of 2 … … 216 216 free( area ); 217 217 } // for 218 219 220 221 222 218 } // for 219 220 // check calloc/realloc/free (sbrk) 221 222 for ( i; 1 ~ 10_000 ~ 12 ) { 223 223 // initial N byte allocation 224 224 char * area = (char *)calloc( 5, i ); … … 237 237 } // for 238 238 free( area ); 239 240 241 242 243 239 } // for 240 241 // check calloc/realloc/free (mmap) 242 243 for ( i; 1 ~ 10_000 ~ 12 ) { 244 244 // initial N byte allocation 245 245 size_t s = i + default_mmap_start(); // cross over point … … 259 259 } // for 260 260 free( area ); 261 262 263 264 265 261 } // for 262 263 // check memalign/realloc/free 264 265 size_t amount = 2; 266 266 for ( a; libAlign() ~= limit ~ a ) { // generate powers of 2 267 267 // initial N byte allocation … … 286 286 } // for 287 287 free( area ); 288 289 290 288 } // for 289 290 // check cmemalign/free 291 291 292 292 for ( a; libAlign() ~= limit ~ a ) { // generate powers of 2 … … 305 305 free( area ); 306 306 } // for 307 308 309 310 311 307 } // for 308 309 // check cmemalign/realloc/free 310 311 amount = 2; 312 312 for ( a; libAlign() ~= limit ~ a ) { // generate powers of 2 313 313 // initial N byte allocation … … 338 338 } // for 339 339 free( area ); 340 340 } // for 341 341 //sout | "worker" | thisTask() | "successful completion"; 342 342 } // Worker main 343 343 344 344 int main() { 345 346 345 const unsigned int NoOfWorkers = 4; 346 { 347 347 processor processors[NoOfWorkers - 1] __attribute__(( unused )); // more than one processor 348 348 Worker workers[NoOfWorkers] __attribute__(( unused )); 349 349 } 350 350 // checkFreeOn(); 351 351 // malloc_stats(); 352 352 } 353 353
Note: See TracChangeset
for help on using the changeset viewer.