Ignore:
Timestamp:
Jan 7, 2021, 3:27:00 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
2b4daf2, 64aeca0
Parents:
3c64c668 (diff), eef8dfb (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 park_unpark

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/stdlib.hfa

    r3c64c668 r58fe85a  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 08:27:01 2020
    13 // Update Count     : 401
     12// Last Modified On : Sat Dec 12 13:52:34 2020
     13// Update Count     : 536
    1414//
    1515
    1616#pragma once
    1717
    18 #include "bits/defs.hfa"
    19 #include "bits/align.hfa"
     18#include "bits/defs.hfa"                                                                // OPTIONAL_THREAD
     19#include "bits/align.hfa"                                                               // libAlign
    2020
    2121#include <stdlib.h>                                                                             // *alloc, strto*, ato*
    22 
     22#include <heap.hfa>
     23
     24// Reduce includes by explicitly defining these routines.
    2325extern "C" {
    24         void * memalign( size_t align, size_t size );           // malloc.h
     26        void * memalign( size_t alignment, size_t size );       // malloc.h
     27        void * pvalloc( size_t size );                                          // malloc.h
    2528        void * memset( void * dest, int fill, size_t size ); // string.h
    2629        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
    2830} // extern "C"
    29 
    30 void * 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
    4150static inline forall( dtype T | sized(T) ) {
    42         // C dynamic allocation
     51        // CFA safe equivalents, i.e., implicit size specification
    4352
    4453        T * malloc( void ) {
    45                 if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc
     54                if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( (size_t)sizeof(T) ); // C allocation
    4655                else return (T *)memalign( _Alignof(T), sizeof(T) );
    4756        } // malloc
    4857
     58        T * aalloc( size_t dim ) {
     59                $ARRAY_ALLOC( aalloc, amemalign, dim );
     60        } // aalloc
     61
    4962        T * calloc( size_t 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) );
     63                $ARRAY_ALLOC( calloc, cmemalign, dim );
    5264        } // calloc
    5365
     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
    5471        T * realloc( T * ptr, size_t size ) {                           // CFA realloc, eliminate return-type cast
    55                 return (T *)(void *)realloc( (void *)ptr, size ); // C realloc
     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
    5674        } // realloc
    5775
     
    6078        } // memalign
    6179
     80        T * amemalign( size_t align, size_t dim ) {
     81                return (T *)amemalign( align, dim, sizeof(T) ); // CFA amemalign
     82        } // amemalign
     83
    6284        T * cmemalign( size_t align, size_t dim  ) {
    6385                return (T *)cmemalign( align, dim, sizeof(T) ); // CFA cmemalign
     
    7294        } // posix_memalign
    7395
    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 
    112 forall( dtype T | sized(T) ) {
    113         T * alloc_set( T ptr[], size_t dim, char fill );        // realloc array with fill
    114 } // distribution
     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
     150typedef struct S_align                  { inline size_t;  } T_align;
     151typedef struct S_resize                 { inline void *;  }     T_resize;
     152
     153forall( 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
     158static inline T_align   ?`align   ( size_t a )  { return (T_align){a}; }
     159static inline T_resize  ?`resize  ( void * a )  { return (T_resize){a}; }
    115160
    116161static 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 
    156 forall( 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
     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
    159234
    160235static inline forall( dtype T | sized(T) ) {
    161         // data, non-array types
     236        // CFA safe initialization/copy, i.e., implicit size specification, non-array types
    162237        T * memset( T * dest, char fill ) {
    163238                return (T *)memset( dest, fill, sizeof(T) );
     
    167242                return (T *)memcpy( dest, src, sizeof(T) );
    168243        } // memcpy
    169 } // distribution
    170 
    171 static inline forall( dtype T | sized(T) ) {
    172         // data, array types
     244
     245        // CFA safe initialization/copy, i.e., implicit size specification, array types
    173246        T * amemset( T dest[], char fill, size_t dim ) {
    174247                return (T *)(void *)memset( dest, fill, dim * sizeof(T) ); // C memset
     
    180253} // distribution
    181254
    182 // allocation/deallocation and constructor/destructor, non-array types
    183 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * new( Params p );
    184 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void delete( T * ptr );
    185 forall( 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
    188 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * anew( size_t dim, Params p );
    189 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void adelete( size_t dim, T arr[] );
    190 forall( dtype T | sized(T) | { void ^?{}( T & ); }, ttype Params | { void adelete( Params ); } ) void adelete( size_t dim, T arr[], Params rest );
     255// CFA deallocation for multiple objects
     256static inline forall( dtype T )                                                 // FIX ME, problems with 0p in list
     257void free( T * ptr ) {
     258        free( (void *)ptr );                                                            // C free
     259} // free
     260static inline forall( dtype T, ttype TT | { void free( TT ); } )
     261void free( T * ptr, TT rest ) {
     262        free( ptr );
     263        free( rest );
     264} // free
     265
     266// CFA allocation/deallocation and constructor/destructor, non-array types
     267static inline forall( dtype T | sized(T), ttype TT | { void ?{}( T &, TT ); } )
     268T * new( TT p ) {
     269        return &(*(T *)malloc()){ p };                                                  // run constructor
     270} // new
     271
     272static inline forall( dtype T | { void ^?{}( T & ); } )
     273void 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
     280static inline forall( dtype T, ttype TT | { void ^?{}( T & ); void delete( TT ); } )
     281void delete( T * ptr, TT rest ) {
     282        delete( ptr );
     283        delete( rest );
     284} // delete
     285
     286// CFA allocation/deallocation and constructor/destructor, array types
     287forall( dtype T | sized(T), ttype TT | { void ?{}( T &, TT ); } ) T * anew( size_t dim, TT p );
     288forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void adelete( T arr[] );
     289forall( dtype T | sized(T) | { void ^?{}( T & ); }, ttype TT | { void adelete( TT ); } ) void adelete( T arr[], TT rest );
    191290
    192291//---------------------------------------
     
    254353extern "C" {                                                                                    // override C version
    255354        void srandom( unsigned int seed );
    256         long int random( void );
     355        long int random( void );                                                        // GENERATES POSITIVE AND NEGATIVE VALUES
     356        // For positive values, use unsigned int, e.g., unsigned int r = random() % 100U;
    257357} // extern "C"
    258358
     
    261361        long int random( long int u ) { if ( u < 0 ) return random( u, 0 ); else return random( 0, u ); } // [0,u)
    262362        unsigned long int random( void ) { return lrand48(); }
     363        unsigned long int random( unsigned long int u ) { return lrand48() % u; } // [0,u)
    263364        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)
    264         unsigned long int random( unsigned long int u ) { return lrand48() % u; } // [0,u)
    265365
    266366        char random( void ) { return (unsigned long int)random(); }
     
    283383//---------------------------------------
    284384
    285 #include "common.hfa"
    286 
    287 //---------------------------------------
    288 
    289 extern bool threading_enabled(void) OPTIONAL_THREAD;
     385extern bool threading_enabled( void ) OPTIONAL_THREAD;
    290386
    291387// Local Variables: //
Note: See TracChangeset for help on using the changeset viewer.