Changeset 8ee54963 for libcfa/src
- Timestamp:
- Dec 28, 2022, 12:49:41 PM (2 years ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- d9585291
- Parents:
- ea2ed3a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/heap.cfa
rea2ed3a r8ee54963 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Oct 30 20:56:20202213 // Update Count : 15 8412 // Last Modified On : Wed Dec 28 12:37:38 2022 13 // Update Count : 1597 14 14 // 15 15 … … 17 17 #include <string.h> // memset, memcpy 18 18 #include <limits.h> // ULONG_MAX 19 #include <stdlib.h> // EXIT_FAILURE20 19 #include <errno.h> // errno, ENOMEM, EINVAL 21 #include <unistd.h> // STDERR_FILENO, sbrk, sysconf 22 #include <malloc.h> // memalign, malloc_usable_size 20 #include <unistd.h> // STDERR_FILENO, sbrk, sysconf, write 23 21 #include <sys/mman.h> // mmap, munmap 24 22 extern "C" { … … 26 24 } // extern "C" 27 25 26 #include "heap.hfa" 28 27 #include "bits/align.hfa" // libAlign 29 28 #include "bits/defs.hfa" // likely, unlikely … … 140 139 #endif 141 140 142 typedef volatile uintptr_t SpinLock_t CALIGN; // aligned addressable word-size141 typedef volatile uintptr_t SpinLock_t; 143 142 144 143 static inline __attribute__((always_inline)) void lock( volatile SpinLock_t & slock ) { … … 147 146 148 147 for ( unsigned int i = 1;; i += 1 ) { 149 if ( slock == 0 && __atomic_test_and_set( &slock, __ATOMIC_ SEQ_CST) == 0 ) break; // Fence148 if ( slock == 0 && __atomic_test_and_set( &slock, __ATOMIC_ACQUIRE ) == 0 ) break; // Fence 150 149 for ( volatile unsigned int s = 0; s < spin; s += 1 ) Pause(); // exponential spin 151 150 spin += spin; // powers of 2 … … 156 155 157 156 static inline __attribute__((always_inline)) void unlock( volatile SpinLock_t & slock ) { 158 __atomic_clear( &slock, __ATOMIC_ SEQ_CST); // Fence157 __atomic_clear( &slock, __ATOMIC_RELEASE ); // Fence 159 158 } // spin_unlock 160 159 … … 261 260 static_assert( libAlign() >= sizeof( Storage ), "minimum alignment < sizeof( Storage )" ); 262 261 263 struct __attribute__(( aligned (8) ))FreeHeader {264 size_t blockSize __attribute__(( aligned(8) ));// size of allocations on this list262 struct CALIGN FreeHeader { 263 size_t blockSize CALIGN; // size of allocations on this list 265 264 #ifdef OWNERSHIP 266 265 #ifdef RETURNSPIN … … 284 283 285 284 #ifdef __CFA_DEBUG__ 286 int64_t allocUnfreed; // running total of allocations minus frees; can be negative285 ptrdiff_t allocUnfreed; // running total of allocations minus frees; can be negative 287 286 #endif // __CFA_DEBUG__ 288 287 … … 369 368 // Thread-local storage is allocated lazily when the storage is accessed. 370 369 static __thread size_t PAD1 CALIGN TLSMODEL __attribute__(( unused )); // protect false sharing 371 static __thread Heap * volatileheapManager CALIGN TLSMODEL;370 static __thread Heap * heapManager CALIGN TLSMODEL; 372 371 static __thread size_t PAD2 CALIGN TLSMODEL __attribute__(( unused )); // protect further false sharing 373 372 … … 443 442 // 12K ~= 120K byte superblock. Where 128-heap superblock handles a medium sized multi-processor server. 444 443 size_t remaining = heapManagersStorageEnd - heapManagersStorage; // remaining free heaps in superblock 445 if ( ! heapManagersStorage || remaining != 0 ) {444 if ( ! heapManagersStorage || remaining == 0 ) { 446 445 // Each block of heaps is a multiple of the number of cores on the computer. 447 446 int HeapDim = get_nprocs(); // get_nprocs_conf does not work … … 562 561 // allocUnfreed is set to 0 when a heap is created and it accumulates any unfreed storage during its multiple thread 563 562 // usages. At the end, add up each heap allocUnfreed value across all heaps to get the total unfreed storage. 564 int64_t allocUnfreed = 0;563 ptrdiff_t allocUnfreed = 0; 565 564 for ( Heap * heap = heapMaster.heapManagersList; heap; heap = heap->nextHeapManager ) { 566 565 allocUnfreed += heap->allocUnfreed; … … 572 571 char helpText[512]; 573 572 __cfaabi_bits_print_buffer( STDERR_FILENO, helpText, sizeof(helpText), 574 "CFA warning (UNIX pid:%ld) : program terminating with % ju(0x%jx) bytes of storage allocated but not freed.\n"573 "CFA warning (UNIX pid:%ld) : program terminating with %td(%#tx) bytes of storage allocated but not freed.\n" 575 574 "Possible cause is unfreed storage allocated by the program or system/library routines called from the program.\n", 576 575 (long int)getpid(), allocUnfreed, allocUnfreed ); // always print the UNIX pid … … 950 949 block = freeHead->freeList; // remove node from stack 951 950 if ( unlikely( block == 0p ) ) { // no free block ? 952 // Freelist for this size is empty, so check return list (OWNERSHIP), carve it out of the heap,if there951 // Freelist for this size is empty, so check return list (OWNERSHIP), or carve it out of the heap if there 953 952 // is enough left, or get some more heap storage and carve it off. 954 953 #ifdef OWNERSHIP … … 1115 1114 while ( ! __atomic_compare_exchange_n( &freeHead->returnList, &header->kind.real.next, (Heap.Storage *)header, 1116 1115 false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ); 1116 1117 #ifdef __STATISTICS__ 1118 stats.return_pushes += 1; 1119 stats.return_storage_request += rsize; 1120 stats.return_storage_alloc += size; 1121 #endif // __STATISTICS__ 1117 1122 #endif // RETURNSPIN 1118 1123 } // if … … 1125 1130 freeHead->freeList = (Heap.Storage *)header; 1126 1131 #endif // ! OWNERSHIP 1127 1128 #ifdef __U_STATISTICS__1129 stats.return_pushes += 1;1130 stats.return_storage_request += rsize;1131 stats.return_storage_alloc += size;1132 #endif // __U_STATISTICS__1133 1132 1134 1133 // OK TO BE PREEMPTED HERE AS heapManager IS NO LONGER ACCESSED. … … 1180 1179 1181 1180 #ifdef __STATISTICS__ 1182 static void incCalls( intptr_t statName ) libcfa_nopreempt {1181 static void incCalls( size_t statName ) libcfa_nopreempt { 1183 1182 heapManager->stats.counters[statName].calls += 1; 1184 1183 } // incCalls 1185 1184 1186 static void incZeroCalls( intptr_t statName ) libcfa_nopreempt {1185 static void incZeroCalls( size_t statName ) libcfa_nopreempt { 1187 1186 heapManager->stats.counters[statName].calls_0 += 1; 1188 1187 } // incZeroCalls … … 1456 1455 // 0p, no operation is performed. 1457 1456 void free( void * addr ) libcfa_public { 1458 // verify( heapManager );1459 1460 1457 if ( unlikely( addr == 0p ) ) { // special case 1461 1458 #ifdef __STATISTICS__
Note: See TracChangeset
for help on using the changeset viewer.