Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/stdlib.hfa

    r09da82d re3fea42  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Dec 12 13:52:34 2020
    13 // Update Count     : 536
     12// Last Modified On : Tue Feb  4 08:27:01 2020
     13// Update Count     : 401
    1414//
    1515
    1616#pragma once
    1717
    18 #include "bits/defs.hfa"                                                                // OPTIONAL_THREAD
    19 #include "bits/align.hfa"                                                               // libAlign
     18#include "bits/defs.hfa"
     19#include "bits/align.hfa"
    2020
    2121#include <stdlib.h>                                                                             // *alloc, strto*, ato*
    22 #include <heap.hfa>
    23 
    24 // Reduce includes by explicitly defining these routines.
     22
    2523extern "C" {
    26         void * memalign( size_t alignment, size_t size );       // malloc.h
    27         void * pvalloc( size_t size );                                          // malloc.h
     24        void * memalign( size_t align, size_t size );           // malloc.h
    2825        void * memset( void * dest, int fill, size_t size ); // string.h
    2926        void * memcpy( void * dest, const void * src, size_t size ); // string.h
     27    void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); // CFA heap
    3028} // extern "C"
     29
     30void * realloc( void * oaddr, size_t nalign, size_t size ); // CFA heap
    3131
    3232//---------------------------------------
     
    3939//---------------------------------------
    4040
    41 #include "common.hfa"
    42 
    43 //---------------------------------------
    44 
    45 // Macro because of returns
    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 static inline forall( dtype T | sized(T) ) {
    51         // CFA safe equivalents, i.e., implicit size specification
     41static inline forall( dtype T | sized(T) ) {
     42        // C dynamic allocation
    5243
    5344        T * malloc( void ) {
    54                 if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( (size_t)sizeof(T) ); // C allocation
     45                if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc
    5546                else return (T *)memalign( _Alignof(T), sizeof(T) );
    5647        } // malloc
    5748
    58         T * aalloc( size_t dim ) {
    59                 $ARRAY_ALLOC( aalloc, amemalign, dim );
    60         } // aalloc
    61 
    6249        T * calloc( size_t dim ) {
    63                 $ARRAY_ALLOC( calloc, cmemalign, dim );
     50                if ( _Alignof(T) <= libAlign() )return (T *)(void *)calloc( dim, sizeof(T) ); // C calloc
     51                else return (T *)cmemalign( _Alignof(T), dim, sizeof(T) );
    6452        } // calloc
    6553
    66         T * resize( T * ptr, size_t size ) {                            // CFA resize, eliminate return-type cast
    67                 if ( _Alignof(T) <= libAlign() ) return (T *)(void *)resize( (void *)ptr, size ); // CFA resize
    68                 else return (T *)(void *)resize( (void *)ptr, _Alignof(T), size ); // CFA resize
    69         } // resize
    70 
    7154        T * realloc( T * ptr, size_t size ) {                           // CFA realloc, eliminate return-type cast
    72                 if ( _Alignof(T) <= libAlign() ) return (T *)(void *)realloc( (void *)ptr, size ); // C realloc
    73                 else return (T *)(void *)realloc( (void *)ptr, _Alignof(T), size ); // CFA realloc
     55                return (T *)(void *)realloc( (void *)ptr, size ); // C realloc
    7456        } // realloc
    7557
     
    7860        } // memalign
    7961
    80         T * amemalign( size_t align, size_t dim ) {
    81                 return (T *)amemalign( align, dim, sizeof(T) ); // CFA amemalign
    82         } // amemalign
    83 
    8462        T * cmemalign( size_t align, size_t dim  ) {
    8563                return (T *)cmemalign( align, dim, sizeof(T) ); // CFA cmemalign
     
    9472        } // posix_memalign
    9573
    96         T * valloc( void ) {
    97                 return (T *)valloc( sizeof(T) );                                // C valloc
    98         } // valloc
    99 
    100         T * pvalloc( void ) {
    101                 return (T *)pvalloc( sizeof(T) );                               // C pvalloc
    102         } // pvalloc
    103 } // distribution
    104 
    105 /*
    106         FIX ME : fix alloc interface after Ticker Number 214 is resolved, define and add union to S_fill. Then, modify postfix-fill functions to support T * with nmemb, char, and T object of any size. Finally, change alloc_internal.
    107         Or, just follow the instructions below for that.
    108 
    109         1. Replace the current forall-block that contains defintions of S_fill and S_realloc with following:
    110                 forall( dtype T | sized(T) ) {
    111                         union  U_fill           { char c; T * a; T t; };
    112                         struct S_fill           { char tag; U_fill(T) fill; };
    113                         struct S_realloc        { inline T *; };
    114                 }
    115 
    116         2. Replace all current postfix-fill functions with following for updated S_fill:
    117                 S_fill(T) ?`fill( char a )                                      { S_fill(T) ret = {'c'}; ret.fill.c = a; return ret; }
    118                 S_fill(T) ?`fill( T    a )                                      { S_fill(T) ret = {'t'}; memcpy(&ret.fill.t, &a, sizeof(T)); return ret; }
    119                 S_fill(T) ?`fill( T    a[], size_t nmemb )      { S_fill(T) ret = {'a', nmemb}; ret.fill.a = a; return ret; }
    120 
    121         3. Replace the $alloc_internal function which is outside ttype forall-block with following function:
    122                 T * $alloc_internal( void * Resize, T * Realloc, size_t Align, size_t Dim, S_fill(T) Fill) {
    123                         T * ptr = NULL;
    124                         size_t size = sizeof(T);
    125                         size_t copy_end = 0;
    126 
    127                         if(Resize) {
    128                                 ptr = (T*) (void *) resize( (int *)Resize, Align, Dim * size );
    129                         } else if (Realloc) {
    130                                 if (Fill.tag != '0') copy_end = min(malloc_size( Realloc ), Dim * size);
    131                                 ptr = (T*) (void *) realloc( (int *)Realloc, Align, Dim * size );
    132                         } else {
    133                                 ptr = (T*) (void *) memalign( Align, Dim * size );
    134                         }
    135 
    136                         if(Fill.tag == 'c') {
    137                                 memset( (char *)ptr + copy_end, (int)Fill.fill.c, Dim * size - copy_end );
    138                         } else if(Fill.tag == 't') {
    139                                 for ( int i = copy_end; i <= Dim * size - size ; i += size ) {
    140                                         memcpy( (char *)ptr + i, &Fill.fill.t, size );
    141                                 }
    142                         } else if(Fill.tag == 'a') {
    143                                 memcpy( (char *)ptr + copy_end, Fill.fill.a, min(Dim * size - copy_end, size * Fill.nmemb) );
    144                         }
    145 
    146                         return ptr;
    147                 } // $alloc_internal
    148 */
    149 
    150 typedef struct S_align                  { inline size_t;  } T_align;
    151 typedef struct S_resize                 { inline void *;  }     T_resize;
    152 
    153 forall( dtype T ) {
    154         struct S_fill           { char tag; char c; size_t size; T * at; char t[50]; };
    155         struct S_realloc        { inline T *; };
    156 }
    157 
    158 static inline T_align   ?`align   ( size_t a )  { return (T_align){a}; }
    159 static inline T_resize  ?`resize  ( void * a )  { return (T_resize){a}; }
    160 
    161 static inline forall( dtype T | sized(T) ) {
    162         S_fill(T) ?`fill ( T t ) {
    163                 S_fill(T) ret = { 't' };
    164                 size_t size = sizeof(T);
    165                 if(size > sizeof(ret.t)) { printf("ERROR: const object of size greater than 50 bytes given for dynamic memory fill\n"); exit(1); }
    166                 memcpy( &ret.t, &t, size );
    167                 return ret;
    168         }
    169         S_fill(T)               ?`fill ( char c )                               { return (S_fill(T)){ 'c', c }; }
    170         S_fill(T)               ?`fill ( T * a )                                { return (S_fill(T)){ 'T', '0', 0, a }; }
    171         S_fill(T)               ?`fill ( T a[], size_t nmemb )  { return (S_fill(T)){ 'a', '0', nmemb * sizeof(T), a }; }
    172 
    173         S_realloc(T)    ?`realloc ( T * a )                             { return (S_realloc(T)){a}; }
    174 
    175         T * $alloc_internal( void * Resize, T * Realloc, size_t Align, size_t Dim, S_fill(T) Fill) {
    176                 T * ptr = NULL;
    177                 size_t size = sizeof(T);
    178                 size_t copy_end = 0;
    179 
    180                 if ( Resize ) {
    181                         ptr = (T*) (void *) resize( (void *)Resize, Align, Dim * size );
    182                 } else if ( Realloc ) {
    183                         if (Fill.tag != '0') copy_end = min(malloc_size( Realloc ), Dim * size);
    184                         ptr = (T*) (void *) realloc( (void *)Realloc, Align, Dim * size );
    185                 } else {
    186                         ptr = (T*) (void *) memalign( Align, Dim * size );
    187                 }
    188 
    189                 if(Fill.tag == 'c') {
    190                         memset( (char *)ptr + copy_end, (int)Fill.c, Dim * size - copy_end );
    191                 } else if(Fill.tag == 't') {
    192                         for ( int i = copy_end; i < Dim * size; i += size ) {
    193                                 memcpy( (char *)ptr + i, &Fill.t, size );
    194                         }
    195                 } else if(Fill.tag == 'a') {
    196                         memcpy( (char *)ptr + copy_end, Fill.at, min(Dim * size - copy_end, Fill.size) );
    197                 } else if(Fill.tag == 'T') {
    198                         for ( int i = copy_end; i < Dim * size; i += size ) {
    199                                 memcpy( (char *)ptr + i, Fill.at, size );
    200                         }
    201                 }
    202 
    203                 return ptr;
    204         } // $alloc_internal
    205 
    206         forall( ttype TT | { T * $alloc_internal( void *, T *, size_t, size_t, S_fill(T), TT ); } ) {
    207 
    208                 T * $alloc_internal( void *       , T * Realloc, size_t Align, size_t Dim, S_fill(T) Fill, T_resize Resize, TT rest) {
    209                 return $alloc_internal( Resize, (T*)0p, Align, Dim, Fill, rest);
    210                 }
    211 
    212                 T * $alloc_internal( void * Resize, T *        , size_t Align, size_t Dim, S_fill(T) Fill, S_realloc(T) Realloc, TT rest) {
    213                 return $alloc_internal( (void*)0p, Realloc, Align, Dim, Fill, rest);
    214                 }
    215 
    216                 T * $alloc_internal( void * Resize, T * Realloc, size_t      , size_t Dim, S_fill(T) Fill, T_align Align, TT rest) {
    217                 return $alloc_internal( Resize, Realloc, Align, Dim, Fill, rest);
    218                 }
    219 
    220                 T * $alloc_internal( void * Resize, T * Realloc, size_t Align, size_t Dim, S_fill(T)     , S_fill(T) Fill, TT rest) {
    221                 return $alloc_internal( Resize, Realloc, Align, Dim, Fill, rest);
    222                 }
    223 
    224             T * alloc( TT all ) {
    225                 return $alloc_internal( (void*)0p, (T*)0p, (_Alignof(T) > libAlign() ? _Alignof(T) : libAlign()), (size_t)1, (S_fill(T)){'0'}, all);
    226             }
    227 
    228             T * alloc( size_t dim, TT all ) {
    229                 return $alloc_internal( (void*)0p, (T*)0p, (_Alignof(T) > libAlign() ? _Alignof(T) : libAlign()), dim, (S_fill(T)){'0'}, all);
    230             }
    231 
    232         } // distribution TT
    233 } // distribution T
    234 
    235 static inline forall( dtype T | sized(T) ) {
    236         // CFA safe initialization/copy, i.e., implicit size specification, non-array types
     74        // Cforall dynamic allocation
     75
     76        T * alloc( void ) {
     77                return malloc();
     78        } // alloc
     79
     80        T * alloc( size_t dim ) {
     81                if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( dim * (size_t)sizeof(T) );
     82                else return (T *)memalign( _Alignof(T), dim * sizeof(T) );
     83        } // alloc
     84
     85        T * alloc( T ptr[], size_t dim ) {                                      // realloc
     86                return (T *)(void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc
     87        } // alloc
     88
     89        T * alloc_set( char fill ) {
     90                return (T *)memset( (T *)alloc(), (int)fill, sizeof(T) ); // initialize with fill value
     91        } // alloc
     92
     93        T * alloc_set( T fill ) {
     94                return (T *)memcpy( (T *)alloc(), &fill, sizeof(T) ); // initialize with fill value
     95        } // alloc
     96
     97        T * alloc_set( size_t dim, char fill ) {
     98                return (T *)memset( (T *)alloc( dim ), (int)fill, dim * sizeof(T) ); // initialize with fill value
     99        } // alloc
     100
     101        T * alloc_set( size_t dim, T fill ) {
     102                T * r = (T *)alloc( dim );
     103                for ( i; dim ) { memcpy( &r[i], &fill, sizeof(T) ); } // initialize with fill value
     104                return r;
     105        } // alloc
     106
     107        T * alloc_set( size_t dim, const T fill[] ) {
     108                return (T *)memcpy( (T *)alloc( dim ), fill, dim * sizeof(T) ); // initialize with fill value
     109        } // alloc
     110} // distribution
     111
     112forall( dtype T | sized(T) ) {
     113        T * alloc_set( T ptr[], size_t dim, char fill );        // realloc array with fill
     114} // distribution
     115
     116static inline forall( dtype T | sized(T) ) {
     117        T * alloc_align( size_t align ) {
     118                return (T *)memalign( align, sizeof(T) );
     119        } // alloc_align
     120
     121        T * alloc_align( size_t align, size_t dim ) {
     122                return (T *)memalign( align, dim * sizeof(T) );
     123        } // alloc_align
     124
     125        T * alloc_align( T ptr[], size_t align ) {                      // aligned realloc array
     126                return (T *)(void *)realloc( (void *)ptr, align, sizeof(T) ); // CFA realloc
     127        } // alloc_align
     128
     129        T * alloc_align( T ptr[], size_t align, size_t dim ) { // aligned realloc array
     130                return (T *)(void *)realloc( (void *)ptr, align, dim * sizeof(T) ); // CFA realloc
     131        } // alloc_align
     132
     133        T * alloc_align_set( size_t align, char fill ) {
     134                return (T *)memset( (T *)alloc_align( align ), (int)fill, sizeof(T) ); // initialize with fill value
     135        } // alloc_align
     136
     137        T * alloc_align_set( size_t align, T fill ) {
     138                return (T *)memcpy( (T *)alloc_align( align ), &fill, sizeof(T) ); // initialize with fill value
     139        } // alloc_align
     140
     141        T * alloc_align_set( size_t align, size_t dim, char fill ) {
     142                return (T *)memset( (T *)alloc_align( align, dim ), (int)fill, dim * sizeof(T) ); // initialize with fill value
     143        } // alloc_align
     144
     145        T * alloc_align_set( size_t align, size_t dim, T fill ) {
     146                T * r = (T *)alloc_align( align, dim );
     147                for ( i; dim ) { memcpy( &r[i], &fill, sizeof(T) ); } // initialize with fill value
     148                return r;
     149        } // alloc_align
     150
     151        T * alloc_align_set( size_t align, size_t dim, const T fill[] ) {
     152                return (T *)memcpy( (T *)alloc_align( align, dim ), fill, dim * sizeof(T) );
     153        } // alloc_align
     154} // distribution
     155
     156forall( dtype T | sized(T) ) {
     157        T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ); // aligned realloc array with fill
     158} // distribution
     159
     160static inline forall( dtype T | sized(T) ) {
     161        // data, non-array types
    237162        T * memset( T * dest, char fill ) {
    238163                return (T *)memset( dest, fill, sizeof(T) );
     
    242167                return (T *)memcpy( dest, src, sizeof(T) );
    243168        } // memcpy
    244 
    245         // CFA safe initialization/copy, i.e., implicit size specification, array types
     169} // distribution
     170
     171static inline forall( dtype T | sized(T) ) {
     172        // data, array types
    246173        T * amemset( T dest[], char fill, size_t dim ) {
    247174                return (T *)(void *)memset( dest, fill, dim * sizeof(T) ); // C memset
     
    253180} // distribution
    254181
    255 // CFA deallocation for multiple objects
    256 static inline forall( dtype T )                                                 // FIX ME, problems with 0p in list
    257 void free( T * ptr ) {
    258         free( (void *)ptr );                                                            // C free
    259 } // free
    260 static inline forall( dtype T, ttype TT | { void free( TT ); } )
    261 void free( T * ptr, TT rest ) {
    262         free( ptr );
    263         free( rest );
    264 } // free
    265 
    266 // CFA allocation/deallocation and constructor/destructor, non-array types
    267 static inline forall( dtype T | sized(T), ttype TT | { void ?{}( T &, TT ); } )
    268 T * new( TT p ) {
    269         return &(*(T *)malloc()){ p };                                                  // run constructor
    270 } // new
    271 
    272 static inline forall( dtype T | { void ^?{}( T & ); } )
    273 void delete( T * ptr ) {
    274         // special case for 0-sized object => always call destructor
    275         if ( ptr || sizeof(ptr) == 0 ) {                                        // ignore null but not 0-sized objects
    276                 ^(*ptr){};                                                                              // run destructor
    277         } // if
    278         free( ptr );                                                                            // always call free
    279 } // delete
    280 static inline forall( dtype T, ttype TT | { void ^?{}( T & ); void delete( TT ); } )
    281 void delete( T * ptr, TT rest ) {
    282         delete( ptr );
    283         delete( rest );
    284 } // delete
    285 
    286 // CFA allocation/deallocation and constructor/destructor, array types
    287 forall( dtype T | sized(T), ttype TT | { void ?{}( T &, TT ); } ) T * anew( size_t dim, TT p );
    288 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void adelete( T arr[] );
    289 forall( dtype T | sized(T) | { void ^?{}( T & ); }, ttype TT | { void adelete( TT ); } ) void adelete( T arr[], TT rest );
     182// allocation/deallocation and constructor/destructor, non-array types
     183forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * new( Params p );
     184forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void delete( T * ptr );
     185forall( dtype T, ttype Params | sized(T) | { void ^?{}( T & ); void delete( Params ); } ) void delete( T * ptr, Params rest );
     186
     187// allocation/deallocation and constructor/destructor, array types
     188forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * anew( size_t dim, Params p );
     189forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void adelete( size_t dim, T arr[] );
     190forall( dtype T | sized(T) | { void ^?{}( T & ); }, ttype Params | { void adelete( Params ); } ) void adelete( size_t dim, T arr[], Params rest );
    290191
    291192//---------------------------------------
     
    353254extern "C" {                                                                                    // override C version
    354255        void srandom( unsigned int seed );
    355         long int random( void );                                                        // GENERATES POSITIVE AND NEGATIVE VALUES
    356         // For positive values, use unsigned int, e.g., unsigned int r = random() % 100U;
     256        long int random( void );
    357257} // extern "C"
    358258
     
    361261        long int random( long int u ) { if ( u < 0 ) return random( u, 0 ); else return random( 0, u ); } // [0,u)
    362262        unsigned long int random( void ) { return lrand48(); }
     263        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)
    363264        unsigned long int random( unsigned long int u ) { return lrand48() % u; } // [0,u)
    364         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)
    365265
    366266        char random( void ) { return (unsigned long int)random(); }
     
    383283//---------------------------------------
    384284
    385 extern bool threading_enabled( void ) OPTIONAL_THREAD;
     285#include "common.hfa"
     286
     287//---------------------------------------
     288
     289extern bool threading_enabled(void) OPTIONAL_THREAD;
    386290
    387291// Local Variables: //
Note: See TracChangeset for help on using the changeset viewer.