Changes in / [b78c54f:ab780e6]
- Location:
- libcfa/src
- Files:
-
- 5 edited
-
concurrency/kernel/cluster.cfa (modified) (3 diffs)
-
concurrency/kernel/startup.cfa (modified) (2 diffs)
-
heap.cfa (modified) (28 diffs)
-
heap.hfa (modified) (3 diffs)
-
stdlib.hfa (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel/cluster.cfa
rb78c54f rab780e6 341 341 // Make sure that everything is consistent 342 342 /* paranoid */ check_readyQ( cltr ); 343 ///* paranoid */ verify( (target == 0) == (cltr->sched.caches == 0p) );343 /* paranoid */ verify( (target == 0) == (cltr->sched.caches == 0p) ); 344 344 345 345 __cfadbg_print_safe(ready_queue, "Kernel : Growing ready queue done\n"); … … 416 416 fix_times(readyQ.tscs, ncount); 417 417 } 418 419 418 cltr->sched.caches = alloc( target, cltr->sched.caches`realloc ); 420 419 … … 429 428 430 429 // Make sure that everything is consistent 431 ///* paranoid */ verify( (target == 0) == (cltr->sched.caches == 0p) );430 /* paranoid */ verify( (target == 0) == (cltr->sched.caches == 0p) ); 432 431 /* paranoid */ check_readyQ( cltr ); 433 432 -
libcfa/src/concurrency/kernel/startup.cfa
rb78c54f rab780e6 672 672 uint_fast32_t last_size = ready_mutate_lock(); 673 673 674 // Adjust the ready queue size675 ready_queue_shrink( &this );674 // Adjust the ready queue size 675 ready_queue_shrink( &this ); 676 676 677 677 // Unlock the RWlock … … 682 682 /* paranoid */ verify( this.sched.readyQ.tscs == 0p ); 683 683 /* paranoid */ verify( this.sched.readyQ.count == 0 ); 684 ///* paranoid */ verify( this.sched.io.tscs == 0p );685 ///* paranoid */ verify( this.sched.caches == 0p );684 /* paranoid */ verify( this.sched.io.tscs == 0p ); 685 /* paranoid */ verify( this.sched.caches == 0p ); 686 686 687 687 enable_interrupts( false ); // Don't poll, could be in main cluster -
libcfa/src/heap.cfa
rb78c54f rab780e6 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Apr 7 21:54:29202413 // Update Count : 16 4412 // Last Modified On : Wed Jan 3 21:30:54 2024 13 // Update Count : 1619 14 14 // 15 15 … … 114 114 115 115 116 // CFAgeneric Bsearchl does not inline, so substitute with hand-coded binary-search.116 // generic Bsearchl does not inline, so substitute with hand-coded binary-search. 117 117 inline __attribute__((always_inline)) 118 118 static size_t Bsearchl( unsigned int key, const unsigned int vals[], size_t dim ) { … … 190 190 unsigned int realloc_calls, realloc_0_calls; 191 191 unsigned long long int realloc_storage_request, realloc_storage_alloc; 192 unsigned int free_calls, free_null_ 0_calls;192 unsigned int free_calls, free_null_calls; 193 193 unsigned long long int free_storage_request, free_storage_alloc; 194 194 unsigned int return_pulls, return_pushes; … … 232 232 struct Header { // header 233 233 union Kind { 234 struct RealHeader { // 4-byte word => 8-byte header, 8-byte word => 16-byte header234 struct RealHeader { 235 235 union { 236 // 2nd low-order bit => zero filled, 3rd low-order bit => mmapped 237 // FreeHeader * home; // allocated block points back to home locations (must overlay alignment) 238 void * home; // allocated block points back to home locations (must overlay alignment) 239 size_t blockSize; // size for munmap (must overlay alignment) 240 Storage * next; // freed block points to next freed block of same size 236 struct { // 4-byte word => 8-byte header, 8-byte word => 16-byte header 237 union { 238 // 2nd low-order bit => zero filled, 3rd low-order bit => mmapped 239 // FreeHeader * home; // allocated block points back to home locations (must overlay alignment) 240 void * home; // allocated block points back to home locations (must overlay alignment) 241 size_t blockSize; // size for munmap (must overlay alignment) 242 Storage * next; // freed block points to next freed block of same size 243 }; 244 size_t size; // allocation size in bytes 245 }; 241 246 }; 242 size_t size; // allocation size in bytes243 247 } real; // RealHeader 244 248 … … 257 261 258 262 struct CALIGN FreeHeader { 263 size_t blockSize CALIGN; // size of allocations on this list 259 264 #ifdef OWNERSHIP 260 265 #ifdef RETURNSPIN … … 266 271 Storage * freeList; // thread free list 267 272 Heap * homeManager; // heap owner (free storage to bucket, from bucket to heap) 268 size_t blockSize; // size of allocations on this list269 273 }; // FreeHeader 270 274 … … 365 369 static __thread size_t PAD1 CALIGN TLSMODEL __attribute__(( unused )); // protect false sharing 366 370 static __thread Heap * heapManager CALIGN TLSMODEL; 367 static __thread bool heapManagerBootFlag CALIGN TLSMODEL = false;371 static __thread bool heapManagerBootFlag CALIGN TLSMODEL = false; 368 372 static __thread size_t PAD2 CALIGN TLSMODEL __attribute__(( unused )); // protect further false sharing 369 373 … … 591 595 592 596 #ifdef __STATISTICS__ 597 static HeapStatistics stats; // zero filled 598 593 599 #define prtFmt \ 594 600 "\nHeap statistics: (storage request / allocation)\n" \ … … 601 607 " resize >0 calls %'u; 0 calls %'u; storage %'llu / %'llu bytes\n" \ 602 608 " realloc >0 calls %'u; 0 calls %'u; storage %'llu / %'llu bytes\n" \ 603 " free !null calls %'u; null /0calls %'u; storage %'llu / %'llu bytes\n" \609 " free !null calls %'u; null calls %'u; storage %'llu / %'llu bytes\n" \ 604 610 " return pulls %'u; pushes %'u; storage %'llu / %'llu bytes\n" \ 605 611 " sbrk calls %'u; storage %'llu bytes\n" \ … … 621 627 resize_calls, resize_0_calls, resize_storage_request, resize_storage_alloc, 622 628 realloc_calls, realloc_0_calls, realloc_storage_request, realloc_storage_alloc, 623 free_calls, free_null_ 0_calls, free_storage_request, free_storage_alloc,629 free_calls, free_null_calls, free_storage_request, free_storage_alloc, 624 630 return_pulls, return_pushes, return_storage_request, return_storage_alloc, 625 631 sbrk_calls, sbrk_storage, … … 644 650 "<total type=\"resize\" >0 count=\"%'u;\" 0 count=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n" \ 645 651 "<total type=\"realloc\" >0 count=\"%'u;\" 0 count=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n" \ 646 "<total type=\"free\" !null=\"%'u;\" 0 null /0=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n" \652 "<total type=\"free\" !null=\"%'u;\" 0 null=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n" \ 647 653 "<total type=\"return\" pulls=\"%'u;\" 0 pushes=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n" \ 648 654 "<total type=\"sbrk\" count=\"%'u;\" size=\"%'llu\"/> bytes\n" \ … … 664 670 resize_calls, resize_0_calls, resize_storage_request, resize_storage_alloc, 665 671 realloc_calls, realloc_0_calls, realloc_storage_request, realloc_storage_alloc, 666 free_calls, free_null_ 0_calls, free_storage_request, free_storage_alloc,672 free_calls, free_null_calls, free_storage_request, free_storage_alloc, 667 673 return_pulls, return_pushes, return_storage_request, return_storage_alloc, 668 674 sbrk_calls, sbrk_storage, … … 793 799 } else { 794 800 fakeHeader( header, alignment ); 795 if ( unlikely( MmappedBit( header ) ) ) { // mmapped storage?801 if ( unlikely( MmappedBit( header ) ) ) { // mmapped ? 796 802 verify( addr < heapBegin || heapEnd < addr ); 797 803 size = ClearStickyBits( header->kind.real.blockSize ); // mmap size 798 freeHead = 0p; // prevent uninitialized warning799 804 return true; 800 805 } // if … … 899 904 900 905 906 #define BOOT_HEAP_MANAGER \ 907 if ( unlikely( ! heapMasterBootFlag ) ) { \ 908 heapManagerCtor(); /* trigger for first heap */ \ 909 } /* if */ 910 901 911 #ifdef __STATISTICS__ 902 912 #define STAT_NAME __counter 903 913 #define STAT_PARM , unsigned int STAT_NAME 904 914 #define STAT_ARG( name ) , name 905 #define STAT_0_CNT( counter ) heapManager->stats.counters[counter].calls_0 += 1915 #define STAT_0_CNT( counter ) stats.counters[counter].calls_0 += 1 906 916 #else 907 917 #define STAT_NAME … … 911 921 #endif // __STATISTICS__ 912 922 913 #define BOOT_HEAP_MANAGER \ 914 if ( unlikely( ! heapMasterBootFlag ) ) { \ 915 heapManagerCtor(); /* trigger for first heap */ \ 916 } /* if */ \ 917 verify( heapManager ); 918 919 #define __NONNULL_0_ALLOC__ /* Uncomment to return non-null address for malloc( 0 ). */ 920 #ifndef __NONNULL_0_ALLOC__ 921 #define __NULL_0_ALLOC__( counter, ... ) /* 0 byte allocation returns null pointer */ \ 922 if ( unlikely( size == 0 ) ) { \ 923 // Uncomment to get allocation addresses for a 0-sized allocation rather than a null pointer. 924 //#define __NONNULL_0_ALLOC__ 925 #if ! defined( __NONNULL_0_ALLOC__ ) 926 #define __NULL_0_ALLOC__ unlikely( size == 0 ) || /* 0 BYTE ALLOCATION RETURNS NULL POINTER */ 927 #else 928 #define __NULL_0_ALLOC__ 929 #endif // __NONNULL_0_ALLOC__ 930 931 #define PROLOG( counter, ... ) \ 932 BOOT_HEAP_MANAGER; \ 933 if ( \ 934 __NULL_0_ALLOC__ \ 935 unlikely( size > ULONG_MAX - sizeof(Heap.Storage) ) ) { /* error check */ \ 923 936 STAT_0_CNT( counter ); \ 924 __VA_ARGS__; /* call routine, if specified */\937 __VA_ARGS__; \ 925 938 return 0p; \ 926 939 } /* if */ 927 #else 928 #define __NULL_0_ALLOC__( counter, ... ) 929 #endif // __NONNULL_0_ALLOC__ 930 931 #ifdef __DEBUG__ 932 #define __OVERFLOW_MALLOC__( ... ) \ 933 if ( unlikely( size > ULONG_MAX - sizeof(Heap.Storage) ) ) { /* error check */ \ 934 __VA_ARGS__; /* call routine, if specified */ \ 935 return 0p; \ 936 } /* if */ 937 #else 938 #define __OVERFLOW_MALLOC__( ... ) 939 #endif // __DEBUG__ 940 941 #define PROLOG( counter, ... ) \ 942 BOOT_HEAP_MANAGER; \ 943 __NULL_0_ALLOC__( counter, __VA_ARGS__ ) \ 944 __OVERFLOW_MALLOC__( __VA_ARGS__ ) 940 945 941 946 942 #define SCRUB_SIZE 1024lu … … 952 948 PROLOG( STAT_NAME ); 953 949 950 verify( heapManager ); 954 951 Heap.Storage * block; // pointer to new block of storage 955 952 … … 959 956 960 957 #ifdef __STATISTICS__ 961 #ifdef __NONNULL_0_ALLOC__ 962 if ( unlikely( size == 0 ) ) // malloc( 0 ) ? 963 stats.counters[STAT_NAME].calls_0 += 1; 964 else 965 #endif // __NONNULL_0_ALLOC__ 966 stats.counters[STAT_NAME].calls += 1; 958 stats.counters[STAT_NAME].calls += 1; 967 959 stats.counters[STAT_NAME].request += size; 968 960 #endif // __STATISTICS__ … … 1086 1078 1087 1079 static void doFree( void * addr ) libcfa_nopreempt with( *heapManager ) { 1088 // char buf[64];1089 // int len = sprintf( buf, "doFree addr %p\n", addr );1090 // write( 2, buf, len );1091 1092 1080 verify( addr ); 1093 1081 … … 1103 1091 #endif // __STATISTICS__ || __CFA_DEBUG__ 1104 1092 1105 // Do not move these down because heap can be null!1106 1093 #ifdef __STATISTICS__ 1107 #ifdef __NONNULL_0_ALLOC__1108 if ( unlikely( rsize == 0 ) ) // malloc( 0 ) ?1109 stats.free_null_0_calls += 1;1110 else1111 #endif // __NONNULL_0_ALLOC__1112 heapManager->stats.free_calls += 1; // count free amd implicit frees from resize/realloc1113 1094 stats.free_storage_request += rsize; 1114 1095 stats.free_storage_alloc += size; … … 1136 1117 } // if 1137 1118 } else { 1138 assert( freeHead );1139 1119 #ifdef __CFA_DEBUG__ 1140 1120 // memset is NOT always inlined! … … 1341 1321 // call to malloc(), alloc(), calloc() or realloc(). If the area pointed to was moved, a free(oaddr) is done. 1342 1322 void * resize( void * oaddr, size_t size ) libcfa_public { 1343 if ( unlikely( oaddr == 0p ) ) { // => malloc( size )1323 if ( unlikely( oaddr == 0p ) ) { // => malloc( size ) 1344 1324 return doMalloc( size STAT_ARG( RESIZE ) ); 1345 1325 } // if … … 1353 1333 1354 1334 size_t odsize = DataStorage( bsize, oaddr, header ); // data storage available in bucket 1355 // same size, DO NOT PRESERVESTICKY PROPERTIES.1335 // same size, DO NOT preserve STICKY PROPERTIES. 1356 1336 if ( oalign == libAlign() && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size 1357 1337 ClearZeroFillBit( header ); // no alignment and turn off 0 fill … … 1366 1346 } // if 1367 1347 1368 // change size, DO NOT PRESERVESTICKY PROPERTIES.1348 // change size, DO NOT preserve STICKY PROPERTIES. 1369 1349 doFree( oaddr ); // free previous storage 1370 1350 … … 1376 1356 // the old and new sizes. 1377 1357 void * realloc( void * oaddr, size_t size ) libcfa_public { 1378 // char buf[64];1379 // int len = sprintf( buf, "realloc1 oaddr %p size %d\n", oaddr, size );1380 // write( 2, buf, len );1381 1358 if ( unlikely( oaddr == 0p ) ) { // => malloc( size ) 1382 1359 return doMalloc( size STAT_ARG( REALLOC ) ); … … 1521 1498 } // if 1522 1499 1500 #ifdef __STATISTICS__ 1501 incCalls( FREE ); 1502 #endif // __STATISTICS__ 1503 1523 1504 doFree( addr ); // handles heapManager == nullptr 1524 1505 } // free … … 1598 1579 #endif // __STATISTICS__ 1599 1580 } // malloc_stats_clear 1581 1600 1582 1601 1583 // Changes the file descriptor where malloc_stats() writes statistics. … … 1718 1700 } // if 1719 1701 1720 // change size, DO NOT PRESERVESTICKY PROPERTIES.1702 // change size, DO NOT preserve STICKY PROPERTIES. 1721 1703 doFree( oaddr ); // free previous storage 1722 1704 return memalignNoStats( nalign, size STAT_ARG( RESIZE ) ); // create new aligned area … … 1725 1707 1726 1708 void * realloc( void * oaddr, size_t nalign, size_t size ) libcfa_public { 1727 // char buf[64];1728 // int len = sprintf( buf, "realloc2 oaddr %p size %d\n", oaddr, size );1729 // write( 2, buf, len );1730 1709 if ( unlikely( oaddr == 0p ) ) { // => malloc( size ) 1731 1710 return memalignNoStats( nalign, size STAT_ARG( REALLOC ) ); -
libcfa/src/heap.hfa
rb78c54f rab780e6 10 10 // Created On : Tue May 26 11:23:55 2020 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Apr 1 09:36:20 202413 // Update Count : 2 512 // Last Modified On : Mon Sep 11 11:18:18 2023 13 // Update Count : 24 14 14 // 15 15 … … 46 46 } // extern "C" 47 47 48 // New allocation operations.49 48 void * resize( void * oaddr, size_t alignment, size_t size ); 50 49 void * realloc( void * oaddr, size_t alignment, size_t size ); … … 52 51 53 52 // Local Variables: // 53 // mode: c // 54 54 // tab-width: 4 // 55 55 // End: // -
libcfa/src/stdlib.hfa
rb78c54f rab780e6 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Apr 12 07:39:15202413 // Update Count : 81212 // Last Modified On : Sun Mar 17 08:25:31 2024 13 // Update Count : 796 14 14 // 15 15 … … 109 109 1. Replace the current forall-block that contains defintions of S_fill and S_realloc with following: 110 110 forall( T & | sized(T) ) { 111 union U_fill { char c; T * a; T t; };112 struct S_fill { char tag; U_fill(T) fill; };113 struct S_realloc { inline T *; };111 union U_fill { char c; T * a; T t; }; 112 struct S_fill { char tag; U_fill(T) fill; }; 113 struct S_realloc { inline T *; }; 114 114 } 115 115 116 116 2. Replace all current postfix-fill functions with following for updated S_fill: 117 S_fill(T) ?`fill( char a ) { S_fill(T) ret = {'c'}; ret.fill.c = a; return ret; }118 S_fill(T) ?`fill( T a ){ S_fill(T) ret = {'t'}; memcpy(&ret.fill.t, &a, sizeof(T)); return ret; }119 S_fill(T) ?`fill( T a[], size_t nmemb ){ S_fill(T) ret = {'a', nmemb}; ret.fill.a = a; return ret; }117 S_fill(T) ?`fill( char a ) { S_fill(T) ret = {'c'}; ret.fill.c = a; return ret; } 118 S_fill(T) ?`fill( T a ) { S_fill(T) ret = {'t'}; memcpy(&ret.fill.t, &a, sizeof(T)); return ret; } 119 S_fill(T) ?`fill( T a[], size_t nmemb ) { S_fill(T) ret = {'a', nmemb}; ret.fill.a = a; return ret; } 120 120 121 121 3. Replace the alloc_internal$ function which is outside ttype forall-block with following function: … … 148 148 */ 149 149 150 typedef struct S_align { inline size_t; } T_align;151 typedef struct S_resize { inline void *; } T_resize;150 typedef struct S_align { inline size_t; } T_align; 151 typedef struct S_resize { inline void *; } T_resize; 152 152 153 153 forall( T & ) { 154 struct S_fill { char tag; char c; size_t size; T * at; char t[50]; };155 struct S_realloc { inline T *; };154 struct S_fill { char tag; char c; size_t size; T * at; char t[50]; }; 155 struct S_realloc { inline T *; }; 156 156 } 157 157 158 static inline T_align ?`align( size_t a ) { return (T_align){a}; } 159 static inline T_resize ?`resize( void * a ) { return (T_resize){a}; } 160 161 extern "C" ssize_t write(int fd, const void *buf, size_t count); 158 static inline T_align ?`align ( size_t a ) { return (T_align){a}; } 159 static inline T_resize ?`resize ( void * a ) { return (T_resize){a}; } 160 162 161 static inline forall( T & | sized(T) ) { 163 162 S_fill(T) ?`fill ( T t ) { … … 170 169 return ret; 171 170 } 172 S_fill(T) ?`fill ( zero_t ) = void; // FIX ME: remove this once ticket 214 is resolved173 S_fill(T) ?`fill ( T * a ){ return (S_fill(T)){ 'T', '0', 0, a }; } // FIX ME: remove this once ticket 214 is resolved174 S_fill(T) ?`fill ( char c ){ return (S_fill(T)){ 'c', c }; }175 S_fill(T) ?`fill ( T a[], size_t nmemb ){ return (S_fill(T)){ 'a', '0', nmemb * sizeof(T), a }; }176 177 S_realloc(T) ?`realloc ( T * a ){ return (S_realloc(T)){a}; }171 S_fill(T) ?`fill ( zero_t ) = void; // FIX ME: remove this once ticket 214 is resolved 172 S_fill(T) ?`fill ( T * a ) { return (S_fill(T)){ 'T', '0', 0, a }; } // FIX ME: remove this once ticket 214 is resolved 173 S_fill(T) ?`fill ( char c ) { return (S_fill(T)){ 'c', c }; } 174 S_fill(T) ?`fill ( T a[], size_t nmemb ) { return (S_fill(T)){ 'a', '0', nmemb * sizeof(T), a }; } 175 176 S_realloc(T) ?`realloc ( T * a ) { return (S_realloc(T)){a}; } 178 177 179 178 T * alloc_internal$( void * Resize, T * Realloc, size_t Align, size_t Dim, S_fill(T) Fill ) { … … 183 182 184 183 if ( Resize ) { 185 ptr = (T*) (void *)resize( (void *)Resize, Align, Dim * size );184 ptr = (T*) (void *) resize( (void *)Resize, Align, Dim * size ); 186 185 } else if ( Realloc ) { 187 186 if ( Fill.tag != '0' ) copy_end = min(malloc_size( Realloc ), Dim * size ); 188 ptr = (T *) (void *)realloc( (void *)Realloc, Align, Dim * size );187 ptr = (T *) (void *) realloc( (void *)Realloc, Align, Dim * size ); 189 188 } else { 190 ptr = (T *) (void *) memalign( Align, Dim * size );189 ptr = (T *) (void *) memalign( Align, Dim * size ); 191 190 } 192 191
Note:
See TracChangeset
for help on using the changeset viewer.