Changeset 76e2113


Ignore:
Timestamp:
Apr 18, 2020, 9:08:12 AM (4 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
692e6f1
Parents:
899dfbb
Message:

add setter routines for sticky operations, add allocation size to header

Location:
libcfa/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/heap.cfa

    r899dfbb r76e2113  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Apr  1 15:59:53 2020
    13 // Update Count     : 692
     12// Last Modified On : Sat Apr 18 08:17:53 2020
     13// Update Count     : 716
    1414//
    1515
     
    181181                                } fake; // FakeHeader
    182182                        } kind; // Kind
    183                         uint32_t dimension;                                                     // used by calloc-like to remember number of array elements
     183                        size_t size;                                                            // allocation size in bytes
    184184                } header; // Header
    185185                char pad[libAlign() - sizeof( Header )];
     
    265265static unsigned long long int free_storage;
    266266static unsigned int free_calls;
     267static unsigned long long int aalloc_storage;
     268static unsigned int aalloc_calls;
    267269static unsigned long long int calloc_storage;
    268270static unsigned int calloc_calls;
    269271static unsigned long long int memalign_storage;
    270272static unsigned int memalign_calls;
     273static unsigned long long int amemalign_storage;
     274static unsigned int amemalign_calls;
    271275static unsigned long long int cmemalign_storage;
    272276static unsigned int cmemalign_calls;
     
    280284// Use "write" because streams may be shutdown when calls are made.
    281285static void printStats() {
    282         char helpText[512];
     286        char helpText[1024];
    283287        __cfaabi_bits_print_buffer( STDERR_FILENO, helpText, sizeof(helpText),
    284288                                                                        "\nHeap statistics:\n"
    285289                                                                        "  malloc: calls %u / storage %llu\n"
     290                                                                        "  aalloc: calls %u / storage %llu\n"
    286291                                                                        "  calloc: calls %u / storage %llu\n"
    287292                                                                        "  memalign: calls %u / storage %llu\n"
     293                                                                        "  amemalign: calls %u / storage %llu\n"
    288294                                                                        "  cmemalign: calls %u / storage %llu\n"
    289295                                                                        "  resize: calls %u / storage %llu\n"
     
    294300                                                                        "  sbrk: calls %u / storage %llu\n",
    295301                                                                        malloc_calls, malloc_storage,
     302                                                                        aalloc_calls, calloc_storage,
    296303                                                                        calloc_calls, calloc_storage,
    297304                                                                        memalign_calls, memalign_storage,
     305                                                                        amemalign_calls, amemalign_storage,
    298306                                                                        cmemalign_calls, cmemalign_storage,
    299307                                                                        resize_calls, resize_storage,
     
    307315
    308316static int printStatsXML( FILE * stream ) {                             // see malloc_info
    309         char helpText[512];
     317        char helpText[1024];
    310318        int len = snprintf( helpText, sizeof(helpText),
    311319                                                "<malloc version=\"1\">\n"
     
    314322                                                "</sizes>\n"
    315323                                                "<total type=\"malloc\" count=\"%u\" size=\"%llu\"/>\n"
     324                                                "<total type=\"aalloc\" count=\"%u\" size=\"%llu\"/>\n"
    316325                                                "<total type=\"calloc\" count=\"%u\" size=\"%llu\"/>\n"
    317326                                                "<total type=\"memalign\" count=\"%u\" size=\"%llu\"/>\n"
     327                                                "<total type=\"amemalign\" count=\"%u\" size=\"%llu\"/>\n"
    318328                                                "<total type=\"cmemalign\" count=\"%u\" size=\"%llu\"/>\n"
    319329                                                "<total type=\"resize\" count=\"%u\" size=\"%llu\"/>\n"
     
    325335                                                "</malloc>",
    326336                                                malloc_calls, malloc_storage,
     337                                                aalloc_calls, aalloc_storage,
    327338                                                calloc_calls, calloc_storage,
    328339                                                memalign_calls, memalign_storage,
     340                                                amemalign_calls, amemalign_storage,
    329341                                                cmemalign_calls, cmemalign_storage,
    330342                                                resize_calls, resize_storage,
     
    566578        } // if
    567579
     580        block->header.size = size;                                                      // store allocation size
    568581        void * addr = &(block->data);                                           // adjust off header to user bytes
    569582
     
    734747        //assert( heapManager.heapBegin != 0 );
    735748        if ( unlikely( heapManager.heapBegin == 0p ) ) heapManager{}; // called before memory_startup ?
     749#if __SIZEOF_POINTER__ == 8
     750        verify( size < ((typeof(size_t))1 << 48) );
     751#endif // __SIZEOF_POINTER__ == 8
    736752        void * addr = doMalloc( size );
    737753        if ( unlikely( addr == 0p ) ) errno = ENOMEM;           // POSIX
     
    740756
    741757
    742 static inline void * callocNoStats( size_t noOfElems, size_t elemSize ) {
    743         size_t size = noOfElems * elemSize;
     758static inline void * callocNoStats( size_t dim, size_t elemSize ) {
     759        size_t size = dim * elemSize;
    744760        char * addr = (char *)mallocNoStats( size );
    745761  if ( unlikely( addr == 0p ) ) return 0p;
     
    758774                memset( addr, '\0', bsize - sizeof(HeapManager.Storage) ); // set to zeros
    759775
    760         assert( noOfElems <= UINT32_MAX );
    761         header->dimension = noOfElems;                                          // store number of array elements
    762776        header->kind.real.blockSize |= 2;                                       // mark as zero filled
    763777        return addr;
     
    801815
    802816
    803 static inline void * cmemalignNoStats( size_t alignment, size_t noOfElems, size_t elemSize ) {
    804         size_t size = noOfElems * elemSize;
     817static inline void * cmemalignNoStats( size_t alignment, size_t dim, size_t elemSize ) {
     818        size_t size = dim * elemSize;
    805819        char * addr = (char *)memalignNoStats( alignment, size );
    806820  if ( unlikely( addr == 0p ) ) return 0p;
     
    815829                memset( addr, '\0', dataStorage( bsize, addr, header ) ); // set to zeros
    816830
    817         assert( noOfElems <= UINT32_MAX );
    818         header->dimension = noOfElems;                                          // store initial array size
    819831        header->kind.real.blockSize |= 2;                                       // mark as zero filled
    820832        return addr;
     
    843855        } // malloc
    844856
    845         // Allocate memory for an array of nmemb elements of size bytes each and returns a pointer to the allocated
    846         // memory. The memory is set to zero. If nmemb or size is 0, then calloc() returns either 0p, or a unique pointer
    847         // value that can later be successfully passed to free().
    848         void * calloc( size_t noOfElems, size_t elemSize ) {
     857
     858        // Allocate memory for an array of dim elements of size bytes each and returns a pointer to the allocated memory. If
     859        // dim or size is 0, then calloc() returns either 0p, or a unique pointer value that can later be successfully
     860        // passed to free().
     861        void * aalloc( size_t dim, size_t elemSize ) {
     862                #ifdef __STATISTICS__
     863                __atomic_add_fetch( &aalloc_calls, 1, __ATOMIC_SEQ_CST );
     864                __atomic_add_fetch( &aalloc_storage, dim * elemSize, __ATOMIC_SEQ_CST );
     865                #endif // __STATISTICS__
     866
     867                size_t size = dim * elemSize;
     868                char * addr = (char *)mallocNoStats( size );
     869          if ( unlikely( addr == 0p ) ) return 0p;
     870
     871                HeapManager.Storage.Header * header;
     872                HeapManager.FreeHeader * freeElem;
     873                size_t bsize, alignment;
     874                headers( "aalloc", addr, header, freeElem, bsize, alignment );
     875
     876                header->kind.real.blockSize |= 2;                               // mark as zero filled
     877                return addr;
     878        } // aalloc
     879
     880
     881        // Same as aalloc() with memory is set to zero.
     882        void * calloc( size_t dim, size_t elemSize ) {
    849883                #ifdef __STATISTICS__
    850884                __atomic_add_fetch( &calloc_calls, 1, __ATOMIC_SEQ_CST );
    851                 __atomic_add_fetch( &calloc_storage, noOfElems * elemSize, __ATOMIC_SEQ_CST );
    852                 #endif // __STATISTICS__
    853 
    854                 return callocNoStats( noOfElems, elemSize );
     885                __atomic_add_fetch( &calloc_storage, dim * elemSize, __ATOMIC_SEQ_CST );
     886                #endif // __STATISTICS__
     887
     888                return callocNoStats( dim, elemSize );
    855889        } // calloc
    856890
     
    874908                size_t bsize, oalign = 0;
    875909                headers( "resize", oaddr, header, freeElem, bsize, oalign );
     910
    876911                size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
    877 
    878912                // same size, DO NOT preserve STICKY PROPERTIES.
    879                 if ( oalign == 0 && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size
     913          if ( oalign == 0 && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size
    880914                        header->kind.real.blockSize &= -2;                      // no alignment and turn off 0 fill
    881915                        return oaddr;
     
    951985
    952986
     987        // Same as aalloc() with memory alignment.
     988        void * amemalign( size_t alignment, size_t dim, size_t elemSize ) {
     989                #ifdef __STATISTICS__
     990                __atomic_add_fetch( &cmemalign_calls, 1, __ATOMIC_SEQ_CST );
     991                __atomic_add_fetch( &cmemalign_storage, dim * elemSize, __ATOMIC_SEQ_CST );
     992                #endif // __STATISTICS__
     993
     994                size_t size = dim * elemSize;
     995                char * addr = (char *)memalignNoStats( alignment, size );
     996          if ( unlikely( addr == 0p ) ) return 0p;
     997                HeapManager.Storage.Header * header;
     998                HeapManager.FreeHeader * freeElem;
     999                size_t bsize;
     1000                headers( "amemalign", addr, header, freeElem, bsize, alignment );
     1001
     1002                header->kind.real.blockSize |= 2;                               // mark as zero filled
     1003                return addr;
     1004        } // amemalign
     1005
     1006
    9531007        // Same as calloc() with memory alignment.
    954         void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ) {
     1008        void * cmemalign( size_t alignment, size_t dim, size_t elemSize ) {
    9551009                #ifdef __STATISTICS__
    9561010                __atomic_add_fetch( &cmemalign_calls, 1, __ATOMIC_SEQ_CST );
    957                 __atomic_add_fetch( &cmemalign_storage, noOfElems * elemSize, __ATOMIC_SEQ_CST );
    958                 #endif // __STATISTICS__
    959 
    960                 return cmemalignNoStats( alignment, noOfElems, elemSize );
     1011                __atomic_add_fetch( &cmemalign_storage, dim * elemSize, __ATOMIC_SEQ_CST );
     1012                #endif // __STATISTICS__
     1013
     1014                return cmemalignNoStats( alignment, dim, elemSize );
    9611015        } // cmemalign
    9621016
     
    10151069
    10161070
    1017         // Returns the alignment of the allocation.
     1071        // Returns the alignment of an allocation.
    10181072        size_t malloc_alignment( void * addr ) {
    10191073          if ( unlikely( addr == 0p ) ) return libAlign();      // minimum alignment
     
    10261080        } // malloc_alignment
    10271081
    1028 
    1029         // Returns true if the allocation is zero filled, i.e., initially allocated by calloc().
     1082        // Set the alignment for an the allocation and return previous alignment or 0 if no alignment.
     1083        size_t $malloc_alignment_set( void * addr, size_t alignment ) {
     1084          if ( unlikely( addr == 0p ) ) return libAlign();      // minimum alignment
     1085                size_t ret;
     1086                HeapManager.Storage.Header * header = headerAddr( addr );
     1087                if ( (header->kind.fake.alignment & 1) == 1 ) { // fake header ?
     1088                        ret = header->kind.fake.alignment & -2;         // remove flag from old value
     1089                        header->kind.fake.alignment = alignment | 1; // add flag to new value
     1090                } else {
     1091                        ret = 0;                                                                        // => no alignment to change
     1092                } // if
     1093                return ret;
     1094        } // $malloc_alignment_set
     1095
     1096
     1097        // Returns true if the allocation is zero filled, e.g., allocated by calloc().
    10301098        bool malloc_zero_fill( void * addr ) {
    10311099          if ( unlikely( addr == 0p ) ) return false;           // null allocation is not zero fill
     
    10341102                        header = realHeader( header );                          // backup from fake to real header
    10351103                } // if
    1036                 return (header->kind.real.blockSize & 2) != 0;  // zero filled (calloc/cmemalign) ?
     1104                return (header->kind.real.blockSize & 2) != 0;  // zero filled ?
    10371105        } // malloc_zero_fill
    10381106
    1039 
    1040         // Returns number of elements if the allocation is for an array, i.e., by calloc().
    1041         size_t malloc_dimension( void * addr ) {
     1107        // Set allocation is zero filled and return previous zero filled.
     1108        bool $malloc_zero_fill_set( void * addr ) {
    10421109          if ( unlikely( addr == 0p ) ) return false;           // null allocation is not zero fill
    10431110                HeapManager.Storage.Header * header = headerAddr( addr );
     
    10451112                        header = realHeader( header );                          // backup from fake to real header
    10461113                } // if
    1047                 return header->dimension;                                               // array (calloc/cmemalign)
    1048         } // malloc_zero_fill
     1114                bool ret = (header->kind.real.blockSize & 2) != 0; // zero filled ?
     1115                header->kind.real.blockSize |= 2;                               // mark as zero filled
     1116                return ret;
     1117        } // $malloc_zero_fill_set
     1118
     1119
     1120        // Returns original total allocation size (not bucket size) => array size is dimension * sizeif(T).
     1121        size_t malloc_size( void * addr ) {
     1122          if ( unlikely( addr == 0p ) ) return false;           // null allocation is not zero fill
     1123                HeapManager.Storage.Header * header = headerAddr( addr );
     1124                if ( (header->kind.fake.alignment & 1) == 1 ) { // fake header ?
     1125                        header = realHeader( header );                          // backup from fake to real header
     1126                } // if
     1127                return header->size;
     1128        } // malloc_size
     1129
     1130        // Set allocation size and return previous size.
     1131        size_t $malloc_size_set( void * addr, size_t size ) {
     1132          if ( unlikely( addr == 0p ) ) return false;           // null allocation is not zero fill
     1133                HeapManager.Storage.Header * header = headerAddr( addr );
     1134                if ( (header->kind.fake.alignment & 1) == 1 ) { // fake header ?
     1135                        header = realHeader( header );                          // backup from fake to real header
     1136                } // if
     1137                size_t ret = header->size;
     1138                header->size = size;
     1139                return ret;
     1140        } // $malloc_size_set
    10491141
    10501142
  • libcfa/src/stdhdr/malloc.h

    r899dfbb r76e2113  
    1010// Created On       : Thu Jul 20 15:58:16 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Mar  8 10:01:20 2020
    13 // Update Count     : 11
     12// Last Modified On : Thu Apr 16 22:44:06 2020
     13// Update Count     : 13
    1414//
    1515
     
    3131
    3232extern "C" {
     33void * aalloc( size_t noOfElems, size_t elemSize );
     34void * amemalign( size_t alignment, size_t noOfElems, size_t elemSize );
    3335void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize );
    3436size_t malloc_alignment( void * );
    3537bool malloc_zero_fill( void * );
    36 size_t malloc_dimension( void * );
     38size_t malloc_size( void * );
    3739int malloc_stats_fd( int fd );
    3840} // extern "C"
  • libcfa/src/stdlib.cfa

    r899dfbb r76e2113  
    1010// Created On       : Thu Jan 28 17:10:29 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Mar 31 13:26:46 2020
    13 // Update Count     : 495
     12// Last Modified On : Thu Apr 16 22:43:33 2020
     13// Update Count     : 498
    1414//
    1515
     
    3737        } // alloc_set
    3838
    39         T * alloc_set( T ptr[], size_t dim, T fill ) { // realloc array with fill
     39        T * alloc_set( T ptr[], size_t dim, T fill ) {          // realloc array with fill
    4040                size_t olen = malloc_usable_size( ptr );                // current allocation
    4141                void * nptr = (void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc
    4242                size_t nlen = malloc_usable_size( nptr );               // new allocation
    4343                if ( nlen > olen ) {                                                    // larger ?
    44                         for ( i; dim ) { memcpy( &ptr[i], &fill, sizeof(T) ); } // initialize with fill value
     44                        for ( i; malloc_size( ptr ) / sizeof(T) ~ dim ) {
     45                                memcpy( &ptr[i], &fill, sizeof(T) );    // initialize with fill value
     46                        } // for
    4547                } // if
    4648                return (T *)nptr;
  • libcfa/src/stdlib.hfa

    r899dfbb r76e2113  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Apr  1 18:38:41 2020
    13 // Update Count     : 429
     12// Last Modified On : Thu Apr 16 22:44:05 2020
     13// Update Count     : 432
    1414//
    1515
     
    2525        void * memalign( size_t align, size_t size );           // malloc.h
    2626        size_t malloc_usable_size( void * ptr );                        // malloc.h
     27        size_t malloc_size( void * addr );                                      // CFA heap
    2728        void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); // CFA heap
    2829        void * memset( void * dest, int fill, size_t size ); // string.h
Note: See TracChangeset for help on using the changeset viewer.