Changeset 032234bd for libcfa/src/heap.cfa
- Timestamp:
- May 16, 2022, 12:04:23 PM (23 months ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
- Children:
- 108345a
- Parents:
- d8454b9
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/heap.cfa
rd8454b9 r032234bd 36 36 static bool traceHeap = false; 37 37 38 inline bool traceHeap() { return traceHeap; }39 40 bool traceHeapOn() {38 inline bool traceHeap() libcfa_public { return traceHeap; } 39 40 bool traceHeapOn() libcfa_public { 41 41 bool temp = traceHeap; 42 42 traceHeap = true; … … 44 44 } // traceHeapOn 45 45 46 bool traceHeapOff() {46 bool traceHeapOff() libcfa_public { 47 47 bool temp = traceHeap; 48 48 traceHeap = false; … … 50 50 } // traceHeapOff 51 51 52 bool traceHeapTerm() { return false; }52 bool traceHeapTerm() libcfa_public { return false; } 53 53 54 54 55 55 static bool prtFree = false; 56 56 57 bool prtFree() {57 static bool prtFree() { 58 58 return prtFree; 59 59 } // prtFree 60 60 61 bool prtFreeOn() {61 static bool prtFreeOn() { 62 62 bool temp = prtFree; 63 63 prtFree = true; … … 65 65 } // prtFreeOn 66 66 67 bool prtFreeOff() {67 static bool prtFreeOff() { 68 68 bool temp = prtFree; 69 69 prtFree = false; … … 388 388 static unsigned int maxBucketsUsed; // maximum number of buckets in use 389 389 // extern visibility, used by runtime kernel 390 size_t __page_size; // architecture pagesize 391 int __map_prot; // common mmap/mprotect protection 390 // would be cool to remove libcfa_public but it's needed for libcfathread 391 libcfa_public size_t __page_size; // architecture pagesize 392 libcfa_public int __map_prot; // common mmap/mprotect protection 392 393 393 394 … … 727 728 728 729 729 s ize_t prtFree( Heap & manager ) with( manager ) {730 static size_t prtFree( Heap & manager ) with( manager ) { 730 731 size_t total = 0; 731 732 #ifdef __STATISTICS__ … … 879 880 // Allocates size bytes and returns a pointer to the allocated memory. The contents are undefined. If size is 0, 880 881 // then malloc() returns a unique pointer value that can later be successfully passed to free(). 881 void * malloc( size_t size ) {882 void * malloc( size_t size ) libcfa_public { 882 883 #ifdef __STATISTICS__ 883 884 if ( likely( size > 0 ) ) { … … 894 895 895 896 // Same as malloc() except size bytes is an array of dim elements each of elemSize bytes. 896 void * aalloc( size_t dim, size_t elemSize ) {897 void * aalloc( size_t dim, size_t elemSize ) libcfa_public { 897 898 size_t size = dim * elemSize; 898 899 #ifdef __STATISTICS__ … … 910 911 911 912 // Same as aalloc() with memory set to zero. 912 void * calloc( size_t dim, size_t elemSize ) {913 void * calloc( size_t dim, size_t elemSize ) libcfa_public { 913 914 size_t size = dim * elemSize; 914 915 if ( unlikely( size ) == 0 ) { // 0 BYTE ALLOCATION RETURNS NULL POINTER … … 951 952 // not 0p, then the call is equivalent to free(oaddr). Unless oaddr is 0p, it must have been returned by an earlier 952 953 // call to malloc(), alloc(), calloc() or realloc(). If the area pointed to was moved, a free(oaddr) is done. 953 void * resize( void * oaddr, size_t size ) {954 void * resize( void * oaddr, size_t size ) libcfa_public { 954 955 // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned. 955 956 if ( unlikely( size == 0 ) ) { // special cases … … 996 997 // Same as resize() but the contents are unchanged in the range from the start of the region up to the minimum of 997 998 // the old and new sizes. 998 void * realloc( void * oaddr, size_t size ) {999 void * realloc( void * oaddr, size_t size ) libcfa_public { 999 1000 // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned. 1000 1001 if ( unlikely( size == 0 ) ) { // special cases … … 1060 1061 1061 1062 // Same as realloc() except the new allocation size is large enough for an array of nelem elements of size elsize. 1062 void * reallocarray( void * oaddr, size_t dim, size_t elemSize ) {1063 void * reallocarray( void * oaddr, size_t dim, size_t elemSize ) libcfa_public { 1063 1064 return realloc( oaddr, dim * elemSize ); 1064 1065 } // reallocarray … … 1066 1067 1067 1068 // Same as malloc() except the memory address is a multiple of alignment, which must be a power of two. (obsolete) 1068 void * memalign( size_t alignment, size_t size ) {1069 void * memalign( size_t alignment, size_t size ) libcfa_public { 1069 1070 #ifdef __STATISTICS__ 1070 1071 if ( likely( size > 0 ) ) { … … 1081 1082 1082 1083 // Same as aalloc() with memory alignment. 1083 void * amemalign( size_t alignment, size_t dim, size_t elemSize ) {1084 void * amemalign( size_t alignment, size_t dim, size_t elemSize ) libcfa_public { 1084 1085 size_t size = dim * elemSize; 1085 1086 #ifdef __STATISTICS__ … … 1097 1098 1098 1099 // Same as calloc() with memory alignment. 1099 void * cmemalign( size_t alignment, size_t dim, size_t elemSize ) {1100 void * cmemalign( size_t alignment, size_t dim, size_t elemSize ) libcfa_public { 1100 1101 size_t size = dim * elemSize; 1101 1102 if ( unlikely( size ) == 0 ) { // 0 BYTE ALLOCATION RETURNS NULL POINTER … … 1136 1137 // Same as memalign(), but ISO/IEC 2011 C11 Section 7.22.2 states: the value of size shall be an integral multiple 1137 1138 // of alignment. This requirement is universally ignored. 1138 void * aligned_alloc( size_t alignment, size_t size ) {1139 void * aligned_alloc( size_t alignment, size_t size ) libcfa_public { 1139 1140 return memalign( alignment, size ); 1140 1141 } // aligned_alloc … … 1145 1146 // is 0, then posix_memalign() returns either 0p, or a unique pointer value that can later be successfully passed to 1146 1147 // free(3). 1147 int posix_memalign( void ** memptr, size_t alignment, size_t size ) {1148 int posix_memalign( void ** memptr, size_t alignment, size_t size ) libcfa_public { 1148 1149 if ( unlikely( alignment < libAlign() || ! is_pow2( alignment ) ) ) return EINVAL; // check alignment 1149 1150 *memptr = memalign( alignment, size ); … … 1154 1155 // Allocates size bytes and returns a pointer to the allocated memory. The memory address shall be a multiple of the 1155 1156 // page size. It is equivalent to memalign(sysconf(_SC_PAGESIZE),size). 1156 void * valloc( size_t size ) {1157 void * valloc( size_t size ) libcfa_public { 1157 1158 return memalign( __page_size, size ); 1158 1159 } // valloc … … 1160 1161 1161 1162 // Same as valloc but rounds size to multiple of page size. 1162 void * pvalloc( size_t size ) {1163 void * pvalloc( size_t size ) libcfa_public { 1163 1164 return memalign( __page_size, ceiling2( size, __page_size ) ); // round size to multiple of page size 1164 1165 } // pvalloc … … 1168 1169 // or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behaviour occurs. If ptr is 1169 1170 // 0p, no operation is performed. 1170 void free( void * addr ) {1171 void free( void * addr ) libcfa_public { 1171 1172 if ( unlikely( addr == 0p ) ) { // special case 1172 1173 #ifdef __STATISTICS__ … … 1189 1190 1190 1191 // Returns the alignment of an allocation. 1191 size_t malloc_alignment( void * addr ) {1192 size_t malloc_alignment( void * addr ) libcfa_public { 1192 1193 if ( unlikely( addr == 0p ) ) return libAlign(); // minimum alignment 1193 1194 Heap.Storage.Header * header = HeaderAddr( addr ); … … 1201 1202 1202 1203 // Returns true if the allocation is zero filled, e.g., allocated by calloc(). 1203 bool malloc_zero_fill( void * addr ) {1204 bool malloc_zero_fill( void * addr ) libcfa_public { 1204 1205 if ( unlikely( addr == 0p ) ) return false; // null allocation is not zero fill 1205 1206 Heap.Storage.Header * header = HeaderAddr( addr ); … … 1212 1213 1213 1214 // Returns original total allocation size (not bucket size) => array size is dimension * sizeof(T). 1214 size_t malloc_size( void * addr ) {1215 size_t malloc_size( void * addr ) libcfa_public { 1215 1216 if ( unlikely( addr == 0p ) ) return 0; // null allocation has zero size 1216 1217 Heap.Storage.Header * header = HeaderAddr( addr ); … … 1224 1225 // Returns the number of usable bytes in the block pointed to by ptr, a pointer to a block of memory allocated by 1225 1226 // malloc or a related function. 1226 size_t malloc_usable_size( void * addr ) {1227 size_t malloc_usable_size( void * addr ) libcfa_public { 1227 1228 if ( unlikely( addr == 0p ) ) return 0; // null allocation has 0 size 1228 1229 Heap.Storage.Header * header; … … 1236 1237 1237 1238 // Prints (on default standard error) statistics about memory allocated by malloc and related functions. 1238 void malloc_stats( void ) {1239 void malloc_stats( void ) libcfa_public { 1239 1240 #ifdef __STATISTICS__ 1240 1241 printStats(); … … 1245 1246 1246 1247 // Changes the file descriptor where malloc_stats() writes statistics. 1247 int malloc_stats_fd( int fd __attribute__(( unused )) ) {1248 int malloc_stats_fd( int fd __attribute__(( unused )) ) libcfa_public { 1248 1249 #ifdef __STATISTICS__ 1249 1250 int temp = stats_fd; … … 1259 1260 // The string is printed on the file stream stream. The exported string includes information about all arenas (see 1260 1261 // malloc). 1261 int malloc_info( int options, FILE * stream __attribute__(( unused )) ) {1262 int malloc_info( int options, FILE * stream __attribute__(( unused )) ) libcfa_public { 1262 1263 if ( options != 0 ) { errno = EINVAL; return -1; } 1263 1264 #ifdef __STATISTICS__ … … 1271 1272 // Adjusts parameters that control the behaviour of the memory-allocation functions (see malloc). The param argument 1272 1273 // specifies the parameter to be modified, and value specifies the new value for that parameter. 1273 int mallopt( int option, int value ) {1274 int mallopt( int option, int value ) libcfa_public { 1274 1275 if ( value < 0 ) return 0; 1275 1276 choose( option ) { … … 1285 1286 1286 1287 // Attempt to release free memory at the top of the heap (by calling sbrk with a suitable argument). 1287 int malloc_trim( size_t ) {1288 int malloc_trim( size_t ) libcfa_public { 1288 1289 return 0; // => impossible to release memory 1289 1290 } // malloc_trim … … 1294 1295 // structure dynamically allocated via malloc, and a pointer to that data structure is returned as the function 1295 1296 // result. (The caller must free this memory.) 1296 void * malloc_get_state( void ) {1297 void * malloc_get_state( void ) libcfa_public { 1297 1298 return 0p; // unsupported 1298 1299 } // malloc_get_state … … 1301 1302 // Restores the state of all malloc internal bookkeeping variables to the values recorded in the opaque data 1302 1303 // structure pointed to by state. 1303 int malloc_set_state( void * ) {1304 int malloc_set_state( void * ) libcfa_public { 1304 1305 return 0; // unsupported 1305 1306 } // malloc_set_state … … 1307 1308 1308 1309 // Sets the amount (bytes) to extend the heap when there is insufficent free storage to service an allocation. 1309 __attribute__((weak)) size_t malloc_expansion() { return __CFA_DEFAULT_HEAP_EXPANSION__; }1310 __attribute__((weak)) size_t malloc_expansion() libcfa_public { return __CFA_DEFAULT_HEAP_EXPANSION__; } 1310 1311 1311 1312 // Sets the crossover point between allocations occuring in the sbrk area or separately mmapped. 1312 __attribute__((weak)) size_t malloc_mmap_start() { return __CFA_DEFAULT_MMAP_START__; }1313 __attribute__((weak)) size_t malloc_mmap_start() libcfa_public { return __CFA_DEFAULT_MMAP_START__; } 1313 1314 1314 1315 // Amount subtracted to adjust for unfreed program storage (debug only). 1315 __attribute__((weak)) size_t malloc_unfreed() { return __CFA_DEFAULT_HEAP_UNFREED__; }1316 __attribute__((weak)) size_t malloc_unfreed() libcfa_public { return __CFA_DEFAULT_HEAP_UNFREED__; } 1316 1317 } // extern "C" 1317 1318 1318 1319 1319 1320 // Must have CFA linkage to overload with C linkage realloc. 1320 void * resize( void * oaddr, size_t nalign, size_t size ) {1321 void * resize( void * oaddr, size_t nalign, size_t size ) libcfa_public { 1321 1322 // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned. 1322 1323 if ( unlikely( size == 0 ) ) { // special cases … … 1380 1381 1381 1382 1382 void * realloc( void * oaddr, size_t nalign, size_t size ) {1383 void * realloc( void * oaddr, size_t nalign, size_t size ) libcfa_public { 1383 1384 // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned. 1384 1385 if ( unlikely( size == 0 ) ) { // special cases
Note: See TracChangeset
for help on using the changeset viewer.