Ignore:
Timestamp:
Aug 11, 2020, 4:40:15 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
0d070ca
Parents:
07d867b (diff), 129674b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into new-ast

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/stdlib.hfa

    r07d867b r22f94a4  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Apr 16 22:44:05 2020
    13 // Update Count     : 432
     12// Last Modified On : Thu Jul 30 16:14:58 2020
     13// Update Count     : 490
    1414//
    1515
     
    2020
    2121#include <stdlib.h>                                                                             // *alloc, strto*, ato*
     22#include <heap.hfa>
    2223
    2324// Reduce includes by explicitly defining these routines.
    2425extern "C" {
    25         void * memalign( size_t align, size_t size );           // malloc.h
    26         size_t malloc_usable_size( void * ptr );                        // malloc.h
    27         size_t malloc_size( void * addr );                                      // CFA heap
    28         void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); // CFA heap
     26        void * memalign( size_t alignment, size_t size );       // malloc.h
     27        void * pvalloc( size_t size );                                          // malloc.h
    2928        void * memset( void * dest, int fill, size_t size ); // string.h
    3029        void * memcpy( void * dest, const void * src, size_t size ); // string.h
    31         void * resize( void * oaddr, size_t size );                     // CFA heap
    3230} // extern "C"
    33 
    34 void * resize( void * oaddr, size_t nalign, size_t size ); // CFA heap
    35 void * realloc( void * oaddr, size_t nalign, size_t size ); // CFA heap
    3631
    3732//---------------------------------------
     
    4439//---------------------------------------
    4540
     41// Macro because of returns
     42#define $VAR_ALLOC( allocation, alignment ) \
     43        if ( _Alignof(T) <= libAlign() ) return (T *)(void *)allocation( (size_t)sizeof(T) ); /* C allocation */ \
     44        else return (T *)alignment( _Alignof(T), sizeof(T) )
     45
     46#define $ARRAY_ALLOC( allocation, alignment, dim ) \
     47        if ( _Alignof(T) <= libAlign() ) return (T *)(void *)allocation( dim, (size_t)sizeof(T) ); /* C allocation */ \
     48        else return (T *)alignment( _Alignof(T), dim, sizeof(T) )
     49
     50#define $RE_SPECIALS( ptr, size, allocation, alignment ) \
     51        if ( unlikely( size == 0 ) || unlikely( ptr == 0p ) ) { \
     52                if ( unlikely( size == 0 ) ) free( ptr ); \
     53                $VAR_ALLOC( malloc, memalign ); \
     54        } /* if */
     55
    4656static inline forall( dtype T | sized(T) ) {
    4757        // Cforall safe equivalents, i.e., implicit size specification
    4858
    4959        T * malloc( void ) {
    50                 if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc
    51                 else return (T *)memalign( _Alignof(T), sizeof(T) );
     60                $VAR_ALLOC( malloc, memalign );
    5261        } // malloc
    5362
     63        T * aalloc( size_t dim ) {
     64                $ARRAY_ALLOC( aalloc, amemalign, dim );
     65        } // aalloc
     66
    5467        T * calloc( size_t dim ) {
    55                 if ( _Alignof(T) <= libAlign() )return (T *)(void *)calloc( dim, sizeof(T) ); // C calloc
    56                 else return (T *)cmemalign( _Alignof(T), dim, sizeof(T) );
     68                $ARRAY_ALLOC( calloc, cmemalign, dim );
    5769        } // calloc
    5870
     71        T * resize( T * ptr, size_t size ) {                            // CFA resize, eliminate return-type cast
     72                $RE_SPECIALS( ptr, size, malloc, memalign );
     73                if ( _Alignof(T) <= libAlign() ) return (T *)(void *)resize( (void *)ptr, size ); // CFA resize
     74                else return (T *)(void *)resize( (void *)ptr, _Alignof(T), size ); // CFA resize
     75        } // resize
     76
    5977        T * realloc( T * ptr, size_t size ) {                           // CFA realloc, eliminate return-type cast
    60                 return (T *)(void *)realloc( (void *)ptr, size ); // C realloc
     78                $RE_SPECIALS( ptr, size, malloc, memalign );
     79                if ( _Alignof(T) <= libAlign() ) return (T *)(void *)realloc( (void *)ptr, size ); // C realloc
     80                else return (T *)(void *)realloc( (void *)ptr, _Alignof(T), size ); // CFA realloc
    6181        } // realloc
    6282
     
    6585        } // memalign
    6686
     87        T * amemalign( size_t align, size_t dim ) {
     88                return (T *)amemalign( align, dim, sizeof(T) ); // CFA amemalign
     89        } // amemalign
     90
    6791        T * cmemalign( size_t align, size_t dim  ) {
    6892                return (T *)cmemalign( align, dim, sizeof(T) ); // CFA cmemalign
     
    76100                return posix_memalign( (void **)ptr, align, sizeof(T) ); // C posix_memalign
    77101        } // posix_memalign
     102
     103        T * valloc( void ) {
     104                return (T *)valloc( sizeof(T) );                                // C valloc
     105        } // valloc
     106
     107        T * pvalloc( void ) {
     108                return (T *)pvalloc( sizeof(T) );                               // C pvalloc
     109        } // pvalloc
    78110} // distribution
    79111
     
    86118
    87119        T * alloc( size_t dim ) {
    88                 if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( dim * (size_t)sizeof(T) );
    89                 else return (T *)memalign( _Alignof(T), dim * sizeof(T) );
     120                return aalloc( dim );
    90121        } // alloc
    91122
    92123        forall( dtype S | sized(S) )
    93124        T * alloc( S ptr[], size_t dim = 1 ) {                          // singleton/array resize
    94                 size_t len = malloc_usable_size( ptr );                 // current bucket size
    95                 if ( sizeof(T) * dim > len ) {                                  // not enough space ?
    96                         T * temp = alloc( dim );                                        // new storage
    97                         free( ptr );                                                            // free old storage
    98                         return temp;
     125                return resize( (T *)ptr, dim * sizeof(T) );             // CFA resize
     126        } // alloc
     127
     128        T * alloc( T ptr[], size_t dim = 1, bool copy = true ) {
     129                if ( copy ) {
     130                        return realloc( ptr, dim * sizeof(T) );         // CFA realloc
    99131                } else {
    100                         return (T *)ptr;
    101                 } // if
    102         } // alloc
    103 
    104         T * alloc( T ptr[], size_t dim, bool copy = true ) {
    105                 if ( copy ) {                                                                   // realloc
    106                         return (T *)(void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc
    107                 } else {
    108                         struct __Unknown {};
    109                         return alloc( (__Unknown *)ptr, dim );          // reuse, cheat making T/S different types
     132                        return resize( ptr, dim * sizeof(T) );          // CFA resize
    110133                } // if
    111134        } // alloc
     
    132155                return (T *)memcpy( (T *)alloc( dim ), fill, dim * sizeof(T) ); // initialize with fill value
    133156        } // alloc
    134 } // distribution
    135 
    136 forall( dtype T | sized(T) ) {
    137         T * alloc_set( T ptr[], size_t dim, char fill );        // realloc array with fill
    138         T * alloc_set( T ptr[], size_t dim, T fill );           // realloc array with fill
     157
     158        T * alloc_set( T ptr[], size_t dim, char fill ) {       // realloc array with fill
     159                size_t osize = malloc_size( ptr );                              // current allocation
     160                size_t nsize = dim * sizeof(T);                                 // new allocation
     161                T * nptr = realloc( ptr, nsize );                               // CFA realloc
     162                if ( nsize > osize ) {                                                  // larger ?
     163                        memset( (char *)nptr + osize, (int)fill, nsize - osize ); // initialize added storage
     164                } // if
     165                return nptr;
     166        } // alloc_set
     167
     168        T * alloc_set( T ptr[], size_t dim, T & fill ) {        // realloc array with fill
     169                size_t odim = malloc_size( ptr ) / sizeof(T);   // current dimension
     170                size_t nsize = dim * sizeof(T);                                 // new allocation
     171                size_t ndim = nsize / sizeof(T);                                // new dimension
     172                T * nptr = realloc( ptr, nsize );                               // CFA realloc
     173                if ( ndim > odim ) {                                                    // larger ?
     174                        for ( i; odim ~ ndim ) {
     175                                memcpy( &nptr[i], &fill, sizeof(T) );   // initialize with fill value
     176                        } // for
     177                } // if
     178                return nptr;
     179        } // alloc_align_set
    139180} // distribution
    140181
     
    148189        } // alloc_align
    149190
    150         T * alloc_align( T ptr[], size_t align ) {                      // aligned realloc array
    151                 return (T *)(void *)realloc( (void *)ptr, align, sizeof(T) ); // CFA realloc
     191        T * alloc_align( T * ptr, size_t align ) {                      // aligned realloc array
     192                return (T *)(void *)realloc( (void *)ptr, align, sizeof(T) ); // CFA C realloc
    152193        } // alloc_align
    153194
     
    182223                return (T *)memcpy( (T *)alloc_align( align, dim ), fill, dim * sizeof(T) );
    183224        } // alloc_align
    184 } // distribution
    185 
    186 forall( dtype T | sized(T) ) {
    187         T * alloc_align_set( T ptr[], size_t align, char fill ); // aligned realloc with fill
    188         T * alloc_align_set( T ptr[], size_t align, T fill ); // aligned realloc with fill
    189         T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ); // aligned realloc array with fill
    190         T * alloc_align_set( T ptr[], size_t align, size_t dim, T fill ); // aligned realloc array with fill
     225
     226        T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ) {
     227                size_t osize = malloc_size( ptr );                              // current allocation
     228                size_t nsize = dim * sizeof(T);                                 // new allocation
     229                T * nptr = alloc_align( ptr, align, nsize );
     230                if ( nsize > osize ) {                                                  // larger ?
     231                        memset( (char *)nptr + osize, (int)fill, nsize - osize ); // initialize added storage
     232                } // if
     233                return nptr;
     234        } // alloc_align_set
     235
     236        T * alloc_align_set( T ptr[], size_t align, size_t dim, T & fill ) {
     237                size_t odim = malloc_size( ptr ) / sizeof(T);   // current dimension
     238                size_t nsize = dim * sizeof(T);                                 // new allocation
     239                size_t ndim = nsize / sizeof(T);                                // new dimension
     240                T * nptr = alloc_align( ptr, align, nsize );
     241                if ( ndim > odim ) {                                                    // larger ?
     242                        for ( i; odim ~ ndim ) {
     243                                memcpy( &nptr[i], &fill, sizeof(T) );   // initialize with fill value
     244                        } // for
     245                } // if
     246                return nptr;
     247        } // alloc_align_set
    191248} // distribution
    192249
     
    215272// Cforall allocation/deallocation and constructor/destructor, non-array types
    216273forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * new( Params p );
    217 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void delete( T * ptr );
    218 forall( dtype T, ttype Params | sized(T) | { void ^?{}( T & ); void delete( Params ); } ) void delete( T * ptr, Params rest );
     274forall( dtype T | { void ^?{}( T & ); } ) void delete( T * ptr );
     275forall( dtype T, ttype Params | { void ^?{}( T & ); void delete( Params ); } ) void delete( T * ptr, Params rest );
    219276
    220277// Cforall allocation/deallocation and constructor/destructor, array types
     
    287344extern "C" {                                                                                    // override C version
    288345        void srandom( unsigned int seed );
    289         long int random( void );
     346        long int random( void );                                                        // GENERATES POSITIVE AND NEGATIVE VALUES
     347        // For positive values, use unsigned int, e.g., unsigned int r = random() % 100U;
    290348} // extern "C"
    291349
     
    294352        long int random( long int u ) { if ( u < 0 ) return random( u, 0 ); else return random( 0, u ); } // [0,u)
    295353        unsigned long int random( void ) { return lrand48(); }
     354        unsigned long int random( unsigned long int u ) { return lrand48() % u; } // [0,u)
    296355        unsigned long int random( unsigned long int l, unsigned long int u ) { if ( u < l ) [u, l] = [l, u]; return lrand48() % (u - l) + l; } // [l,u)
    297         unsigned long int random( unsigned long int u ) { return lrand48() % u; } // [0,u)
    298356
    299357        char random( void ) { return (unsigned long int)random(); }
Note: See TracChangeset for help on using the changeset viewer.