Changeset 58fe85a for libcfa/src/stdlib.hfa
- Timestamp:
- Jan 7, 2021, 3:27:00 PM (5 years ago)
- 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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/stdlib.hfa
r3c64c668 r58fe85a 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Feb 4 08:27:01202013 // Update Count : 40112 // Last Modified On : Sat Dec 12 13:52:34 2020 13 // Update Count : 536 14 14 // 15 15 16 16 #pragma once 17 17 18 #include "bits/defs.hfa" 19 #include "bits/align.hfa" 18 #include "bits/defs.hfa" // OPTIONAL_THREAD 19 #include "bits/align.hfa" // libAlign 20 20 21 21 #include <stdlib.h> // *alloc, strto*, ato* 22 22 #include <heap.hfa> 23 24 // Reduce includes by explicitly defining these routines. 23 25 extern "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 25 28 void * memset( void * dest, int fill, size_t size ); // string.h 26 29 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 heap28 30 } // extern "C" 29 30 void * realloc( void * oaddr, size_t nalign, size_t size ); // CFA heap31 31 32 32 //--------------------------------------- … … 39 39 //--------------------------------------- 40 40 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 41 50 static inline forall( dtype T | sized(T) ) { 42 // C dynamic allocation51 // CFA safe equivalents, i.e., implicit size specification 43 52 44 53 T * malloc( void ) { 45 if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc54 if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( (size_t)sizeof(T) ); // C allocation 46 55 else return (T *)memalign( _Alignof(T), sizeof(T) ); 47 56 } // malloc 48 57 58 T * aalloc( size_t dim ) { 59 $ARRAY_ALLOC( aalloc, amemalign, dim ); 60 } // aalloc 61 49 62 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 ); 52 64 } // calloc 53 65 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 54 71 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 56 74 } // realloc 57 75 … … 60 78 } // memalign 61 79 80 T * amemalign( size_t align, size_t dim ) { 81 return (T *)amemalign( align, dim, sizeof(T) ); // CFA amemalign 82 } // amemalign 83 62 84 T * cmemalign( size_t align, size_t dim ) { 63 85 return (T *)cmemalign( align, dim, sizeof(T) ); // CFA cmemalign … … 72 94 } // posix_memalign 73 95 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 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}; } 115 160 116 161 static 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 159 234 160 235 static inline forall( dtype T | sized(T) ) { 161 // data, non-array types236 // CFA safe initialization/copy, i.e., implicit size specification, non-array types 162 237 T * memset( T * dest, char fill ) { 163 238 return (T *)memset( dest, fill, sizeof(T) ); … … 167 242 return (T *)memcpy( dest, src, sizeof(T) ); 168 243 } // 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 173 246 T * amemset( T dest[], char fill, size_t dim ) { 174 247 return (T *)(void *)memset( dest, fill, dim * sizeof(T) ); // C memset … … 180 253 } // distribution 181 254 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 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 ); 191 290 192 291 //--------------------------------------- … … 254 353 extern "C" { // override C version 255 354 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; 257 357 } // extern "C" 258 358 … … 261 361 long int random( long int u ) { if ( u < 0 ) return random( u, 0 ); else return random( 0, u ); } // [0,u) 262 362 unsigned long int random( void ) { return lrand48(); } 363 unsigned long int random( unsigned long int u ) { return lrand48() % u; } // [0,u) 263 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) 264 unsigned long int random( unsigned long int u ) { return lrand48() % u; } // [0,u)265 365 266 366 char random( void ) { return (unsigned long int)random(); } … … 283 383 //--------------------------------------- 284 384 285 #include "common.hfa" 286 287 //--------------------------------------- 288 289 extern bool threading_enabled(void) OPTIONAL_THREAD; 385 extern bool threading_enabled( void ) OPTIONAL_THREAD; 290 386 291 387 // Local Variables: //
Note:
See TracChangeset
for help on using the changeset viewer.