Changeset cfbc703d


Ignore:
Timestamp:
Apr 1, 2020, 9:32:21 PM (5 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:
6d43cdde
Parents:
5137f9f
Message:

add resize and more "alloc" routines

Files:
7 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/heap.cfa

    r5137f9f rcfbc703d  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar  6 10:14:52 2020
    13 // Update Count     : 650
     12// Last Modified On : Wed Apr  1 15:59:53 2020
     13// Update Count     : 692
    1414//
    1515
     
    150150                                                        union {
    151151//                                                              FreeHeader * home;              // allocated block points back to home locations (must overlay alignment)
     152                                                                // 2nd low-order bit => zero filled
    152153                                                                void * home;                    // allocated block points back to home locations (must overlay alignment)
    153154                                                                size_t blockSize;               // size for munmap (must overlay alignment)
     
    169170                                struct FakeHeader {
    170171                                        #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
    171                                         uint32_t alignment;                                     // low-order bits of home/blockSize used for tricks
     172                                        // 1st low-order bit => fake header & alignment
     173                                        uint32_t alignment;
    172174                                        #endif // __ORDER_LITTLE_ENDIAN__
    173175
     
    179181                                } fake; // FakeHeader
    180182                        } kind; // Kind
     183                        uint32_t dimension;                                                     // used by calloc-like to remember number of array elements
    181184                } header; // Header
    182185                char pad[libAlign() - sizeof( Header )];
     
    268271static unsigned long long int cmemalign_storage;
    269272static unsigned int cmemalign_calls;
     273static unsigned long long int resize_storage;
     274static unsigned int resize_calls;
    270275static unsigned long long int realloc_storage;
    271276static unsigned int realloc_calls;
     
    282287                                                                        "  memalign: calls %u / storage %llu\n"
    283288                                                                        "  cmemalign: calls %u / storage %llu\n"
     289                                                                        "  resize: calls %u / storage %llu\n"
    284290                                                                        "  realloc: calls %u / storage %llu\n"
    285291                                                                        "  free: calls %u / storage %llu\n"
     
    291297                                                                        memalign_calls, memalign_storage,
    292298                                                                        cmemalign_calls, cmemalign_storage,
     299                                                                        resize_calls, resize_storage,
    293300                                                                        realloc_calls, realloc_storage,
    294301                                                                        free_calls, free_storage,
     
    310317                                                "<total type=\"memalign\" count=\"%u\" size=\"%llu\"/>\n"
    311318                                                "<total type=\"cmemalign\" count=\"%u\" size=\"%llu\"/>\n"
     319                                                "<total type=\"resize\" count=\"%u\" size=\"%llu\"/>\n"
    312320                                                "<total type=\"realloc\" count=\"%u\" size=\"%llu\"/>\n"
    313321                                                "<total type=\"free\" count=\"%u\" size=\"%llu\"/>\n"
     
    320328                                                memalign_calls, memalign_storage,
    321329                                                cmemalign_calls, cmemalign_storage,
     330                                                resize_calls, resize_storage,
    322331                                                realloc_calls, realloc_storage,
    323332                                                free_calls, free_storage,
     
    339348
    340349
    341 static inline void checkAlign( size_t alignment ) {
    342         if ( alignment < libAlign() || ! libPow2( alignment ) ) {
    343                 abort( "Alignment %zu for memory allocation is less than %d and/or not a power of 2.", alignment, libAlign() );
    344         } // if
    345 } // checkAlign
    346 
    347 
    348350static inline bool setHeapExpand( size_t value ) {
    349351  if ( heapExpand < pageSize ) return true;
     
    380382
    381383
     384// <-------+----------------------------------------------------> bsize (bucket size)
     385// |header |addr
     386//==================================================================================
     387//                   align/offset |
     388// <-----------------<------------+-----------------------------> bsize (bucket size)
     389//                   |fake-header | addr
     390#define headerAddr( addr ) ((HeapManager.Storage.Header *)( (char *)addr - sizeof(HeapManager.Storage) ))
     391#define realHeader( header ) ((HeapManager.Storage.Header *)((char *)header - header->kind.fake.offset))
     392
     393// <-------<<--------------------- dsize ---------------------->> bsize (bucket size)
     394// |header |addr
     395//==================================================================================
     396//                   align/offset |
     397// <------------------------------<<---------- dsize --------->>> bsize (bucket size)
     398//                   |fake-header |addr
     399#define dataStorage( bsize, addr, header ) (bsize - ( (char *)addr - (char *)header ))
     400
     401
     402static inline void checkAlign( size_t alignment ) {
     403        if ( alignment < libAlign() || ! libPow2( alignment ) ) {
     404                abort( "Alignment %zu for memory allocation is less than %d and/or not a power of 2.", alignment, libAlign() );
     405        } // if
     406} // checkAlign
     407
     408
    382409static inline void checkHeader( bool check, const char name[], void * addr ) {
    383410        if ( unlikely( check ) ) {                                                      // bad address ?
     
    391418static inline void fakeHeader( HeapManager.Storage.Header *& header, size_t & alignment ) {
    392419        if ( unlikely( (header->kind.fake.alignment & 1) == 1 ) ) { // fake header ?
    393                 size_t offset = header->kind.fake.offset;
    394420                alignment = header->kind.fake.alignment & -2;   // remove flag from value
    395421                #ifdef __CFA_DEBUG__
    396422                checkAlign( alignment );                                                // check alignment
    397423                #endif // __CFA_DEBUG__
    398                 header = (HeapManager.Storage.Header *)((char *)header - offset);
     424                header = realHeader( header );                                  // backup from fake to real header
    399425        } // if
    400426} // fakeHeader
    401 
    402 
    403 // <-------+----------------------------------------------------> bsize (bucket size)
    404 // |header |addr
    405 //==================================================================================
    406 //                                | alignment
    407 // <-----------------<------------+-----------------------------> bsize (bucket size)
    408 //                   |fake-header | addr
    409 #define headerAddr( addr ) ((HeapManager.Storage.Header *)( (char *)addr - sizeof(HeapManager.Storage) ))
    410 
    411 // <-------<<--------------------- dsize ---------------------->> bsize (bucket size)
    412 // |header |addr
    413 //==================================================================================
    414 //                                | alignment
    415 // <------------------------------<<---------- dsize --------->>> bsize (bucket size)
    416 //                   |fake-header |addr
    417 #define dataStorage( bsize, addr, header ) (bsize - ( (char *)addr - (char *)header ))
    418427
    419428
     
    749758                memset( addr, '\0', bsize - sizeof(HeapManager.Storage) ); // set to zeros
    750759
     760        assert( noOfElems <= UINT32_MAX );
     761        header->dimension = noOfElems;                                          // store number of array elements
    751762        header->kind.real.blockSize |= 2;                                       // mark as zero filled
    752763        return addr;
     
    803814        #endif // __CFA_DEBUG__
    804815                memset( addr, '\0', dataStorage( bsize, addr, header ) ); // set to zeros
    805         header->kind.real.blockSize |= 2;                               // mark as zero filled
    806 
     816
     817        assert( noOfElems <= UINT32_MAX );
     818        header->dimension = noOfElems;                                          // store initial array size
     819        header->kind.real.blockSize |= 2;                                       // mark as zero filled
    807820        return addr;
    808821} // cmemalignNoStats
     
    842855        } // calloc
    843856
    844         // Change the size of the memory block pointed to by ptr to size bytes. The contents shall be unchanged in the range
    845         // from the start of the region up to the minimum of the old and new sizes. If the new size is larger than the old
    846         // size, the added memory shall not be initialized.  If ptr is 0p, then the call is equivalent to malloc(size), for
    847         // all values of size; if size is equal to zero, and ptr is not 0p, then the call is equivalent to free(ptr). Unless
    848         // ptr is 0p, it must have been returned by an earlier call to malloc(), calloc() or realloc(). If the area pointed
    849         // to was moved, a free(ptr) is done.
     857        // Change the size of the memory block pointed to by ptr to size bytes. The contents are undefined.  If ptr is 0p,
     858        // then the call is equivalent to malloc(size), for all values of size; if size is equal to zero, and ptr is not 0p,
     859        // then the call is equivalent to free(ptr). Unless ptr is 0p, it must have been returned by an earlier call to
     860        // malloc(), calloc() or realloc(). If the area pointed to was moved, a free(ptr) is done.
     861
     862        void * resize( void * oaddr, size_t size ) {
     863                #ifdef __STATISTICS__
     864                __atomic_add_fetch( &resize_calls, 1, __ATOMIC_SEQ_CST );
     865                __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST );
     866                #endif // __STATISTICS__
     867
     868                // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
     869          if ( unlikely( size == 0 ) ) { free( oaddr ); return mallocNoStats( size ); } // special cases
     870          if ( unlikely( oaddr == 0p ) ) return mallocNoStats( size );
     871
     872                HeapManager.Storage.Header * header;
     873                HeapManager.FreeHeader * freeElem;
     874                size_t bsize, oalign = 0;
     875                headers( "resize", oaddr, header, freeElem, bsize, oalign );
     876                size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
     877
     878                // same size, DO NOT preserve STICKY PROPERTIES.
     879                if ( oalign == 0 && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size
     880                        header->kind.real.blockSize &= -2;                      // no alignment and turn off 0 fill
     881                        return oaddr;
     882                } // if
     883       
     884                // change size, DO NOT preserve STICKY PROPERTIES.
     885                void * naddr = mallocNoStats( size );                   // create new area
     886                free( oaddr );
     887                return naddr;
     888        } // resize
     889
     890
     891        // Same as resize but the contents shall be unchanged in the range from the start of the region up to the minimum of
     892        // the old and new sizes.
    850893        void * realloc( void * oaddr, size_t size ) {
    851894                #ifdef __STATISTICS__
    852895                __atomic_add_fetch( &realloc_calls, 1, __ATOMIC_SEQ_CST );
     896                __atomic_add_fetch( &realloc_storage, size, __ATOMIC_SEQ_CST );
    853897                #endif // __STATISTICS__
    854898
     
    866910                        // Do not know size of original allocation => cannot do 0 fill for any additional space because do not know
    867911                        // where to start filling, i.e., do not overwrite existing values in space.
    868                         //
    869                         // This case does not result in a new profiler entry because the previous one still exists and it must match with
    870                         // the free for this memory.  Hence, this realloc does not appear in the profiler output.
    871912                        return oaddr;
    872913                } // if
    873 
    874                 #ifdef __STATISTICS__
    875                 __atomic_add_fetch( &realloc_storage, size, __ATOMIC_SEQ_CST );
    876                 #endif // __STATISTICS__
    877914
    878915                // change size and copy old content to new storage
     
    9851022                        return header->kind.fake.alignment & -2;        // remove flag from value
    9861023                } else {
    987                         return libAlign ();                                                     // minimum alignment
     1024                        return libAlign();                                                      // minimum alignment
    9881025                } // if
    9891026        } // malloc_alignment
     
    9951032                HeapManager.Storage.Header * header = headerAddr( addr );
    9961033                if ( (header->kind.fake.alignment & 1) == 1 ) { // fake header ?
    997                         header = (HeapManager.Storage.Header *)((char *)header - header->kind.fake.offset);
     1034                        header = realHeader( header );                          // backup from fake to real header
    9981035                } // if
    9991036                return (header->kind.real.blockSize & 2) != 0;  // zero filled (calloc/cmemalign) ?
     1037        } // malloc_zero_fill
     1038
     1039
     1040        // Returns number of elements if the allocation is for an array, i.e., by calloc().
     1041        size_t malloc_dimension( void * addr ) {
     1042          if ( unlikely( addr == 0p ) ) return false;           // null allocation is not zero fill
     1043                HeapManager.Storage.Header * header = headerAddr( addr );
     1044                if ( (header->kind.fake.alignment & 1) == 1 ) { // fake header ?
     1045                        header = realHeader( header );                          // backup from fake to real header
     1046                } // if
     1047                return header->dimension;                                               // array (calloc/cmemalign)
    10001048        } // malloc_zero_fill
    10011049
     
    10791127
    10801128// Must have CFA linkage to overload with C linkage realloc.
    1081 void * realloc( void * oaddr, size_t nalign, size_t size ) {
     1129void * resize( void * oaddr, size_t nalign, size_t size ) {
    10821130        #ifdef __STATISTICS__
    1083         __atomic_add_fetch( &realloc_calls, 1, __ATOMIC_SEQ_CST );
     1131        __atomic_add_fetch( &resize_calls, 1, __ATOMIC_SEQ_CST );
     1132        __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST );
    10841133        #endif // __STATISTICS__
    10851134
    10861135        // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
    1087   if ( unlikely( size == 0 ) ) { free( oaddr ); return mallocNoStats( size ); } // special cases
    1088   if ( unlikely( oaddr == 0p ) ) return mallocNoStats( size );
     1136  if ( unlikely( size == 0 ) ) { free( oaddr ); return memalignNoStats( nalign, size ); } // special cases
     1137  if ( unlikely( oaddr == 0p ) ) return memalignNoStats( nalign, size );
     1138
    10891139
    10901140        if ( unlikely( nalign == 0 ) ) nalign = libAlign();     // reset alignment to minimum
     
    10971147        HeapManager.FreeHeader * freeElem;
    10981148        size_t bsize, oalign = 0;
    1099         headers( "realloc", oaddr, header, freeElem, bsize, oalign );
     1149        headers( "resize", oaddr, header, freeElem, bsize, oalign );
    11001150        size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
    11011151
    1102   if ( oalign != 0 && (uintptr_t)oaddr % nalign == 0 ) { // has alignment and just happens to work out
    1103                 headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
    1104                 return realloc( oaddr, size );
    1105         } // if
    1106 
    1107         #ifdef __STATISTICS__
    1108         __atomic_add_fetch( &realloc_storage, size, __ATOMIC_SEQ_CST );
    1109         #endif // __STATISTICS__
    1110 
    1111         // change size and copy old content to new storage
     1152        if ( oalign <= nalign && (uintptr_t)oaddr % nalign == 0 ) { // <= alignment and new alignment happens to match
     1153                if ( oalign >= libAlign() ) {                                   // fake header ?
     1154                        headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
     1155                } // if
     1156                if ( size <= odsize && odsize <= size * 2 ) {   // allow 50% wasted storage for smaller size
     1157                        header->kind.real.blockSize &= -2;                      // turn off 0 fill
     1158                        return oaddr;
     1159                } // if
     1160        } // if
     1161
     1162        // change size
    11121163
    11131164        void * naddr;
     
    11181169        } // if
    11191170
     1171        free( oaddr );
     1172        return naddr;
     1173} // resize
     1174
     1175
     1176void * realloc( void * oaddr, size_t nalign, size_t size ) {
     1177        if ( unlikely( nalign == 0 ) ) nalign = libAlign();     // reset alignment to minimum
     1178        #ifdef __CFA_DEBUG__
     1179        else
     1180                checkAlign( nalign );                                                   // check alignment
     1181        #endif // __CFA_DEBUG__
     1182
     1183        HeapManager.Storage.Header * header;
     1184        HeapManager.FreeHeader * freeElem;
     1185        size_t bsize, oalign = 0;
     1186        headers( "realloc", oaddr, header, freeElem, bsize, oalign );
     1187        size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
     1188
     1189        if ( oalign <= nalign && (uintptr_t)oaddr % nalign == 0 ) { // <= alignment and new alignment happens to match
     1190                if ( oalign >= libAlign() ) {                                   // fake header ?
     1191                        headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
     1192                } // if
     1193                return realloc( oaddr, size );
     1194        } // if
     1195
     1196        // change size and copy old content to new storage
     1197
     1198        #ifdef __STATISTICS__
     1199        __atomic_add_fetch( &realloc_calls, 1, __ATOMIC_SEQ_CST );
     1200        __atomic_add_fetch( &realloc_storage, size, __ATOMIC_SEQ_CST );
     1201        #endif // __STATISTICS__
     1202
     1203        // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
     1204  if ( unlikely( size == 0 ) ) { free( oaddr ); return memalignNoStats( nalign, size ); } // special cases
     1205  if ( unlikely( oaddr == 0p ) ) return memalignNoStats( nalign, size );
     1206
     1207        void * naddr;
     1208        if ( unlikely( header->kind.real.blockSize & 2 ) ) { // previous request zero fill
     1209                naddr = cmemalignNoStats( nalign, 1, size );    // create new aligned area
     1210        } else {
     1211                naddr = memalignNoStats( nalign, size );                // create new aligned area
     1212        } // if
     1213
    11201214        headers( "realloc", naddr, header, freeElem, bsize, oalign );
    1121         size_t ndsize = dataStorage( bsize, naddr, header ); // data storage avilable in bucket
     1215        size_t ndsize = dataStorage( bsize, naddr, header ); // data storage available in bucket
    11221216        // To preserve prior fill, the entire bucket must be copied versus the size.
    11231217        memcpy( naddr, oaddr, MIN( odsize, ndsize ) );          // copy bytes
  • libcfa/src/stdhdr/malloc.h

    r5137f9f rcfbc703d  
    1010// Created On       : Thu Jul 20 15:58:16 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Aug 11 09:06:31 2018
    13 // Update Count     : 10
     12// Last Modified On : Sun Mar  8 10:01:20 2020
     13// Update Count     : 11
    1414//
    1515
     
    3131
    3232extern "C" {
     33void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize );
    3334size_t malloc_alignment( void * );
    3435bool malloc_zero_fill( void * );
     36size_t malloc_dimension( void * );
    3537int malloc_stats_fd( int fd );
    36 void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize );
    3738} // extern "C"
    3839
  • libcfa/src/stdlib.cfa

    r5137f9f rcfbc703d  
    1010// Created On       : Thu Jan 28 17:10:29 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 08:27:08 2020
    13 // Update Count     : 486
     12// Last Modified On : Tue Mar 31 13:26:46 2020
     13// Update Count     : 495
    1414//
    1515
     
    2020#define _XOPEN_SOURCE 600                                                               // posix_memalign, *rand48
    2121#include <string.h>                                                                             // memcpy, memset
    22 #include <malloc.h>                                                                             // malloc_usable_size
    2322//#include <math.h>                                                                             // fabsf, fabs, fabsl
    2423#include <complex.h>                                                                    // _Complex_I
     
    3837        } // alloc_set
    3938
     39        T * alloc_set( T ptr[], size_t dim, T fill ) { // realloc array with fill
     40                size_t olen = malloc_usable_size( ptr );                // current allocation
     41                void * nptr = (void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc
     42                size_t nlen = malloc_usable_size( nptr );               // new allocation
     43                if ( nlen > olen ) {                                                    // larger ?
     44                        for ( i; dim ) { memcpy( &ptr[i], &fill, sizeof(T) ); } // initialize with fill value
     45                } // if
     46                return (T *)nptr;
     47        } // alloc_align_set
     48
    4049        T * alloc_align_set( T ptr[], size_t align, char fill ) { // aligned realloc with fill
    4150                size_t olen = malloc_usable_size( ptr );                // current allocation
     
    4554                if ( nlen > olen ) {                                                    // larger ?
    4655                        memset( (char *)nptr + olen, (int)fill, nlen - olen ); // initialize added storage
     56                } // if
     57                return (T *)nptr;
     58        } // alloc_align_set
     59
     60        T * alloc_align_set( T ptr[], size_t align, size_t dim, T fill ) { // aligned realloc with fill
     61                size_t olen = malloc_usable_size( ptr );                // current allocation
     62                void * nptr = (void *)realloc( (void *)ptr, align, sizeof(T) ); // CFA realloc
     63                // char * nptr = alloc_align( ptr, align );
     64                size_t nlen = malloc_usable_size( nptr );               // new allocation
     65                if ( nlen > olen ) {                                                    // larger ?
     66                        for ( i; dim ) { memcpy( &ptr[i], &fill, sizeof(T) ); } // initialize with fill value
    4767                } // if
    4868                return (T *)nptr;
  • libcfa/src/stdlib.hfa

    r5137f9f rcfbc703d  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar  5 11:29:06 2020
    13 // Update Count     : 407
     12// Last Modified On : Wed Apr  1 18:38:41 2020
     13// Update Count     : 429
    1414//
    1515
     
    2424extern "C" {
    2525        void * memalign( size_t align, size_t size );           // malloc.h
    26     void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); // CFA heap
     26        size_t malloc_usable_size( void * ptr );                        // malloc.h
     27        void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); // CFA heap
    2728        void * memset( void * dest, int fill, size_t size ); // string.h
    2829        void * memcpy( void * dest, const void * src, size_t size ); // string.h
     30        void * resize( void * oaddr, size_t size );                     // CFA heap
    2931} // extern "C"
    3032
     33void * resize( void * oaddr, size_t nalign, size_t size ); // CFA heap
    3134void * realloc( void * oaddr, size_t nalign, size_t size ); // CFA heap
    3235
     
    7275                return posix_memalign( (void **)ptr, align, sizeof(T) ); // C posix_memalign
    7376        } // posix_memalign
    74 
     77} // distribution
     78
     79static inline forall( dtype T | sized(T) ) {
    7580        // Cforall safe general allocation, fill, resize, array
    7681
     
    8489        } // alloc
    8590
    86         T * alloc( T ptr[], size_t dim ) {                                      // realloc
    87                 return (T *)(void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc
     91        forall( dtype S | sized(S) )
     92        T * alloc( S ptr[], size_t dim = 1 ) {                          // singleton/array resize
     93                size_t len = malloc_usable_size( ptr );                 // current bucket size
     94                if ( sizeof(T) * dim > len ) {                                  // not enough space ?
     95                        T * temp = alloc( dim );                                        // new storage
     96                        free( ptr );                                                            // free old storage
     97                        return temp;
     98                } else {
     99                        return (T *)ptr;
     100                } // if
     101        } // alloc
     102
     103        T * alloc( T ptr[], size_t dim, bool copy = true ) {
     104                if ( copy ) {                                                                   // realloc
     105                        return (T *)(void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc
     106                } else {
     107                        struct __Unknown {};
     108                        return alloc( (__Unknown *)ptr, dim );          // reuse, cheat making T/S different types
     109                } // if
    88110        } // alloc
    89111
     
    113135forall( dtype T | sized(T) ) {
    114136        T * alloc_set( T ptr[], size_t dim, char fill );        // realloc array with fill
     137        T * alloc_set( T ptr[], size_t dim, T fill );           // realloc array with fill
    115138} // distribution
    116139
     
    126149        T * alloc_align( T ptr[], size_t align ) {                      // aligned realloc array
    127150                return (T *)(void *)realloc( (void *)ptr, align, sizeof(T) ); // CFA realloc
     151        } // alloc_align
     152
     153        forall( dtype S | sized(S) )
     154        T * alloc_align( S ptr[], size_t align ) {                      // aligned reuse array
     155                return (T *)(void *)resize( (void *)ptr, align, sizeof(T) ); // CFA realloc
    128156        } // alloc_align
    129157
     
    156184
    157185forall( dtype T | sized(T) ) {
     186        T * alloc_align_set( T ptr[], size_t align, char fill ); // aligned realloc with fill
     187        T * alloc_align_set( T ptr[], size_t align, T fill ); // aligned realloc with fill
    158188        T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ); // aligned realloc array with fill
     189        T * alloc_align_set( T ptr[], size_t align, size_t dim, T fill ); // aligned realloc array with fill
    159190} // distribution
    160191
  • tests/.expect/alloc-ERROR.txt

    r5137f9f rcfbc703d  
    1 alloc.cfa:310:1 error: No reasonable alternatives for expression Applying untyped:
     1alloc.cfa:362:1 error: No reasonable alternatives for expression Applying untyped:
    22  Name: ?=?
    33...to:
    4   Name: p
     4  Name: ip
    55  Applying untyped:
    66    Name: realloc
     
    1919
    2020
    21 alloc.cfa:311:1 error: No reasonable alternatives for expression Applying untyped:
     21alloc.cfa:363:1 error: No reasonable alternatives for expression Applying untyped:
    2222  Name: ?=?
    2323...to:
    24   Name: p
    25   Applying untyped:
    26     Name: alloc
    27   ...to:
    28     Name: stp
    29     Applying untyped:
    30       Name: ?*?
    31     ...to:
    32       Name: dim
    33       Sizeof Expression on: Applying untyped:
    34           Name: *?
    35         ...to:
    36           Name: stp
    37 
    38 
    39 
    40 
    41 alloc.cfa:312:1 error: No reasonable alternatives for expression Applying untyped:
    42   Name: ?=?
    43 ...to:
    44   Name: p
     24  Name: ip
    4525  Applying untyped:
    4626    Name: memset
     
    5030
    5131
    52 alloc.cfa:313:1 error: No reasonable alternatives for expression Applying untyped:
     32alloc.cfa:364:1 error: No reasonable alternatives for expression Applying untyped:
    5333  Name: ?=?
    5434...to:
    55   Name: p
     35  Name: ip
    5636  Applying untyped:
    5737    Name: memcpy
  • tests/.expect/alloc.txt

    r5137f9f rcfbc703d  
    23230xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101
    2424
    25 CFA resize array alloc
     25CFA realloc array alloc
    26260xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef
    27 CFA resize array alloc
     27CFA realloc array alloc
    28280xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101
    29 CFA resize array alloc
     29CFA realloc array alloc
    30300xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef
    31 CFA resize array alloc
     31CFA realloc array alloc, fill
    32320xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede
    33 CFA resize array alloc
     33CFA realloc array alloc, fill
    34340xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef
    35 CFA resize array alloc, fill
     35CFA realloc array alloc, fill
    36360xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede
     37CFA realloc array alloc, 5
     380xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede
     39CFA realloc array alloc, 5
     400xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef
     41CFA realloc array alloc, 5
     420xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff
    3743
    3844C   memalign 42 42.5
  • tests/alloc.cfa

    r5137f9f rcfbc703d  
    1010// Created On       : Wed Feb  3 07:56:22 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Feb 16 09:21:13 2020
    13 // Update Count     : 405
     12// Last Modified On : Wed Apr  1 10:58:35 2020
     13// Update Count     : 424
    1414//
    1515
     
    2828        size_t dim = 10;
    2929        char fill = '\xde';
    30         int * p, * p1;
     30        int * ip, * ip1;
    3131
    3232        // allocation, non-array types
    3333
    34         p = (int *)malloc( sizeof(*p) );                                        // C malloc, type unsafe
    35         *p = 0xdeadbeef;
    36         printf( "C   malloc %#x\n", *p );
    37         free( p );
    38 
    39         p = malloc();                                       // CFA malloc, type safe
    40         *p = 0xdeadbeef;
    41         printf( "CFA malloc %#x\n", *p );
    42         free( p );
    43 
    44         p = alloc();                                        // CFA alloc, type safe
    45         *p = 0xdeadbeef;
    46         printf( "CFA alloc %#x\n", *p );
    47         free( p );
    48 
    49         p = alloc_set( fill );                                                          // CFA alloc, fill
    50         printf( "CFA alloc, fill %08x\n", *p );
    51         free( p );
    52 
    53         p = alloc_set( 3 );                                                                     // CFA alloc, fill
    54         printf( "CFA alloc, fill %d\n", *p );
    55         free( p );
     34        ip = (int *)malloc( sizeof(*ip) );                                      // C malloc, type unsafe
     35        *ip = 0xdeadbeef;
     36        printf( "C   malloc %#x\n", *ip );
     37        free( ip );
     38
     39        ip = malloc();                                                                          // CFA malloc, type safe
     40        *ip = 0xdeadbeef;
     41        printf( "CFA malloc %#x\n", *ip );
     42        free( ip );
     43
     44        ip = alloc();                                                                           // CFA alloc, type safe
     45        *ip = 0xdeadbeef;
     46        printf( "CFA alloc %#x\n", *ip );
     47        free( ip );
     48
     49        ip = alloc_set( fill );                                                         // CFA alloc, fill
     50        printf( "CFA alloc, fill %08x\n", *ip );
     51        free( ip );
     52
     53        ip = alloc_set( 3 );                                                            // CFA alloc, fill
     54        printf( "CFA alloc, fill %d\n", *ip );
     55        free( ip );
    5656
    5757
     
    5959        printf( "\n" );
    6060
    61         p = (int *)calloc( dim, sizeof( *p ) );                         // C array calloc, type unsafe
     61        ip = (int *)calloc( dim, sizeof( *ip ) );                       // C array calloc, type unsafe
    6262        printf( "C   array calloc, fill 0\n" );
    63         for ( i; dim ) { printf( "%#x ", p[i] ); }
    64         printf( "\n" );
    65         free( p );
    66 
    67         p = calloc( dim );                                  // CFA array calloc, type safe
     63        for ( i; dim ) { printf( "%#x ", ip[i] ); }
     64        printf( "\n" );
     65        free( ip );
     66
     67        ip = calloc( dim );                                                                     // CFA array calloc, type safe
    6868        printf( "CFA array calloc, fill 0\n" );
    69         for ( i; dim ) { printf( "%#x ", p[i] ); }
    70         printf( "\n" );
    71         free( p );
    72 
    73         p = alloc( dim );                                   // CFA array alloc, type safe
    74         for ( i; dim ) { p[i] = 0xdeadbeef; }
     69        for ( i; dim ) { printf( "%#x ", ip[i] ); }
     70        printf( "\n" );
     71        free( ip );
     72
     73        ip = alloc( dim );                                                                      // CFA array alloc, type safe
     74        for ( i; dim ) { ip[i] = 0xdeadbeef; }
    7575        printf( "CFA array alloc, no fill\n" );
    76         for ( i; dim ) { printf( "%#x ", p[i] ); }
    77         printf( "\n" );
    78         free( p );
    79 
    80         p = alloc_set( 2 * dim, fill );                                         // CFA array alloc, fill
     76        for ( i; dim ) { printf( "%#x ", ip[i] ); }
     77        printf( "\n" );
     78        free( ip );
     79
     80        ip = alloc_set( 2 * dim, fill );                                        // CFA array alloc, fill
    8181        printf( "CFA array alloc, fill %#hhx\n", fill );
    82         for ( i; 2 * dim ) { printf( "%#x ", p[i] ); }
    83         printf( "\n" );
    84         free( p );
    85 
    86         p = alloc_set( 2 * dim, 0xdeadbeef );                           // CFA array alloc, fill
     82        for ( i; 2 * dim ) { printf( "%#x ", ip[i] ); }
     83        printf( "\n" );
     84        free( ip );
     85
     86        ip = alloc_set( 2 * dim, 0xdeadbeef );                          // CFA array alloc, fill
    8787        printf( "CFA array alloc, fill %#hhx\n", 0xdeadbeef );
    88         for ( i; 2 * dim ) { printf( "%#x ", p[i] ); }
    89         printf( "\n" );
    90         // do not free
    91 
    92         p1 = alloc_set( 2 * dim, p );                                           // CFA array alloc, fill
     88        for ( i; 2 * dim ) { printf( "%#x ", ip[i] ); }
     89        printf( "\n" );
     90        // do not free
     91
     92        ip1 = alloc_set( 2 * dim, ip );                                         // CFA array alloc, fill
    9393        printf( "CFA array alloc, fill from array\n" );
    94         for ( i; 2 * dim ) { printf( "%#x %#x, ", p[i], p1[i] ); }
    95         free( p1 );
    96         printf( "\n" );
     94        for ( i; 2 * dim ) { printf( "%#x %#x, ", ip[i], ip1[i] ); }
     95        free( ip1 );
     96        printf( "\n" );
     97
     98
     99        // realloc, non-array types
     100        printf( "\n" );
     101
     102        ip = (int *)realloc( ip, dim * sizeof(*ip) );           // C realloc
     103        printf( "C realloc\n" );
     104        for ( i; dim ) { printf( "%#x ", ip[i] ); }
     105        printf( "\n" );
     106        // do not free
     107
     108        ip = realloc( ip, 2 * dim * sizeof(*ip) );                      // CFA realloc
     109        for ( i; dim ~ 2 * dim ) { ip[i] = 0x1010101; }
     110        printf( "CFA realloc\n" );
     111        for ( i; 2 * dim ) { printf( "%#x ", ip[i] ); }
     112        printf( "\n" );
     113        // do not free
     114
     115
     116        // realloc, array types
     117        printf( "\n" );
     118
     119        ip = alloc( ip, dim );                                                          // CFA realloc array alloc
     120        for ( i; dim ) { ip[i] = 0xdeadbeef; }
     121        printf( "CFA realloc array alloc\n" );
     122        for ( i; dim ) { printf( "%#x ", ip[i] ); }
     123        printf( "\n" );
     124        // do not free
     125
     126        ip = alloc( ip, 2 * dim );                                                      // CFA realloc array alloc
     127        for ( i; dim ~ 2 * dim ) { ip[i] = 0x1010101; }         // fill upper part
     128        printf( "CFA realloc array alloc\n" );
     129        for ( i; 2 * dim ) { printf( "%#x ", ip[i] ); }
     130        printf( "\n" );
     131        // do not free
     132
     133        ip = alloc( ip, dim );                                                          // CFA realloc array alloc
     134        printf( "CFA realloc array alloc\n" );
     135        for ( i; dim ) { printf( "%#x ", ip[i] ); }
     136        printf( "\n" );
     137        // do not free
     138
     139        ip = alloc_set( ip, 3 * dim, fill );                            // CFA realloc array alloc, fill
     140        printf( "CFA realloc array alloc, fill\n" );
     141        for ( i; 3 * dim ) { printf( "%#x ", ip[i] ); }
     142        printf( "\n" );
     143        // do not free
     144
     145        ip = alloc_set( ip, dim, fill );                                        // CFA realloc array alloc, fill
     146        printf( "CFA realloc array alloc, fill\n" );
     147        for ( i; dim ) { printf( "%#x ", ip[i] ); }
     148        printf( "\n" );
     149        // do not free
     150
     151        ip = alloc_set( ip, 3 * dim, fill );                            // CFA realloc array alloc, fill
     152        printf( "CFA realloc array alloc, fill\n" );
     153        for ( i; 3 * dim ) { printf( "%#x ", ip[i] );; }
     154        printf( "\n" );
     155        // do not free
     156
     157        ip = alloc_set( ip, 3 * dim, 5 );                                       // CFA realloc array alloc, 5
     158        printf( "CFA realloc array alloc, 5\n" );
     159        for ( i; 3 * dim ) { printf( "%#x ", ip[i] ); }
     160        printf( "\n" );
     161        // do not free
     162
     163        ip = alloc_set( ip, dim, 5 );                                           // CFA realloc array alloc, 5
     164        printf( "CFA realloc array alloc, 5\n" );
     165        for ( i; dim ) { printf( "%#x ", ip[i] ); }
     166        printf( "\n" );
     167        // do not free
     168
     169        ip = alloc_set( ip, 3 * dim, 5 );                                       // CFA realloc array alloc, 5
     170        printf( "CFA realloc array alloc, 5\n" );
     171        for ( i; 3 * dim ) { printf( "%#x ", ip[i] );; }
     172        printf( "\n" );
     173        free( ip );
    97174
    98175
    99176        // resize, non-array types
    100         printf( "\n" );
    101 
    102         p = (int *)realloc( p, dim * sizeof(*p) );                      // C realloc
    103         printf( "C realloc\n" );
    104         for ( i; dim ) { printf( "%#x ", p[i] ); }
    105         printf( "\n" );
    106         // do not free
    107 
    108         p = realloc( p, 2 * dim * sizeof(*p) );             // CFA realloc
    109         for ( i; dim ~ 2 * dim ) { p[i] = 0x1010101; }
    110         printf( "CFA realloc\n" );
    111         for ( i; 2 * dim ) { printf( "%#x ", p[i] ); }
    112         printf( "\n" );
    113         // do not free
     177
     178        struct S {
     179                int a[5];
     180        };
     181
     182    ip = alloc();
     183        *ip = 5;
     184    double * dp = alloc( ip );
     185        *dp = 5.5;
     186    S * sp = alloc( dp );
     187        *sp = (S){ {0, 1, 2, 3, 4} };
     188    ip = alloc( sp );
     189        *ip = 3;
     190    free( ip );
    114191
    115192
    116193        // resize, array types
    117         printf( "\n" );
    118 
    119         p = alloc( p, dim );                                // CFA resize array alloc
    120         for ( i; dim ) { p[i] = 0xdeadbeef; }
    121         printf( "CFA resize array alloc\n" );
    122         for ( i; dim ) { printf( "%#x ", p[i] ); }
    123         printf( "\n" );
    124         // do not free
    125 
    126         p = alloc( p, 2 * dim );                            // CFA resize array alloc
    127         for ( i; dim ~ 2 * dim ) { p[i] = 0x1010101; }          // fill upper part
    128         printf( "CFA resize array alloc\n" );
    129         for ( i; 2 * dim ) { printf( "%#x ", p[i] ); }
    130         printf( "\n" );
    131         // do not free
    132 
    133         p = alloc( p, dim );                                // CFA resize array alloc
    134         printf( "CFA resize array alloc\n" );
    135         for ( i; dim ) { printf( "%#x ", p[i] ); }
    136         printf( "\n" );
    137         // do not free
    138 
    139         p = alloc_set( p, 3 * dim, fill );                                      // CFA resize array alloc, fill
    140         printf( "CFA resize array alloc\n" );
    141         for ( i; 3 * dim ) { printf( "%#x ", p[i] ); }
    142         printf( "\n" );
    143         // do not free
    144 
    145         p = alloc_set( p, dim, fill );                                          // CFA resize array alloc, fill
    146         printf( "CFA resize array alloc\n" );
    147         for ( i; dim ) { printf( "%#x ", p[i] ); }
    148         printf( "\n" );
    149         // do not free
    150 
    151         p = alloc_set( p, 3 * dim, fill );                                      // CFA resize array alloc, fill
    152         printf( "CFA resize array alloc, fill\n" );
    153         for ( i; 3 * dim ) { printf( "%#x ", p[i] );; }
    154         printf( "\n" );
    155         free( p );
     194
     195    ip = alloc( 5 );
     196        for ( i; 5 ) { ip[i] = 5; }
     197    dp = alloc( ip, 5 );
     198        for ( i; 5 ) { dp[i] = 5.5; }
     199    sp = alloc( dp, 5 );
     200        for ( i; 5 ) { sp[i] = (S){ {0, 1, 2, 3, 4} }; }
     201    ip = alloc( sp, 3 );
     202        for ( i; 3 ) { ip[i] = 3; }
     203    ip = alloc( ip, 7 );
     204        for ( i; 7 ) { ip[i] = 7; }
     205    ip = alloc( ip, 7, false );
     206        for ( i; 7 ) { ip[i] = 7; }
     207    free( ip );
    156208
    157209
     
    168220        free( stp );
    169221
    170         stp = &(*memalign( Alignment )){ 42, 42.5 };          // CFA memalign
     222        stp = &(*memalign( Alignment )){ 42, 42.5 };            // CFA memalign
    171223        assert( (uintptr_t)stp % Alignment == 0 );
    172224        printf( "CFA memalign %d %g\n", stp->x, stp->y );
     
    300352        free( fp - 1 );
    301353
    302         p = foo( bar( baz( malloc(), 0 ), 0 ), 0 );
    303         *p = 0xdeadbeef;
    304         printf( "CFA deep malloc %#x\n", *p );
    305         free( p );
     354        ip = foo( bar( baz( malloc(), 0 ), 0 ), 0 );
     355        *ip = 0xdeadbeef;
     356        printf( "CFA deep malloc %#x\n", *ip );
     357        free( ip );
    306358
    307359#ifdef ERR1
    308360        stp = malloc();
    309361        printf( "\nSHOULD FAIL\n" );
    310         p = realloc( stp, dim * sizeof( *stp ) );
    311         p = alloc( stp, dim * sizeof( *stp ) );
    312         p = memset( stp, 10 );
    313         p = memcpy( &st1, &st );
     362        ip = realloc( stp, dim * sizeof( *stp ) );
     363        ip = memset( stp, 10 );
     364        ip = memcpy( &st1, &st );
    314365#endif
    315366} // main
Note: See TracChangeset for help on using the changeset viewer.