Changeset c08c3cf
- Timestamp:
- Jan 20, 2021, 8:46:31 PM (2 years ago)
- Branches:
- arm-eh, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 481cf3a
- Parents:
- 467c8b7 (diff), 9db2c92 (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. - Files:
-
- 146 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/prelude/builtins.c
r467c8b7 rc08c3cf 18 18 // type that wraps a pointer and a destructor-like function - used in generating implicit destructor calls for struct members in user-defined functions 19 19 // Note: needs to occur early, because it is used to generate destructor calls during code generation 20 forall( dtype T)20 forall(T &) 21 21 struct __Destructor { 22 22 T * object; … … 25 25 26 26 // defined destructor in the case that non-generated code wants to use __Destructor 27 forall( dtype T)27 forall(T &) 28 28 static inline void ^?{}(__Destructor(T) & x) { 29 29 if (x.object && x.dtor) { … … 34 34 // easy interface into __Destructor's destructor for easy codegen purposes 35 35 extern "C" { 36 forall( dtype T)36 forall(T &) 37 37 static inline void __destroy_Destructor(__Destructor(T) * dtor) { 38 38 ^(*dtor){}; … … 51 51 void abort( const char fmt[], ... ) __attribute__ (( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ )); 52 52 53 forall( dtype T)53 forall(T &) 54 54 static inline T & identity(T & i) { 55 55 return i; … … 64 64 static inline void ^?{}($generator &) {} 65 65 66 trait is_generator( dtype T) {66 trait is_generator(T &) { 67 67 void main(T & this); 68 68 $generator * get_generator(T & this); 69 69 }; 70 70 71 forall( dtype T| is_generator(T))71 forall(T & | is_generator(T)) 72 72 static inline T & resume(T & gen) { 73 73 main(gen); … … 78 78 79 79 static inline { 80 forall( dtype DT| { DT & ?+=?( DT &, one_t ); } )80 forall( DT & | { DT & ?+=?( DT &, one_t ); } ) 81 81 DT & ++?( DT & x ) { return x += 1; } 82 82 83 forall( dtype DT| sized(DT) | { void ?{}( DT &, DT ); void ^?{}( DT & ); DT & ?+=?( DT &, one_t ); } )83 forall( DT & | sized(DT) | { void ?{}( DT &, DT ); void ^?{}( DT & ); DT & ?+=?( DT &, one_t ); } ) 84 84 DT & ?++( DT & x ) { DT tmp = x; x += 1; return tmp; } 85 85 86 forall( dtype DT| { DT & ?-=?( DT &, one_t ); } )86 forall( DT & | { DT & ?-=?( DT &, one_t ); } ) 87 87 DT & --?( DT & x ) { return x -= 1; } 88 88 89 forall( dtype DT| sized(DT) | { void ?{}( DT &, DT ); void ^?{}( DT & ); DT & ?-=?( DT &, one_t ); } )89 forall( DT & | sized(DT) | { void ?{}( DT &, DT ); void ^?{}( DT & ); DT & ?-=?( DT &, one_t ); } ) 90 90 DT & ?--( DT & x ) { DT tmp = x; x -= 1; return tmp; } 91 91 92 forall( dtype DT| { int ?!=?( const DT &, zero_t ); } )92 forall( DT & | { int ?!=?( const DT &, zero_t ); } ) 93 93 int !?( const DT & x ) { return !( x != 0 ); } 94 94 } // distribution 95 95 96 96 // universal typed pointer constant 97 static inline forall( dtype DT) DT * intptr( uintptr_t addr ) { return (DT *)addr; }97 static inline forall( DT & ) DT * intptr( uintptr_t addr ) { return (DT *)addr; } 98 98 static inline forall( ftype FT ) FT * intptr( uintptr_t addr ) { return (FT *)addr; } 99 99 … … 156 156 #define __CFA_EXP_OVERFLOW__() 157 157 158 static inline forall( otypeOT | { void ?{}( OT & this, one_t ); OT ?*?( OT, OT ); } ) {158 static inline forall( OT | { void ?{}( OT & this, one_t ); OT ?*?( OT, OT ); } ) { 159 159 OT ?\?( OT ep, unsigned int y ) { __CFA_EXP__(); } 160 160 OT ?\?( OT ep, unsigned long int y ) { __CFA_EXP__(); } -
libcfa/prelude/prelude-gen.cc
r467c8b7 rc08c3cf 159 159 int main() { 160 160 cout << "# 2 \"prelude.cfa\" // needed for error messages from this file" << endl; 161 cout << "trait sized( dtype T) {};" << endl;161 cout << "trait sized(T &) {};" << endl; 162 162 163 163 cout << "//////////////////////////" << endl; … … 264 264 for (auto cvq : qualifiersPair) { 265 265 for (auto is_vol : { " ", "volatile" }) { 266 cout << "forall( dtype DT) void ?{}(" << cvq.first << type << " * " << is_vol << " &, " << cvq.second << "DT *);" << endl;266 cout << "forall(DT &) void ?{}(" << cvq.first << type << " * " << is_vol << " &, " << cvq.second << "DT *);" << endl; 267 267 } 268 268 } … … 279 279 for (auto cvq : qualifiersSingle) { 280 280 for (auto is_vol : { " ", "volatile" }) { 281 cout << "forall( dtype DT) void ?{}(" << cvq << " DT" << " * " << is_vol << " &);" << endl;281 cout << "forall(DT &) void ?{}(" << cvq << " DT" << " * " << is_vol << " &);" << endl; 282 282 } 283 283 for (auto is_vol : { " ", "volatile" }) { 284 cout << "forall( dtype DT) void ^?{}(" << cvq << " DT" << " * " << is_vol << " &);" << endl;284 cout << "forall(DT &) void ^?{}(" << cvq << " DT" << " * " << is_vol << " &);" << endl; 285 285 } 286 286 } … … 290 290 for (auto is_vol : { " ", "volatile" }) { 291 291 for (auto cvq : qualifiersSingle) { 292 cout << "forall( dtype DT) void ?{}( " << cvq << type << " * " << is_vol << " &, zero_t);" << endl;292 cout << "forall(DT &) void ?{}( " << cvq << type << " * " << is_vol << " &, zero_t);" << endl; 293 293 } 294 294 } … … 317 317 for (auto op : pointerOperators) { 318 318 auto forall = [&op]() { 319 cout << "forall( dtype DT" << op.sized << ") ";319 cout << "forall(DT &" << op.sized << ") "; 320 320 }; 321 321 for (auto type : { "DT"/*, "void"*/ } ) { … … 408 408 for (auto is_vol : { " ", "volatile" }) { 409 409 for (auto cvq : qualifiersPair) { 410 cout << "forall( dtype DT) " << cvq.first << "void * ?=?( " << cvq.first << "void * " << is_vol << " &, " << cvq.second << "DT *);" << endl;410 cout << "forall(DT &) " << cvq.first << "void * ?=?( " << cvq.first << "void * " << is_vol << " &, " << cvq.second << "DT *);" << endl; 411 411 } 412 412 for (auto cvq : qualifiersSingle) { 413 cout << "forall( dtype DT) " << cvq << " DT * ?=?( " << cvq << " DT * " << is_vol << " &, zero_t);" << endl;413 cout << "forall(DT &) " << cvq << " DT * ?=?( " << cvq << " DT * " << is_vol << " &, zero_t);" << endl; 414 414 } 415 415 } -
libcfa/prelude/prelude.old.cf
r467c8b7 rc08c3cf 23 23 // ------------------------------------------------------------ 24 24 25 trait sized( dtype T) {};25 trait sized(T &) {}; 26 26 27 27 // ------------------------------------------------------------ … … 68 68 long double _Complex ?--( long double _Complex & ), ?--( volatile long double _Complex & ); 69 69 70 forall( dtype T| sized(T) ) T * ?++( T *& );71 forall( dtype T| sized(T) ) const T * ?++( const T *& );72 forall( dtype T| sized(T) ) volatile T * ?++( volatile T *& );73 forall( dtype T| sized(T) ) const volatile T * ?++( const volatile T *& );74 forall( dtype T| sized(T) ) T * ?--( T *& );75 forall( dtype T| sized(T) ) const T * ?--( const T *& );76 forall( dtype T| sized(T) ) volatile T * ?--( volatile T *& );77 forall( dtype T| sized(T) ) const volatile T * ?--( const volatile T *& );78 79 forall( dtype T| sized(T) ) T & ?[?]( T *, ptrdiff_t );80 forall( dtype T| sized(T) ) const T & ?[?]( const T *, ptrdiff_t );81 forall( dtype T| sized(T) ) volatile T & ?[?]( volatile T *, ptrdiff_t );82 forall( dtype T| sized(T) ) const volatile T & ?[?]( const volatile T *, ptrdiff_t );83 forall( dtype T| sized(T) ) T & ?[?]( ptrdiff_t, T * );84 forall( dtype T| sized(T) ) const T & ?[?]( ptrdiff_t, const T * );85 forall( dtype T| sized(T) ) volatile T & ?[?]( ptrdiff_t, volatile T * );86 forall( dtype T| sized(T) ) const volatile T & ?[?]( ptrdiff_t, const volatile T * );70 forall( T & | sized(T) ) T * ?++( T *& ); 71 forall( T & | sized(T) ) const T * ?++( const T *& ); 72 forall( T & | sized(T) ) volatile T * ?++( volatile T *& ); 73 forall( T & | sized(T) ) const volatile T * ?++( const volatile T *& ); 74 forall( T & | sized(T) ) T * ?--( T *& ); 75 forall( T & | sized(T) ) const T * ?--( const T *& ); 76 forall( T & | sized(T) ) volatile T * ?--( volatile T *& ); 77 forall( T & | sized(T) ) const volatile T * ?--( const volatile T *& ); 78 79 forall( T & | sized(T) ) T & ?[?]( T *, ptrdiff_t ); 80 forall( T & | sized(T) ) const T & ?[?]( const T *, ptrdiff_t ); 81 forall( T & | sized(T) ) volatile T & ?[?]( volatile T *, ptrdiff_t ); 82 forall( T & | sized(T) ) const volatile T & ?[?]( const volatile T *, ptrdiff_t ); 83 forall( T & | sized(T) ) T & ?[?]( ptrdiff_t, T * ); 84 forall( T & | sized(T) ) const T & ?[?]( ptrdiff_t, const T * ); 85 forall( T & | sized(T) ) volatile T & ?[?]( ptrdiff_t, volatile T * ); 86 forall( T & | sized(T) ) const volatile T & ?[?]( ptrdiff_t, const volatile T * ); 87 87 88 88 // ------------------------------------------------------------ … … 107 107 long double _Complex ++?( long double _Complex & ), --?( long double _Complex & ); 108 108 109 forall( dtype T| sized(T) ) T * ++?( T *& );110 forall( dtype T| sized(T) ) const T * ++?( const T *& );111 forall( dtype T| sized(T) ) volatile T * ++?( volatile T *& );112 forall( dtype T| sized(T) ) const volatile T * ++?( const volatile T *& );113 forall( dtype T| sized(T) ) T * --?( T *& );114 forall( dtype T| sized(T) ) const T * --?( const T *& );115 forall( dtype T| sized(T) ) volatile T * --?( volatile T *& );116 forall( dtype T| sized(T) ) const volatile T * --?( const volatile T *& );117 118 forall( dtype T| sized(T) ) T & *?( T * );119 forall( dtype T| sized(T) ) const T & *?( const T * );120 forall( dtype T| sized(T) ) volatile T & *?( volatile T * );121 forall( dtype T| sized(T) ) const volatile T & *?( const volatile T * );109 forall( T & | sized(T) ) T * ++?( T *& ); 110 forall( T & | sized(T) ) const T * ++?( const T *& ); 111 forall( T & | sized(T) ) volatile T * ++?( volatile T *& ); 112 forall( T & | sized(T) ) const volatile T * ++?( const volatile T *& ); 113 forall( T & | sized(T) ) T * --?( T *& ); 114 forall( T & | sized(T) ) const T * --?( const T *& ); 115 forall( T & | sized(T) ) volatile T * --?( volatile T *& ); 116 forall( T & | sized(T) ) const volatile T * --?( const volatile T *& ); 117 118 forall( T & | sized(T) ) T & *?( T * ); 119 forall( T & | sized(T) ) const T & *?( const T * ); 120 forall( T & | sized(T) ) volatile T & *?( volatile T * ); 121 forall( T & | sized(T) ) const volatile T & *?( const volatile T * ); 122 122 forall( ftype FT ) FT & *?( FT * ); 123 123 … … 142 142 !?( float _Complex ), !?( double _Complex ), !?( long double _Complex ); 143 143 144 forall( dtype DT) int !?( DT * );145 forall( dtype DT) int !?( const DT * );146 forall( dtype DT) int !?( volatile DT * );147 forall( dtype DT) int !?( const volatile DT * );144 forall( DT & ) int !?( DT * ); 145 forall( DT & ) int !?( const DT * ); 146 forall( DT & ) int !?( volatile DT * ); 147 forall( DT & ) int !?( const volatile DT * ); 148 148 forall( ftype FT ) int !?( FT * ); 149 149 … … 191 191 long double _Complex ?+?( long double _Complex, long double _Complex ), ?-?( long double _Complex, long double _Complex ); 192 192 193 forall( dtype T| sized(T) ) T * ?+?( T *, ptrdiff_t );194 forall( dtype T| sized(T) ) T * ?+?( ptrdiff_t, T * );195 forall( dtype T| sized(T) ) const T * ?+?( const T *, ptrdiff_t );196 forall( dtype T| sized(T) ) const T * ?+?( ptrdiff_t, const T * );197 forall( dtype T| sized(T) ) volatile T * ?+?( volatile T *, ptrdiff_t );198 forall( dtype T| sized(T) ) volatile T * ?+?( ptrdiff_t, volatile T * );199 forall( dtype T| sized(T) ) const volatile T * ?+?( const volatile T *, ptrdiff_t );200 forall( dtype T| sized(T) ) const volatile T * ?+?( ptrdiff_t, const volatile T * );201 forall( dtype T| sized(T) ) T * ?-?( T *, ptrdiff_t );202 forall( dtype T| sized(T) ) const T * ?-?( const T *, ptrdiff_t );203 forall( dtype T| sized(T) ) volatile T * ?-?( volatile T *, ptrdiff_t );204 forall( dtype T| sized(T) ) const volatile T * ?-?( const volatile T *, ptrdiff_t );205 forall( dtype T| sized(T) ) ptrdiff_t ?-?( const volatile T *, const volatile T * );193 forall( T & | sized(T) ) T * ?+?( T *, ptrdiff_t ); 194 forall( T & | sized(T) ) T * ?+?( ptrdiff_t, T * ); 195 forall( T & | sized(T) ) const T * ?+?( const T *, ptrdiff_t ); 196 forall( T & | sized(T) ) const T * ?+?( ptrdiff_t, const T * ); 197 forall( T & | sized(T) ) volatile T * ?+?( volatile T *, ptrdiff_t ); 198 forall( T & | sized(T) ) volatile T * ?+?( ptrdiff_t, volatile T * ); 199 forall( T & | sized(T) ) const volatile T * ?+?( const volatile T *, ptrdiff_t ); 200 forall( T & | sized(T) ) const volatile T * ?+?( ptrdiff_t, const volatile T * ); 201 forall( T & | sized(T) ) T * ?-?( T *, ptrdiff_t ); 202 forall( T & | sized(T) ) const T * ?-?( const T *, ptrdiff_t ); 203 forall( T & | sized(T) ) volatile T * ?-?( volatile T *, ptrdiff_t ); 204 forall( T & | sized(T) ) const volatile T * ?-?( const volatile T *, ptrdiff_t ); 205 forall( T & | sized(T) ) ptrdiff_t ?-?( const volatile T *, const volatile T * ); 206 206 207 207 // ------------------------------------------------------------ … … 255 255 ?>?( long double, long double ), ?>=?( long double, long double ); 256 256 257 forall( dtype DT) signed int ?<?( DT *, DT * );258 forall( dtype DT) signed int ?<?( const DT *, const DT * );259 forall( dtype DT) signed int ?<?( volatile DT *, volatile DT * );260 forall( dtype DT) signed int ?<?( const volatile DT *, const volatile DT * );261 262 forall( dtype DT) signed int ?>?( DT *, DT * );263 forall( dtype DT) signed int ?>?( const DT *, const DT * );264 forall( dtype DT) signed int ?>?( volatile DT *, volatile DT * );265 forall( dtype DT) signed int ?>?( const volatile DT *, const volatile DT * );266 267 forall( dtype DT) signed int ?<=?( DT *, DT * );268 forall( dtype DT) signed int ?<=?( const DT *, const DT * );269 forall( dtype DT) signed int ?<=?( volatile DT *, volatile DT * );270 forall( dtype DT) signed int ?<=?( const volatile DT *, const volatile DT * );271 272 forall( dtype DT) signed int ?>=?( DT *, DT * );273 forall( dtype DT) signed int ?>=?( const DT *, const DT * );274 forall( dtype DT) signed int ?>=?( volatile DT *, volatile DT * );275 forall( dtype DT) signed int ?>=?( const volatile DT *, const volatile DT * );257 forall( DT & ) signed int ?<?( DT *, DT * ); 258 forall( DT & ) signed int ?<?( const DT *, const DT * ); 259 forall( DT & ) signed int ?<?( volatile DT *, volatile DT * ); 260 forall( DT & ) signed int ?<?( const volatile DT *, const volatile DT * ); 261 262 forall( DT & ) signed int ?>?( DT *, DT * ); 263 forall( DT & ) signed int ?>?( const DT *, const DT * ); 264 forall( DT & ) signed int ?>?( volatile DT *, volatile DT * ); 265 forall( DT & ) signed int ?>?( const volatile DT *, const volatile DT * ); 266 267 forall( DT & ) signed int ?<=?( DT *, DT * ); 268 forall( DT & ) signed int ?<=?( const DT *, const DT * ); 269 forall( DT & ) signed int ?<=?( volatile DT *, volatile DT * ); 270 forall( DT & ) signed int ?<=?( const volatile DT *, const volatile DT * ); 271 272 forall( DT & ) signed int ?>=?( DT *, DT * ); 273 forall( DT & ) signed int ?>=?( const DT *, const DT * ); 274 forall( DT & ) signed int ?>=?( volatile DT *, volatile DT * ); 275 forall( DT & ) signed int ?>=?( const volatile DT *, const volatile DT * ); 276 276 277 277 // ------------------------------------------------------------ … … 302 302 signed int ?==?( one_t, one_t ), ?!=?( one_t, one_t ); 303 303 304 forall( dtype DT) signed int ?==?( DT *, DT * );305 forall( dtype DT) signed int ?==?( const DT *, const DT * );306 forall( dtype DT) signed int ?==?( volatile DT *, volatile DT * );307 forall( dtype DT) signed int ?==?( const volatile DT *, const volatile DT * );304 forall( DT & ) signed int ?==?( DT *, DT * ); 305 forall( DT & ) signed int ?==?( const DT *, const DT * ); 306 forall( DT & ) signed int ?==?( volatile DT *, volatile DT * ); 307 forall( DT & ) signed int ?==?( const volatile DT *, const volatile DT * ); 308 308 forall( ftype FT ) signed int ?==?( FT *, FT * ); 309 forall( dtype DT) signed int ?!=?( DT *, DT * );310 forall( dtype DT) signed int ?!=?( const DT *, const DT * );311 forall( dtype DT) signed int ?!=?( volatile DT *, volatile DT * );312 forall( dtype DT) signed int ?!=?( const volatile DT *, const volatile DT * );309 forall( DT & ) signed int ?!=?( DT *, DT * ); 310 forall( DT & ) signed int ?!=?( const DT *, const DT * ); 311 forall( DT & ) signed int ?!=?( volatile DT *, volatile DT * ); 312 forall( DT & ) signed int ?!=?( const volatile DT *, const volatile DT * ); 313 313 forall( ftype FT ) signed int ?!=?( FT *, FT * ); 314 314 … … 376 376 377 377 forall( ftype FT ) FT * ?=?( FT *&, FT * ); 378 forall( fty peFT ) FT * ?=?( FT * volatile &, FT * );379 380 forall( dtype DT) DT * ?=?( DT * &, DT * );381 forall( dtype DT) DT * ?=?( DT * volatile &, DT * );382 forall( dtype DT) const DT * ?=?( const DT * &, DT * );383 forall( dtype DT) const DT * ?=?( const DT * volatile &, DT * );384 forall( dtype DT) const DT * ?=?( const DT * &, const DT * );385 forall( dtype DT) const DT * ?=?( const DT * volatile &, const DT * );386 forall( dtype DT) volatile DT * ?=?( volatile DT * &, DT * );387 forall( dtype DT) volatile DT * ?=?( volatile DT * volatile &, DT * );388 forall( dtype DT) volatile DT * ?=?( volatile DT * &, volatile DT * );389 forall( dtype DT) volatile DT * ?=?( volatile DT * volatile &, volatile DT * );390 391 forall( dtype DT) const volatile DT * ?=?( const volatile DT * &, DT * );392 forall( dtype DT) const volatile DT * ?=?( const volatile DT * volatile &, DT * );393 forall( dtype DT) const volatile DT * ?=?( const volatile DT * &, const DT * );394 forall( dtype DT) const volatile DT * ?=?( const volatile DT * volatile &, const DT * );395 forall( dtype DT) const volatile DT * ?=?( const volatile DT * &, volatile DT * );396 forall( dtype DT) const volatile DT * ?=?( const volatile DT * volatile &, volatile DT * );397 forall( dtype DT) const volatile DT * ?=?( const volatile DT * &, const volatile DT * );398 forall( dtype DT) const volatile DT * ?=?( const volatile DT * volatile &, const volatile DT * );399 400 forall( dtype DT) void * ?=?( void * &, DT * );401 forall( dtype DT) void * ?=?( void * volatile &, DT * );402 forall( dtype DT) const void * ?=?( const void * &, DT * );403 forall( dtype DT) const void * ?=?( const void * volatile &, DT * );404 forall( dtype DT) const void * ?=?( const void * &, const DT * );405 forall( dtype DT) const void * ?=?( const void * volatile &, const DT * );406 forall( dtype DT) volatile void * ?=?( volatile void * &, DT * );407 forall( dtype DT) volatile void * ?=?( volatile void * volatile &, DT * );408 forall( dtype DT) volatile void * ?=?( volatile void * &, volatile DT * );409 forall( dtype DT) volatile void * ?=?( volatile void * volatile &, volatile DT * );410 forall( dtype DT) const volatile void * ?=?( const volatile void * &, DT * );411 forall( dtype DT) const volatile void * ?=?( const volatile void * volatile &, DT * );412 forall( dtype DT) const volatile void * ?=?( const volatile void * &, const DT * );413 forall( dtype DT) const volatile void * ?=?( const volatile void * volatile &, const DT * );414 forall( dtype DT) const volatile void * ?=?( const volatile void * &, volatile DT * );415 forall( dtype DT) const volatile void * ?=?( const volatile void * volatile &, volatile DT * );416 forall( dtype DT) const volatile void * ?=?( const volatile void * &, const volatile DT * );417 forall( dtype DT) const volatile void * ?=?( const volatile void * volatile &, const volatile DT * );378 forall( ftyep FT ) FT * ?=?( FT * volatile &, FT * ); 379 380 forall( DT & ) DT * ?=?( DT * &, DT * ); 381 forall( DT & ) DT * ?=?( DT * volatile &, DT * ); 382 forall( DT & ) const DT * ?=?( const DT * &, DT * ); 383 forall( DT & ) const DT * ?=?( const DT * volatile &, DT * ); 384 forall( DT & ) const DT * ?=?( const DT * &, const DT * ); 385 forall( DT & ) const DT * ?=?( const DT * volatile &, const DT * ); 386 forall( DT & ) volatile DT * ?=?( volatile DT * &, DT * ); 387 forall( DT & ) volatile DT * ?=?( volatile DT * volatile &, DT * ); 388 forall( DT & ) volatile DT * ?=?( volatile DT * &, volatile DT * ); 389 forall( DT & ) volatile DT * ?=?( volatile DT * volatile &, volatile DT * ); 390 391 forall( DT & ) const volatile DT * ?=?( const volatile DT * &, DT * ); 392 forall( DT & ) const volatile DT * ?=?( const volatile DT * volatile &, DT * ); 393 forall( DT & ) const volatile DT * ?=?( const volatile DT * &, const DT * ); 394 forall( DT & ) const volatile DT * ?=?( const volatile DT * volatile &, const DT * ); 395 forall( DT & ) const volatile DT * ?=?( const volatile DT * &, volatile DT * ); 396 forall( DT & ) const volatile DT * ?=?( const volatile DT * volatile &, volatile DT * ); 397 forall( DT & ) const volatile DT * ?=?( const volatile DT * &, const volatile DT * ); 398 forall( DT & ) const volatile DT * ?=?( const volatile DT * volatile &, const volatile DT * ); 399 400 forall( DT & ) void * ?=?( void * &, DT * ); 401 forall( DT & ) void * ?=?( void * volatile &, DT * ); 402 forall( DT & ) const void * ?=?( const void * &, DT * ); 403 forall( DT & ) const void * ?=?( const void * volatile &, DT * ); 404 forall( DT & ) const void * ?=?( const void * &, const DT * ); 405 forall( DT & ) const void * ?=?( const void * volatile &, const DT * ); 406 forall( DT & ) volatile void * ?=?( volatile void * &, DT * ); 407 forall( DT & ) volatile void * ?=?( volatile void * volatile &, DT * ); 408 forall( DT & ) volatile void * ?=?( volatile void * &, volatile DT * ); 409 forall( DT & ) volatile void * ?=?( volatile void * volatile &, volatile DT * ); 410 forall( DT & ) const volatile void * ?=?( const volatile void * &, DT * ); 411 forall( DT & ) const volatile void * ?=?( const volatile void * volatile &, DT * ); 412 forall( DT & ) const volatile void * ?=?( const volatile void * &, const DT * ); 413 forall( DT & ) const volatile void * ?=?( const volatile void * volatile &, const DT * ); 414 forall( DT & ) const volatile void * ?=?( const volatile void * &, volatile DT * ); 415 forall( DT & ) const volatile void * ?=?( const volatile void * volatile &, volatile DT * ); 416 forall( DT & ) const volatile void * ?=?( const volatile void * &, const volatile DT * ); 417 forall( DT & ) const volatile void * ?=?( const volatile void * volatile &, const volatile DT * ); 418 418 419 419 //forall( dtype DT ) DT * ?=?( DT * &, zero_t ); 420 420 //forall( dtype DT ) DT * ?=?( DT * volatile &, zero_t ); 421 forall( dtype DT) const DT * ?=?( const DT * &, zero_t );422 forall( dtype DT) const DT * ?=?( const DT * volatile &, zero_t );421 forall( DT & ) const DT * ?=?( const DT * &, zero_t ); 422 forall( DT & ) const DT * ?=?( const DT * volatile &, zero_t ); 423 423 //forall( dtype DT ) volatile DT * ?=?( volatile DT * &, zero_t ); 424 424 //forall( dtype DT ) volatile DT * ?=?( volatile DT * volatile &, zero_t ); 425 forall( dtype DT) const volatile DT * ?=?( const volatile DT * &, zero_t );426 forall( dtype DT) const volatile DT * ?=?( const volatile DT * volatile &, zero_t );425 forall( DT & ) const volatile DT * ?=?( const volatile DT * &, zero_t ); 426 forall( DT & ) const volatile DT * ?=?( const volatile DT * volatile &, zero_t ); 427 427 428 428 forall( ftype FT ) FT * ?=?( FT * &, zero_t ); 429 429 forall( ftype FT ) FT * ?=?( FT * volatile &, zero_t ); 430 430 431 forall( dtype T| sized(T) ) T * ?+=?( T * &, ptrdiff_t );432 forall( dtype T| sized(T) ) T * ?+=?( T * volatile &, ptrdiff_t );433 forall( dtype T| sized(T) ) const T * ?+=?( const T * &, ptrdiff_t );434 forall( dtype T| sized(T) ) const T * ?+=?( const T * volatile &, ptrdiff_t );435 forall( dtype T| sized(T) ) volatile T * ?+=?( volatile T * &, ptrdiff_t );436 forall( dtype T| sized(T) ) volatile T * ?+=?( volatile T * volatile &, ptrdiff_t );437 forall( dtype T| sized(T) ) const volatile T * ?+=?( const volatile T * &, ptrdiff_t );438 forall( dtype T| sized(T) ) const volatile T * ?+=?( const volatile T * volatile &, ptrdiff_t );439 forall( dtype T| sized(T) ) T * ?-=?( T * &, ptrdiff_t );440 forall( dtype T| sized(T) ) T * ?-=?( T * volatile &, ptrdiff_t );441 forall( dtype T| sized(T) ) const T * ?-=?( const T * &, ptrdiff_t );442 forall( dtype T| sized(T) ) const T * ?-=?( const T * volatile &, ptrdiff_t );443 forall( dtype T| sized(T) ) volatile T * ?-=?( volatile T * &, ptrdiff_t );444 forall( dtype T| sized(T) ) volatile T * ?-=?( volatile T * volatile &, ptrdiff_t );445 forall( dtype T| sized(T) ) const volatile T * ?-=?( const volatile T * &, ptrdiff_t );446 forall( dtype T| sized(T) ) const volatile T * ?-=?( const volatile T * volatile &, ptrdiff_t );431 forall( T & | sized(T) ) T * ?+=?( T * &, ptrdiff_t ); 432 forall( T & | sized(T) ) T * ?+=?( T * volatile &, ptrdiff_t ); 433 forall( T & | sized(T) ) const T * ?+=?( const T * &, ptrdiff_t ); 434 forall( T & | sized(T) ) const T * ?+=?( const T * volatile &, ptrdiff_t ); 435 forall( T & | sized(T) ) volatile T * ?+=?( volatile T * &, ptrdiff_t ); 436 forall( T & | sized(T) ) volatile T * ?+=?( volatile T * volatile &, ptrdiff_t ); 437 forall( T & | sized(T) ) const volatile T * ?+=?( const volatile T * &, ptrdiff_t ); 438 forall( T & | sized(T) ) const volatile T * ?+=?( const volatile T * volatile &, ptrdiff_t ); 439 forall( T & | sized(T) ) T * ?-=?( T * &, ptrdiff_t ); 440 forall( T & | sized(T) ) T * ?-=?( T * volatile &, ptrdiff_t ); 441 forall( T & | sized(T) ) const T * ?-=?( const T * &, ptrdiff_t ); 442 forall( T & | sized(T) ) const T * ?-=?( const T * volatile &, ptrdiff_t ); 443 forall( T & | sized(T) ) volatile T * ?-=?( volatile T * &, ptrdiff_t ); 444 forall( T & | sized(T) ) volatile T * ?-=?( volatile T * volatile &, ptrdiff_t ); 445 forall( T & | sized(T) ) const volatile T * ?-=?( const volatile T * &, ptrdiff_t ); 446 forall( T & | sized(T) ) const volatile T * ?-=?( const volatile T * volatile &, ptrdiff_t ); 447 447 448 448 _Bool ?=?( _Bool &, _Bool ), ?=?( volatile _Bool &, _Bool ); … … 723 723 forall( ftype FT ) void ?{}( FT * volatile &, FT * ); 724 724 725 forall( dtype DT) void ?{}( DT * &, DT * );726 forall( dtype DT) void ?{}( const DT * &, DT * );727 forall( dtype DT) void ?{}( const DT * &, const DT * );728 forall( dtype DT) void ?{}( volatile DT * &, DT * );729 forall( dtype DT) void ?{}( volatile DT * &, volatile DT * );730 forall( dtype DT) void ?{}( const volatile DT * &, DT * );731 forall( dtype DT) void ?{}( const volatile DT * &, const DT * );732 forall( dtype DT) void ?{}( const volatile DT * &, volatile DT * );733 forall( dtype DT) void ?{}( const volatile DT * &, const volatile DT * );734 735 forall( dtype DT) void ?{}( void * &, DT * );736 forall( dtype DT) void ?{}( const void * &, DT * );737 forall( dtype DT) void ?{}( const void * &, const DT * );738 forall( dtype DT) void ?{}( volatile void * &, DT * );739 forall( dtype DT) void ?{}( volatile void * &, volatile DT * );740 forall( dtype DT) void ?{}( const volatile void * &, DT * );741 forall( dtype DT) void ?{}( const volatile void * &, const DT * );742 forall( dtype DT) void ?{}( const volatile void * &, volatile DT * );743 forall( dtype DT) void ?{}( const volatile void * &, const volatile DT * );725 forall( DT & ) void ?{}( DT * &, DT * ); 726 forall( DT & ) void ?{}( const DT * &, DT * ); 727 forall( DT & ) void ?{}( const DT * &, const DT * ); 728 forall( DT & ) void ?{}( volatile DT * &, DT * ); 729 forall( DT & ) void ?{}( volatile DT * &, volatile DT * ); 730 forall( DT & ) void ?{}( const volatile DT * &, DT * ); 731 forall( DT & ) void ?{}( const volatile DT * &, const DT * ); 732 forall( DT & ) void ?{}( const volatile DT * &, volatile DT * ); 733 forall( DT & ) void ?{}( const volatile DT * &, const volatile DT * ); 734 735 forall( DT & ) void ?{}( void * &, DT * ); 736 forall( DT & ) void ?{}( const void * &, DT * ); 737 forall( DT & ) void ?{}( const void * &, const DT * ); 738 forall( DT & ) void ?{}( volatile void * &, DT * ); 739 forall( DT & ) void ?{}( volatile void * &, volatile DT * ); 740 forall( DT & ) void ?{}( const volatile void * &, DT * ); 741 forall( DT & ) void ?{}( const volatile void * &, const DT * ); 742 forall( DT & ) void ?{}( const volatile void * &, volatile DT * ); 743 forall( DT & ) void ?{}( const volatile void * &, const volatile DT * ); 744 744 745 745 //forall( dtype DT ) void ?{}( DT * &, zero_t ); 746 746 //forall( dtype DT ) void ?{}( DT * volatile &, zero_t ); 747 forall( dtype DT) void ?{}( const DT * &, zero_t );747 forall( DT & ) void ?{}( const DT * &, zero_t ); 748 748 //forall( dtype DT ) void ?{}( volatile DT * &, zero_t ); 749 749 //forall( dtype DT ) void ?{}( volatile DT * volatile &, zero_t ); 750 forall( dtype DT) void ?{}( const volatile DT * &, zero_t );750 forall( DT & ) void ?{}( const volatile DT * &, zero_t ); 751 751 752 752 forall( ftype FT ) void ?{}( FT * &, zero_t ); … … 755 755 forall( ftype FT ) void ?{}( FT * & ); 756 756 757 forall( dtype DT) void ?{}( DT * &);758 forall( dtype DT) void ?{}( const DT * &);759 forall( dtype DT) void ?{}( volatile DT * &);760 forall( dtype DT) void ?{}( const volatile DT * &);757 forall( DT & ) void ?{}( DT * &); 758 forall( DT & ) void ?{}( const DT * &); 759 forall( DT & ) void ?{}( volatile DT * &); 760 forall( DT & ) void ?{}( const volatile DT * &); 761 761 762 762 void ?{}( void * &); … … 768 768 forall( ftype FT ) void ^?{}( FT * & ); 769 769 770 forall( dtype DT) void ^?{}( DT * &);771 forall( dtype DT) void ^?{}( const DT * &);772 forall( dtype DT) void ^?{}( volatile DT * &);773 forall( dtype DT) void ^?{}( const volatile DT * &);770 forall( DT & ) void ^?{}( DT * &); 771 forall( DT & ) void ^?{}( const DT * &); 772 forall( DT & ) void ^?{}( volatile DT * &); 773 forall( DT & ) void ^?{}( const volatile DT * &); 774 774 775 775 void ^?{}( void * &); -
libcfa/prelude/sync-builtins.cf
r467c8b7 rc08c3cf 206 206 _Bool __sync_bool_compare_and_swap(volatile unsigned __int128 *, unsigned __int128, unsigned __int128,...); 207 207 #endif 208 forall( dtype T) _Bool __sync_bool_compare_and_swap(T * volatile *, T *, T*, ...);208 forall(T &) _Bool __sync_bool_compare_and_swap(T * volatile *, T *, T*, ...); 209 209 210 210 char __sync_val_compare_and_swap(volatile char *, char, char,...); … … 223 223 unsigned __int128 __sync_val_compare_and_swap(volatile unsigned __int128 *, unsigned __int128, unsigned __int128,...); 224 224 #endif 225 forall( dtype T) T * __sync_val_compare_and_swap(T * volatile *, T *, T*,...);225 forall(T &) T * __sync_val_compare_and_swap(T * volatile *, T *, T*,...); 226 226 227 227 char __sync_lock_test_and_set(volatile char *, char,...); … … 326 326 void __atomic_exchange(volatile unsigned __int128 *, volatile unsigned __int128 *, volatile unsigned __int128 *, int); 327 327 #endif 328 forall( dtype T) T * __atomic_exchange_n(T * volatile *, T *, int);329 forall( dtype T) void __atomic_exchange(T * volatile *, T * volatile *, T * volatile *, int);328 forall(T &) T * __atomic_exchange_n(T * volatile *, T *, int); 329 forall(T &) void __atomic_exchange(T * volatile *, T * volatile *, T * volatile *, int); 330 330 331 331 _Bool __atomic_load_n(const volatile _Bool *, int); … … 359 359 void __atomic_load(const volatile unsigned __int128 *, volatile unsigned __int128 *, int); 360 360 #endif 361 forall( dtype T) T * __atomic_load_n(T * const volatile *, int);362 forall( dtype T) void __atomic_load(T * const volatile *, T **, int);361 forall(T &) T * __atomic_load_n(T * const volatile *, int); 362 forall(T &) void __atomic_load(T * const volatile *, T **, int); 363 363 364 364 _Bool __atomic_compare_exchange_n(volatile char *, char *, char, _Bool, int, int); … … 390 390 _Bool __atomic_compare_exchange (volatile unsigned __int128 *, unsigned __int128 *, unsigned __int128 *, _Bool, int, int); 391 391 #endif 392 forall( dtype T) _Bool __atomic_compare_exchange_n (T * volatile *, T **, T*, _Bool, int, int);393 forall( dtype T) _Bool __atomic_compare_exchange (T * volatile *, T **, T**, _Bool, int, int);392 forall(T &) _Bool __atomic_compare_exchange_n (T * volatile *, T **, T*, _Bool, int, int); 393 forall(T &) _Bool __atomic_compare_exchange (T * volatile *, T **, T**, _Bool, int, int); 394 394 395 395 void __atomic_store_n(volatile _Bool *, _Bool, int); … … 423 423 void __atomic_store(volatile unsigned __int128 *, unsigned __int128 *, int); 424 424 #endif 425 forall( dtype T) void __atomic_store_n(T * volatile *, T *, int);426 forall( dtype T) void __atomic_store(T * volatile *, T **, int);425 forall(T &) void __atomic_store_n(T * volatile *, T *, int); 426 forall(T &) void __atomic_store(T * volatile *, T **, int); 427 427 428 428 char __atomic_add_fetch (volatile char *, char, int); -
libcfa/src/bitmanip.hfa
r467c8b7 rc08c3cf 100 100 unsigned long long int floor2( unsigned long long int n, unsigned long long int align ) { verify( is_pow2( align ) ); return n & -align; } 101 101 102 // forall( otypeT | { T ?&?( T, T ); T -?( T ); } )102 // forall( T | { T ?&?( T, T ); T -?( T ); } ) 103 103 // T floor2( T n, T align ) { verify( is_pow2( align ) ); return n & -align; } 104 104 … … 115 115 unsigned long long int ceiling2( unsigned long long int n, unsigned long long int align ) { verify( is_pow2( align ) ); return -floor2( -n, align ); } 116 116 117 // forall( otypeT | { T floor2( T, T ); T -?( T ); } )117 // forall( T | { T floor2( T, T ); T -?( T ); } ) 118 118 // T ceiling2( T n, T align ) { verify( is_pow2( align ) ); return -floor2( -n, align ); } 119 119 } // distribution -
libcfa/src/bits/algorithm.hfa
r467c8b7 rc08c3cf 17 17 18 18 #ifdef SAFE_SORT 19 forall( otypeT | { int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort2( T * arr );20 forall( otypeT | { int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort3( T * arr );21 forall( otypeT | { int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort4( T * arr );22 forall( otypeT | { int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort5( T * arr );23 forall( otypeT | { int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort6( T * arr );24 forall( otypeT | { int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sortN( T * arr, size_t dim );19 forall( T | { int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort2( T * arr ); 20 forall( T | { int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort3( T * arr ); 21 forall( T | { int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort4( T * arr ); 22 forall( T | { int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort5( T * arr ); 23 forall( T | { int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort6( T * arr ); 24 forall( T | { int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sortN( T * arr, size_t dim ); 25 25 26 forall( otypeT | { int ?<?( T, T ); int ?>?( T, T ); } )26 forall( T | { int ?<?( T, T ); int ?>?( T, T ); } ) 27 27 static inline void __libcfa_small_sort( T * arr, size_t dim ) { 28 28 switch( dim ) { … … 41 41 #define SWAP(x,y) { T a = min(arr[x], arr[y]); T b = max(arr[x], arr[y]); arr[x] = a; arr[y] = b;} 42 42 43 forall( otypeT | { int ?<?( T, T ); int ?>?( T, T ); } )43 forall( T | { int ?<?( T, T ); int ?>?( T, T ); } ) 44 44 static inline void __libcfa_small_sort2( T * arr ) { 45 45 SWAP(0, 1); 46 46 } 47 47 48 forall( otypeT | { int ?<?( T, T ); int ?>?( T, T ); } )48 forall( T | { int ?<?( T, T ); int ?>?( T, T ); } ) 49 49 static inline void __libcfa_small_sort3( T * arr ) { 50 50 SWAP(1, 2); … … 53 53 } 54 54 55 forall( otypeT | { int ?<?( T, T ); int ?>?( T, T ); } )55 forall( T | { int ?<?( T, T ); int ?>?( T, T ); } ) 56 56 static inline void __libcfa_small_sort4( T * arr ) { 57 57 SWAP(0, 1); … … 62 62 } 63 63 64 forall( otypeT | { int ?<?( T, T ); int ?>?( T, T ); } )64 forall( T | { int ?<?( T, T ); int ?>?( T, T ); } ) 65 65 static inline void __libcfa_small_sort5( T * arr ) { 66 66 SWAP(0, 1); … … 75 75 } 76 76 77 forall( otypeT | { int ?<?( T, T ); int ?>?( T, T ); } )77 forall( T | { int ?<?( T, T ); int ?>?( T, T ); } ) 78 78 static inline void __libcfa_small_sort6( T * arr ) { 79 79 SWAP(1, 2); … … 91 91 } 92 92 93 forall( otypeT | { int ?<?( T, T ); int ?>?( T, T ); } )93 forall( T | { int ?<?( T, T ); int ?>?( T, T ); } ) 94 94 static inline void __libcfa_small_sortN( T * arr, size_t dim ) { 95 95 int i, j; … … 112 112 static inline void __libcfa_small_sortN( void* * arr, size_t dim ); 113 113 114 forall( dtype T)114 forall( T & ) 115 115 static inline void __libcfa_small_sort( T* * arr, size_t dim ) { 116 116 switch( dim ) { -
libcfa/src/bits/collection.hfa
r467c8b7 rc08c3cf 31 31 32 32 // // wrappers to make Collection have T 33 // forall( dtype T) {33 // forall( T & ) { 34 34 // T *& Next( T * n ) { 35 35 // return (T *)Next( (Colable *)n ); … … 76 76 } // post: elts = null 77 77 78 forall( dtype T) {78 forall( T & ) { 79 79 T * Curr( ColIter & ci ) with( ci ) { 80 80 return (T *)curr; -
libcfa/src/bits/containers.hfa
r467c8b7 rc08c3cf 23 23 24 24 #ifdef __cforall 25 forall( dtype T)25 forall(T &) 26 26 #else 27 27 #define T void … … 40 40 41 41 #ifdef __cforall 42 // forall( otypeT | sized(T))42 // forall(T | sized(T)) 43 43 // static inline void ?{}(__small_array(T) & this) {} 44 44 45 forall( dtype T| sized(T))45 forall(T & | sized(T)) 46 46 static inline T & ?[?]( __small_array(T) & this, __lock_size_t idx ) { 47 47 return ((typeof(this.data))this.data)[idx]; 48 48 } 49 49 50 forall( dtype T| sized(T))50 forall(T & | sized(T)) 51 51 static inline T & ?[?]( const __small_array(T) & this, __lock_size_t idx ) { 52 52 return ((typeof(this.data))this.data)[idx]; 53 53 } 54 54 55 forall( dtype T)55 forall(T &) 56 56 static inline T * begin( const __small_array(T) & this ) { 57 57 return ((typeof(this.data))this.data); 58 58 } 59 59 60 forall( dtype T| sized(T))60 forall(T & | sized(T)) 61 61 static inline T * end( const __small_array(T) & this ) { 62 62 return ((typeof(this.data))this.data) + this.size; … … 69 69 70 70 #ifdef __cforall 71 trait is_node( dtype T) {71 trait is_node(T &) { 72 72 T *& get_next( T & ); 73 73 }; … … 78 78 //----------------------------------------------------------------------------- 79 79 #ifdef __cforall 80 forall( dtype TYPE)80 forall(TYPE &) 81 81 #define T TYPE 82 82 #else … … 95 95 96 96 #ifdef __cforall 97 forall( dtype T)97 forall(T &) 98 98 static inline void ?{}( __stack(T) & this ) { 99 99 (this.top){ 0p }; 100 100 } 101 101 102 static inline forall( dtype T| is_node(T) ) {102 static inline forall( T & | is_node(T) ) { 103 103 void push( __stack(T) & this, T * val ) { 104 104 verify( !get_next( *val ) ); … … 126 126 //----------------------------------------------------------------------------- 127 127 #ifdef __cforall 128 forall( dtype TYPE)128 forall(TYPE &) 129 129 #define T TYPE 130 130 #else … … 144 144 145 145 #ifdef __cforall 146 static inline forall( dtype T| is_node(T) ) {146 static inline forall( T & | is_node(T) ) { 147 147 void ?{}( __queue(T) & this ) with( this ) { 148 148 (this.head){ 1p }; … … 215 215 //----------------------------------------------------------------------------- 216 216 #ifdef __cforall 217 forall( dtype TYPE)217 forall(TYPE &) 218 218 #define T TYPE 219 219 #define __getter_t * [T * & next, T * & prev] ( T & ) … … 237 237 238 238 #ifdef __cforall 239 forall( dtype T)239 forall(T & ) 240 240 static inline [void] ?{}( __dllist(T) & this, * [T * & next, T * & prev] ( T & ) __get ) { 241 241 (this.head){ 0p }; … … 245 245 #define next 0 246 246 #define prev 1 247 static inline forall( dtype T) {247 static inline forall(T &) { 248 248 void push_front( __dllist(T) & this, T & node ) with( this ) { 249 249 verify(__get); -
libcfa/src/bits/defs.hfa
r467c8b7 rc08c3cf 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // defs.hfa -- 7 // defs.hfa -- Commen macros, functions and typedefs 8 // Most files depend on them and they are always useful to have. 9 // 10 // *** Must not contain code specific to libcfathread *** 8 11 // 9 12 // Author : Thierry Delisle … … 62 65 #endif 63 66 } 67 68 // pause to prevent excess processor bus usage 69 #if defined( __i386 ) || defined( __x86_64 ) 70 #define Pause() __asm__ __volatile__ ( "pause" : : : ) 71 #elif defined( __ARM_ARCH ) 72 #define Pause() __asm__ __volatile__ ( "YIELD" : : : ) 73 #else 74 #error unsupported architecture 75 #endif -
libcfa/src/bits/locks.hfa
r467c8b7 rc08c3cf 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // bits/locks.hfa -- Fast internal locks. 7 // bits/locks.hfa -- Basic spinlocks that are reused in the system. 8 // Used for locks that aren't specific to cforall threads and can be used anywhere 9 // 10 // *** Must not contain code specific to libcfathread *** 8 11 // 9 12 // Author : Thierry Delisle … … 19 22 #include "bits/defs.hfa" 20 23 #include <assert.h> 21 22 #ifdef __cforall23 extern "C" {24 #include <pthread.h>25 }26 #endif27 28 // pause to prevent excess processor bus usage29 #if defined( __i386 ) || defined( __x86_64 )30 #define Pause() __asm__ __volatile__ ( "pause" : : : )31 #elif defined( __ARM_ARCH )32 #define Pause() __asm__ __volatile__ ( "YIELD" : : : )33 #else34 #error unsupported architecture35 #endif36 24 37 25 struct __spinlock_t { … … 104 92 enable_interrupts_noPoll(); 105 93 } 106 107 108 #ifdef __CFA_WITH_VERIFY__109 extern bool __cfaabi_dbg_in_kernel();110 #endif111 112 extern "C" {113 char * strerror(int);114 }115 #define CHECKED(x) { int err = x; if( err != 0 ) abort("KERNEL ERROR: Operation \"" #x "\" return error %d - %s\n", err, strerror(err)); }116 117 struct __bin_sem_t {118 pthread_mutex_t lock;119 pthread_cond_t cond;120 int val;121 };122 123 static inline void ?{}(__bin_sem_t & this) with( this ) {124 // Create the mutex with error checking125 pthread_mutexattr_t mattr;126 pthread_mutexattr_init( &mattr );127 pthread_mutexattr_settype( &mattr, PTHREAD_MUTEX_ERRORCHECK_NP);128 pthread_mutex_init(&lock, &mattr);129 130 pthread_cond_init (&cond, (const pthread_condattr_t *)0p); // workaround trac#208: cast should not be required131 val = 0;132 }133 134 static inline void ^?{}(__bin_sem_t & this) with( this ) {135 CHECKED( pthread_mutex_destroy(&lock) );136 CHECKED( pthread_cond_destroy (&cond) );137 }138 139 static inline void wait(__bin_sem_t & this) with( this ) {140 verify(__cfaabi_dbg_in_kernel());141 CHECKED( pthread_mutex_lock(&lock) );142 while(val < 1) {143 pthread_cond_wait(&cond, &lock);144 }145 val -= 1;146 CHECKED( pthread_mutex_unlock(&lock) );147 }148 149 static inline bool post(__bin_sem_t & this) with( this ) {150 bool needs_signal = false;151 152 CHECKED( pthread_mutex_lock(&lock) );153 if(val < 1) {154 val += 1;155 pthread_cond_signal(&cond);156 needs_signal = true;157 }158 CHECKED( pthread_mutex_unlock(&lock) );159 160 return needs_signal;161 }162 163 #undef CHECKED164 165 struct $thread;166 extern void park( void );167 extern void unpark( struct $thread * this );168 static inline struct $thread * active_thread ();169 170 // Semaphore which only supports a single thread171 struct single_sem {172 struct $thread * volatile ptr;173 };174 175 static inline {176 void ?{}(single_sem & this) {177 this.ptr = 0p;178 }179 180 void ^?{}(single_sem &) {}181 182 bool wait(single_sem & this) {183 for() {184 struct $thread * expected = this.ptr;185 if(expected == 1p) {186 if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {187 return false;188 }189 }190 else {191 /* paranoid */ verify( expected == 0p );192 if(__atomic_compare_exchange_n(&this.ptr, &expected, active_thread(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {193 park();194 return true;195 }196 }197 198 }199 }200 201 bool post(single_sem & this) {202 for() {203 struct $thread * expected = this.ptr;204 if(expected == 1p) return false;205 if(expected == 0p) {206 if(__atomic_compare_exchange_n(&this.ptr, &expected, 1p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {207 return false;208 }209 }210 else {211 if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {212 unpark( expected );213 return true;214 }215 }216 }217 }218 }219 220 // Synchronozation primitive which only supports a single thread and one post221 // Similar to a binary semaphore with a 'one shot' semantic222 // is expected to be discarded after each party call their side223 struct oneshot {224 // Internal state :225 // 0p : is initial state (wait will block)226 // 1p : fulfilled (wait won't block)227 // any thread : a thread is currently waiting228 struct $thread * volatile ptr;229 };230 231 static inline {232 void ?{}(oneshot & this) {233 this.ptr = 0p;234 }235 236 void ^?{}(oneshot &) {}237 238 // Wait for the post, return immidiately if it already happened.239 // return true if the thread was parked240 bool wait(oneshot & this) {241 for() {242 struct $thread * expected = this.ptr;243 if(expected == 1p) return false;244 /* paranoid */ verify( expected == 0p );245 if(__atomic_compare_exchange_n(&this.ptr, &expected, active_thread(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {246 park();247 /* paranoid */ verify( this.ptr == 1p );248 return true;249 }250 }251 }252 253 // Mark as fulfilled, wake thread if needed254 // return true if a thread was unparked255 bool post(oneshot & this) {256 struct $thread * got = __atomic_exchange_n( &this.ptr, 1p, __ATOMIC_SEQ_CST);257 if( got == 0p ) return false;258 unpark( got );259 return true;260 }261 }262 263 // base types for future to build upon264 // It is based on the 'oneshot' type to allow multiple futures265 // to block on the same instance, permitting users to block a single266 // thread on "any of" [a given set of] futures.267 // does not support multiple threads waiting on the same future268 struct future_t {269 // Internal state :270 // 0p : is initial state (wait will block)271 // 1p : fulfilled (wait won't block)272 // 2p : in progress ()273 // 3p : abandoned, server should delete274 // any oneshot : a context has been setup to wait, a thread could wait on it275 struct oneshot * volatile ptr;276 };277 278 static inline {279 void ?{}(future_t & this) {280 this.ptr = 0p;281 }282 283 void ^?{}(future_t &) {}284 285 void reset(future_t & this) {286 // needs to be in 0p or 1p287 __atomic_exchange_n( &this.ptr, 0p, __ATOMIC_SEQ_CST);288 }289 290 // check if the future is available291 bool available( future_t & this ) {292 return this.ptr == 1p;293 }294 295 // Prepare the future to be waited on296 // intented to be use by wait, wait_any, waitfor, etc. rather than used directly297 bool setup( future_t & this, oneshot & wait_ctx ) {298 /* paranoid */ verify( wait_ctx.ptr == 0p );299 // The future needs to set the wait context300 for() {301 struct oneshot * expected = this.ptr;302 // Is the future already fulfilled?303 if(expected == 1p) return false; // Yes, just return false (didn't block)304 305 // The future is not fulfilled, try to setup the wait context306 /* paranoid */ verify( expected == 0p );307 if(__atomic_compare_exchange_n(&this.ptr, &expected, &wait_ctx, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {308 return true;309 }310 }311 }312 313 // Stop waiting on a future314 // When multiple futures are waited for together in "any of" pattern315 // futures that weren't fulfilled before the thread woke up316 // should retract the wait ctx317 // intented to be use by wait, wait_any, waitfor, etc. rather than used directly318 void retract( future_t & this, oneshot & wait_ctx ) {319 // Remove the wait context320 struct oneshot * got = __atomic_exchange_n( &this.ptr, 0p, __ATOMIC_SEQ_CST);321 322 // got == 0p: future was never actually setup, just return323 if( got == 0p ) return;324 325 // got == wait_ctx: since fulfil does an atomic_swap,326 // if we got back the original then no one else saw context327 // It is safe to delete (which could happen after the return)328 if( got == &wait_ctx ) return;329 330 // got == 1p: the future is ready and the context was fully consumed331 // the server won't use the pointer again332 // It is safe to delete (which could happen after the return)333 if( got == 1p ) return;334 335 // got == 2p: the future is ready but the context hasn't fully been consumed336 // spin until it is safe to move on337 if( got == 2p ) {338 while( this.ptr != 1p ) Pause();339 return;340 }341 342 // got == any thing else, something wen't wrong here, abort343 abort("Future in unexpected state");344 }345 346 // Mark the future as abandoned, meaning it will be deleted by the server347 bool abandon( future_t & this ) {348 /* paranoid */ verify( this.ptr != 3p );349 350 // Mark the future as abandonned351 struct oneshot * got = __atomic_exchange_n( &this.ptr, 3p, __ATOMIC_SEQ_CST);352 353 // If the future isn't already fulfilled, let the server delete it354 if( got == 0p ) return false;355 356 // got == 2p: the future is ready but the context hasn't fully been consumed357 // spin until it is safe to move on358 if( got == 2p ) {359 while( this.ptr != 1p ) Pause();360 got = 1p;361 }362 363 // The future is completed delete it now364 /* paranoid */ verify( this.ptr != 1p );365 free( &this );366 return true;367 }368 369 // from the server side, mark the future as fulfilled370 // delete it if needed371 bool fulfil( future_t & this ) {372 for() {373 struct oneshot * expected = this.ptr;374 // was this abandoned?375 #if defined(__GNUC__) && __GNUC__ >= 7376 #pragma GCC diagnostic push377 #pragma GCC diagnostic ignored "-Wfree-nonheap-object"378 #endif379 if( expected == 3p ) { free( &this ); return false; }380 #if defined(__GNUC__) && __GNUC__ >= 7381 #pragma GCC diagnostic pop382 #endif383 384 /* paranoid */ verify( expected != 1p ); // Future is already fulfilled, should not happen385 /* paranoid */ verify( expected != 2p ); // Future is bein fulfilled by someone else, this is even less supported then the previous case.386 387 // If there is a wait context, we need to consume it and mark it as consumed after388 // If there is no context then we can skip the in progress phase389 struct oneshot * want = expected == 0p ? 1p : 2p;390 if(__atomic_compare_exchange_n(&this.ptr, &expected, want, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {391 if( expected == 0p ) { /* paranoid */ verify( this.ptr == 1p); return false; }392 bool ret = post( *expected );393 __atomic_store_n( &this.ptr, 1p, __ATOMIC_SEQ_CST);394 return ret;395 }396 }397 398 }399 400 // Wait for the future to be fulfilled401 bool wait( future_t & this ) {402 oneshot temp;403 if( !setup(this, temp) ) return false;404 405 // Wait context is setup, just wait on it406 bool ret = wait( temp );407 408 // Wait for the future to tru409 while( this.ptr == 2p ) Pause();410 // Make sure the state makes sense411 // Should be fulfilled, could be in progress but it's out of date if so412 // since if that is the case, the oneshot was fulfilled (unparking this thread)413 // and the oneshot should not be needed any more414 __attribute__((unused)) struct oneshot * was = this.ptr;415 /* paranoid */ verifyf( was == 1p, "Expected this.ptr to be 1p, was %p\n", was );416 417 // Mark the future as fulfilled, to be consistent418 // with potential calls to avail419 // this.ptr = 1p;420 return ret;421 }422 }423 94 #endif -
libcfa/src/bits/queue.hfa
r467c8b7 rc08c3cf 9 9 // instead of being null. 10 10 11 forall( dtype T| { T *& Next ( T * ); } ) {11 forall( T & | { T *& Next ( T * ); } ) { 12 12 struct Queue { 13 13 inline Collection; // Plan 9 inheritance … … 151 151 } // distribution 152 152 153 forall( dtype T| { T *& Next ( T * ); } ) {153 forall( T & | { T *& Next ( T * ); } ) { 154 154 struct QueueIter { 155 155 inline ColIter; // Plan 9 inheritance -
libcfa/src/bits/sequence.hfa
r467c8b7 rc08c3cf 29 29 30 30 // // wrappers to make Collection have T 31 // forall( dtype T) {31 // forall( T & ) { 32 32 // T *& Back( T * n ) { 33 33 // return (T *)Back( (Seqable *)n ); … … 43 43 // and the back field of the last node points at the first node (circular). 44 44 45 forall( dtype T| { T *& Back ( T * ); T *& Next ( T * ); } ) {45 forall( T & | { T *& Back ( T * ); T *& Next ( T * ); } ) { 46 46 struct Sequence { 47 47 inline Collection; // Plan 9 inheritance … … 231 231 } // distribution 232 232 233 forall( dtype T| { T *& Back ( T * ); T *& Next ( T * ); } ) {233 forall( T & | { T *& Back ( T * ); T *& Next ( T * ); } ) { 234 234 // SeqIter(T) is used to iterate over a Sequence(T) in head-to-tail order. 235 235 struct SeqIter { -
libcfa/src/bits/stack.hfa
r467c8b7 rc08c3cf 9 9 // instead of being null. 10 10 11 forall( dtype T| { T *& Next ( T * ); } ) {11 forall( T & | { T *& Next ( T * ); } ) { 12 12 struct Stack { 13 13 inline Collection; // Plan 9 inheritance … … 67 67 // order returned by drop(). 68 68 69 forall( dtype T| { T *& Next ( T * ); } ) {69 forall( T & | { T *& Next ( T * ); } ) { 70 70 struct StackIter { 71 71 inline ColIter; // Plan 9 inheritance -
libcfa/src/common.cfa
r467c8b7 rc08c3cf 23 23 [ long int, long int ] div( long int num, long int denom ) { ldiv_t qr = ldiv( num, denom ); return [ qr.quot, qr.rem ]; } 24 24 [ long long int, long long int ] div( long long int num, long long int denom ) { lldiv_t qr = lldiv( num, denom ); return [ qr.quot, qr.rem ]; } 25 forall( otypeT | { T ?/?( T, T ); T ?%?( T, T ); } )25 forall( T | { T ?/?( T, T ); T ?%?( T, T ); } ) 26 26 [ T, T ] div( T num, T denom ) { return [ num / denom, num % denom ]; } 27 27 -
libcfa/src/common.hfa
r467c8b7 rc08c3cf 21 21 [ long int, long int ] div( long int num, long int denom ); 22 22 [ long long int, long long int ] div( long long int num, long long int denom ); 23 forall( otypeT | { T ?/?( T, T ); T ?%?( T, T ); } )23 forall( T | { T ?/?( T, T ); T ?%?( T, T ); } ) 24 24 [ T, T ] div( T num, T demon ); 25 25 … … 61 61 } // distribution 62 62 63 forall( otypeT | { void ?{}( T &, zero_t ); int ?<?( T, T ); T -?( T ); } )63 forall( T | { void ?{}( T &, zero_t ); int ?<?( T, T ); T -?( T ); } ) 64 64 T abs( T ); 65 65 … … 70 70 intptr_t min( intptr_t t1, intptr_t t2 ) { return t1 < t2 ? t1 : t2; } // optimization 71 71 uintptr_t min( uintptr_t t1, uintptr_t t2 ) { return t1 < t2 ? t1 : t2; } // optimization 72 forall( otypeT | { int ?<?( T, T ); } )72 forall( T | { int ?<?( T, T ); } ) 73 73 T min( T t1, T t2 ) { return t1 < t2 ? t1 : t2; } 74 74 … … 76 76 intptr_t max( intptr_t t1, intptr_t t2 ) { return t1 > t2 ? t1 : t2; } // optimization 77 77 uintptr_t max( uintptr_t t1, uintptr_t t2 ) { return t1 > t2 ? t1 : t2; } // optimization 78 forall( otypeT | { int ?>?( T, T ); } )78 forall( T | { int ?>?( T, T ); } ) 79 79 T max( T t1, T t2 ) { return t1 > t2 ? t1 : t2; } 80 80 81 forall( otypeT | { T min( T, T ); T max( T, T ); } )81 forall( T | { T min( T, T ); T max( T, T ); } ) 82 82 T clamp( T value, T min_val, T max_val ) { return max( min_val, min( value, max_val ) ); } 83 83 84 forall( otypeT )84 forall( T ) 85 85 void swap( T & v1, T & v2 ) { T temp = v1; v1 = v2; v2 = temp; } 86 86 } // distribution -
libcfa/src/concurrency/coroutine.cfa
r467c8b7 rc08c3cf 46 46 47 47 //----------------------------------------------------------------------------- 48 FORALL_DATA_INSTANCE(CoroutineCancelled, ( dtype coroutine_t), (coroutine_t))49 50 forall( dtype T)48 FORALL_DATA_INSTANCE(CoroutineCancelled, (coroutine_t &), (coroutine_t)) 49 50 forall(T &) 51 51 void mark_exception(CoroutineCancelled(T) *) {} 52 52 53 forall( dtype T)53 forall(T &) 54 54 void copy(CoroutineCancelled(T) * dst, CoroutineCancelled(T) * src) { 55 55 dst->virtual_table = src->virtual_table; … … 58 58 } 59 59 60 forall( dtype T)60 forall(T &) 61 61 const char * msg(CoroutineCancelled(T) *) { 62 62 return "CoroutineCancelled(...)"; … … 64 64 65 65 // This code should not be inlined. It is the error path on resume. 66 forall( dtype T| is_coroutine(T))66 forall(T & | is_coroutine(T)) 67 67 void __cfaehm_cancelled_coroutine( T & cor, $coroutine * desc ) { 68 68 verify( desc->cancellation ); … … 148 148 // Part of the Public API 149 149 // Not inline since only ever called once per coroutine 150 forall( dtype T| is_coroutine(T))150 forall(T & | is_coroutine(T)) 151 151 void prime(T& cor) { 152 152 $coroutine* this = get_coroutine(cor); -
libcfa/src/concurrency/coroutine.hfa
r467c8b7 rc08c3cf 22 22 //----------------------------------------------------------------------------- 23 23 // Exception thrown from resume when a coroutine stack is cancelled. 24 FORALL_DATA_EXCEPTION(CoroutineCancelled, ( dtype coroutine_t), (coroutine_t)) (24 FORALL_DATA_EXCEPTION(CoroutineCancelled, (coroutine_t &), (coroutine_t)) ( 25 25 coroutine_t * the_coroutine; 26 26 exception_t * the_exception; 27 27 ); 28 28 29 forall( dtype T)29 forall(T &) 30 30 void copy(CoroutineCancelled(T) * dst, CoroutineCancelled(T) * src); 31 31 32 forall( dtype T)32 forall(T &) 33 33 const char * msg(CoroutineCancelled(T) *); 34 34 … … 37 37 // Anything that implements this trait can be resumed. 38 38 // Anything that is resumed is a coroutine. 39 trait is_coroutine( dtype T| IS_RESUMPTION_EXCEPTION(CoroutineCancelled, (T))) {39 trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION(CoroutineCancelled, (T))) { 40 40 void main(T & this); 41 41 $coroutine * get_coroutine(T & this); … … 60 60 //----------------------------------------------------------------------------- 61 61 // Public coroutine API 62 forall( dtype T| is_coroutine(T))62 forall(T & | is_coroutine(T)) 63 63 void prime(T & cor); 64 64 … … 72 72 void __cfactx_invoke_coroutine(void (*main)(void *), void * this); 73 73 74 forall( dtype T)74 forall(T &) 75 75 void __cfactx_start(void (*main)(T &), struct $coroutine * cor, T & this, void (*invoke)(void (*main)(void *), void *)); 76 76 … … 129 129 } 130 130 131 forall( dtype T| is_coroutine(T))131 forall(T & | is_coroutine(T)) 132 132 void __cfaehm_cancelled_coroutine( T & cor, $coroutine * desc ); 133 133 134 134 // Resume implementation inlined for performance 135 forall( dtype T| is_coroutine(T))135 forall(T & | is_coroutine(T)) 136 136 static inline T & resume(T & cor) { 137 137 // optimization : read TLS once and reuse it -
libcfa/src/concurrency/future.hfa
r467c8b7 rc08c3cf 19 19 #include "monitor.hfa" 20 20 21 forall( otypeT ) {21 forall( T ) { 22 22 struct future { 23 23 inline future_t; … … 58 58 } 59 59 60 forall( otypeT ) {60 forall( T ) { 61 61 monitor multi_future { 62 62 inline future_t; -
libcfa/src/concurrency/io/types.hfa
r467c8b7 rc08c3cf 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // io/types.hfa -- 7 // io/types.hfa -- PRIVATE 8 // Types used by the I/O subsystem 8 9 // 9 10 // Author : Thierry Delisle … … 21 22 22 23 #include "bits/locks.hfa" 24 #include "kernel/fwd.hfa" 23 25 24 26 #if defined(CFA_HAVE_LINUX_IO_URING_H) -
libcfa/src/concurrency/kernel.cfa
r467c8b7 rc08c3cf 224 224 } 225 225 226 V( this->terminated );226 post( this->terminated ); 227 227 228 228 if(this == mainProcessor) { … … 624 624 // Unexpected Terminating logic 625 625 //============================================================================================= 626 627 extern "C" { 628 extern void __cfaabi_real_abort(void); 629 } 630 static volatile bool kernel_abort_called = false; 631 632 void * kernel_abort(void) __attribute__ ((__nothrow__)) { 633 // abort cannot be recursively entered by the same or different processors because all signal handlers return when 634 // the globalAbort flag is true. 635 bool first = !__atomic_test_and_set( &kernel_abort_called, __ATOMIC_SEQ_CST); 636 637 // first task to abort ? 638 if ( !first ) { 639 // We aren't the first to abort. 640 // I give up, just let C handle it 641 __cfaabi_real_abort(); 642 } 643 644 // disable interrupts, it no longer makes sense to try to interrupt this processor 645 disable_interrupts(); 646 647 return __cfaabi_tls.this_thread; 648 } 649 650 void kernel_abort_msg( void * kernel_data, char * abort_text, int abort_text_size ) { 651 $thread * thrd = ( $thread * ) kernel_data; 626 void __kernel_abort_msg( char * abort_text, int abort_text_size ) { 627 $thread * thrd = __cfaabi_tls.this_thread; 652 628 653 629 if(thrd) { … … 669 645 } 670 646 671 int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {672 return get_coroutine( kernelTLS().this_thread) == get_coroutine(mainThread) ? 4 : 2;647 int __kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) { 648 return get_coroutine(__cfaabi_tls.this_thread) == get_coroutine(mainThread) ? 4 : 2; 673 649 } 674 650 … … 688 664 // Kernel Utilities 689 665 //============================================================================================= 690 //-----------------------------------------------------------------------------691 // Locks692 void ?{}( semaphore & this, int count = 1 ) {693 (this.lock){};694 this.count = count;695 (this.waiting){};696 }697 void ^?{}(semaphore & this) {}698 699 bool P(semaphore & this) with( this ){700 lock( lock __cfaabi_dbg_ctx2 );701 count -= 1;702 if ( count < 0 ) {703 // queue current task704 append( waiting, active_thread() );705 706 // atomically release spin lock and block707 unlock( lock );708 park();709 return true;710 }711 else {712 unlock( lock );713 return false;714 }715 }716 717 bool V(semaphore & this) with( this ) {718 $thread * thrd = 0p;719 lock( lock __cfaabi_dbg_ctx2 );720 count += 1;721 if ( count <= 0 ) {722 // remove task at head of waiting list723 thrd = pop_head( waiting );724 }725 726 unlock( lock );727 728 // make new owner729 unpark( thrd );730 731 return thrd != 0p;732 }733 734 bool V(semaphore & this, unsigned diff) with( this ) {735 $thread * thrd = 0p;736 lock( lock __cfaabi_dbg_ctx2 );737 int release = max(-count, (int)diff);738 count += diff;739 for(release) {740 unpark( pop_head( waiting ) );741 }742 743 unlock( lock );744 745 return thrd != 0p;746 }747 748 666 //----------------------------------------------------------------------------- 749 667 // Debug -
libcfa/src/concurrency/kernel.hfa
r467c8b7 rc08c3cf 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // kernel -- 7 // kernel -- Header containing the core of the kernel API 8 8 // 9 9 // Author : Thierry Delisle … … 24 24 extern "C" { 25 25 #include <bits/pthreadtypes.h> 26 #include <pthread.h> 26 27 #include <linux/types.h> 27 28 } 28 29 29 30 //----------------------------------------------------------------------------- 30 // Locks 31 struct semaphore { 32 __spinlock_t lock; 33 int count; 34 __queue_t($thread) waiting; 35 }; 36 37 void ?{}(semaphore & this, int count = 1); 38 void ^?{}(semaphore & this); 39 bool P (semaphore & this); 40 bool V (semaphore & this); 41 bool V (semaphore & this, unsigned count); 31 // Underlying Locks 32 #ifdef __CFA_WITH_VERIFY__ 33 extern bool __cfaabi_dbg_in_kernel(); 34 #endif 35 36 extern "C" { 37 char * strerror(int); 38 } 39 #define CHECKED(x) { int err = x; if( err != 0 ) abort("KERNEL ERROR: Operation \"" #x "\" return error %d - %s\n", err, strerror(err)); } 40 41 struct __bin_sem_t { 42 pthread_mutex_t lock; 43 pthread_cond_t cond; 44 int val; 45 }; 46 47 static inline void ?{}(__bin_sem_t & this) with( this ) { 48 // Create the mutex with error checking 49 pthread_mutexattr_t mattr; 50 pthread_mutexattr_init( &mattr ); 51 pthread_mutexattr_settype( &mattr, PTHREAD_MUTEX_ERRORCHECK_NP); 52 pthread_mutex_init(&lock, &mattr); 53 54 pthread_cond_init (&cond, (const pthread_condattr_t *)0p); // workaround trac#208: cast should not be required 55 val = 0; 56 } 57 58 static inline void ^?{}(__bin_sem_t & this) with( this ) { 59 CHECKED( pthread_mutex_destroy(&lock) ); 60 CHECKED( pthread_cond_destroy (&cond) ); 61 } 62 63 static inline void wait(__bin_sem_t & this) with( this ) { 64 verify(__cfaabi_dbg_in_kernel()); 65 CHECKED( pthread_mutex_lock(&lock) ); 66 while(val < 1) { 67 pthread_cond_wait(&cond, &lock); 68 } 69 val -= 1; 70 CHECKED( pthread_mutex_unlock(&lock) ); 71 } 72 73 static inline bool post(__bin_sem_t & this) with( this ) { 74 bool needs_signal = false; 75 76 CHECKED( pthread_mutex_lock(&lock) ); 77 if(val < 1) { 78 val += 1; 79 pthread_cond_signal(&cond); 80 needs_signal = true; 81 } 82 CHECKED( pthread_mutex_unlock(&lock) ); 83 84 return needs_signal; 85 } 86 87 #undef CHECKED 42 88 43 89 … … 91 137 92 138 // Termination synchronisation (user semaphore) 93 semaphoreterminated;139 oneshot terminated; 94 140 95 141 // pthread Stack -
libcfa/src/concurrency/kernel/fwd.hfa
r467c8b7 rc08c3cf 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // kernel/fwd.hfa -- 7 // kernel/fwd.hfa -- PUBLIC 8 // Fundamental code needed to implement threading M.E.S. algorithms. 8 9 // 9 10 // Author : Thierry Delisle … … 134 135 extern uint64_t thread_rand(); 135 136 137 // Semaphore which only supports a single thread 138 struct single_sem { 139 struct $thread * volatile ptr; 140 }; 141 142 static inline { 143 void ?{}(single_sem & this) { 144 this.ptr = 0p; 145 } 146 147 void ^?{}(single_sem &) {} 148 149 bool wait(single_sem & this) { 150 for() { 151 struct $thread * expected = this.ptr; 152 if(expected == 1p) { 153 if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 154 return false; 155 } 156 } 157 else { 158 /* paranoid */ verify( expected == 0p ); 159 if(__atomic_compare_exchange_n(&this.ptr, &expected, active_thread(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 160 park(); 161 return true; 162 } 163 } 164 165 } 166 } 167 168 bool post(single_sem & this) { 169 for() { 170 struct $thread * expected = this.ptr; 171 if(expected == 1p) return false; 172 if(expected == 0p) { 173 if(__atomic_compare_exchange_n(&this.ptr, &expected, 1p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 174 return false; 175 } 176 } 177 else { 178 if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 179 unpark( expected ); 180 return true; 181 } 182 } 183 } 184 } 185 } 186 187 // Synchronozation primitive which only supports a single thread and one post 188 // Similar to a binary semaphore with a 'one shot' semantic 189 // is expected to be discarded after each party call their side 190 struct oneshot { 191 // Internal state : 192 // 0p : is initial state (wait will block) 193 // 1p : fulfilled (wait won't block) 194 // any thread : a thread is currently waiting 195 struct $thread * volatile ptr; 196 }; 197 198 static inline { 199 void ?{}(oneshot & this) { 200 this.ptr = 0p; 201 } 202 203 void ^?{}(oneshot &) {} 204 205 // Wait for the post, return immidiately if it already happened. 206 // return true if the thread was parked 207 bool wait(oneshot & this) { 208 for() { 209 struct $thread * expected = this.ptr; 210 if(expected == 1p) return false; 211 /* paranoid */ verify( expected == 0p ); 212 if(__atomic_compare_exchange_n(&this.ptr, &expected, active_thread(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 213 park(); 214 /* paranoid */ verify( this.ptr == 1p ); 215 return true; 216 } 217 } 218 } 219 220 // Mark as fulfilled, wake thread if needed 221 // return true if a thread was unparked 222 bool post(oneshot & this) { 223 struct $thread * got = __atomic_exchange_n( &this.ptr, 1p, __ATOMIC_SEQ_CST); 224 if( got == 0p ) return false; 225 unpark( got ); 226 return true; 227 } 228 } 229 230 // base types for future to build upon 231 // It is based on the 'oneshot' type to allow multiple futures 232 // to block on the same instance, permitting users to block a single 233 // thread on "any of" [a given set of] futures. 234 // does not support multiple threads waiting on the same future 235 struct future_t { 236 // Internal state : 237 // 0p : is initial state (wait will block) 238 // 1p : fulfilled (wait won't block) 239 // 2p : in progress () 240 // 3p : abandoned, server should delete 241 // any oneshot : a context has been setup to wait, a thread could wait on it 242 struct oneshot * volatile ptr; 243 }; 244 245 static inline { 246 void ?{}(future_t & this) { 247 this.ptr = 0p; 248 } 249 250 void ^?{}(future_t &) {} 251 252 void reset(future_t & this) { 253 // needs to be in 0p or 1p 254 __atomic_exchange_n( &this.ptr, 0p, __ATOMIC_SEQ_CST); 255 } 256 257 // check if the future is available 258 bool available( future_t & this ) { 259 return this.ptr == 1p; 260 } 261 262 // Prepare the future to be waited on 263 // intented to be use by wait, wait_any, waitfor, etc. rather than used directly 264 bool setup( future_t & this, oneshot & wait_ctx ) { 265 /* paranoid */ verify( wait_ctx.ptr == 0p ); 266 // The future needs to set the wait context 267 for() { 268 struct oneshot * expected = this.ptr; 269 // Is the future already fulfilled? 270 if(expected == 1p) return false; // Yes, just return false (didn't block) 271 272 // The future is not fulfilled, try to setup the wait context 273 /* paranoid */ verify( expected == 0p ); 274 if(__atomic_compare_exchange_n(&this.ptr, &expected, &wait_ctx, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 275 return true; 276 } 277 } 278 } 279 280 // Stop waiting on a future 281 // When multiple futures are waited for together in "any of" pattern 282 // futures that weren't fulfilled before the thread woke up 283 // should retract the wait ctx 284 // intented to be use by wait, wait_any, waitfor, etc. rather than used directly 285 void retract( future_t & this, oneshot & wait_ctx ) { 286 // Remove the wait context 287 struct oneshot * got = __atomic_exchange_n( &this.ptr, 0p, __ATOMIC_SEQ_CST); 288 289 // got == 0p: future was never actually setup, just return 290 if( got == 0p ) return; 291 292 // got == wait_ctx: since fulfil does an atomic_swap, 293 // if we got back the original then no one else saw context 294 // It is safe to delete (which could happen after the return) 295 if( got == &wait_ctx ) return; 296 297 // got == 1p: the future is ready and the context was fully consumed 298 // the server won't use the pointer again 299 // It is safe to delete (which could happen after the return) 300 if( got == 1p ) return; 301 302 // got == 2p: the future is ready but the context hasn't fully been consumed 303 // spin until it is safe to move on 304 if( got == 2p ) { 305 while( this.ptr != 1p ) Pause(); 306 return; 307 } 308 309 // got == any thing else, something wen't wrong here, abort 310 abort("Future in unexpected state"); 311 } 312 313 // Mark the future as abandoned, meaning it will be deleted by the server 314 bool abandon( future_t & this ) { 315 /* paranoid */ verify( this.ptr != 3p ); 316 317 // Mark the future as abandonned 318 struct oneshot * got = __atomic_exchange_n( &this.ptr, 3p, __ATOMIC_SEQ_CST); 319 320 // If the future isn't already fulfilled, let the server delete it 321 if( got == 0p ) return false; 322 323 // got == 2p: the future is ready but the context hasn't fully been consumed 324 // spin until it is safe to move on 325 if( got == 2p ) { 326 while( this.ptr != 1p ) Pause(); 327 got = 1p; 328 } 329 330 // The future is completed delete it now 331 /* paranoid */ verify( this.ptr != 1p ); 332 free( &this ); 333 return true; 334 } 335 336 // from the server side, mark the future as fulfilled 337 // delete it if needed 338 bool fulfil( future_t & this ) { 339 for() { 340 struct oneshot * expected = this.ptr; 341 // was this abandoned? 342 #if defined(__GNUC__) && __GNUC__ >= 7 343 #pragma GCC diagnostic push 344 #pragma GCC diagnostic ignored "-Wfree-nonheap-object" 345 #endif 346 if( expected == 3p ) { free( &this ); return false; } 347 #if defined(__GNUC__) && __GNUC__ >= 7 348 #pragma GCC diagnostic pop 349 #endif 350 351 /* paranoid */ verify( expected != 1p ); // Future is already fulfilled, should not happen 352 /* paranoid */ verify( expected != 2p ); // Future is bein fulfilled by someone else, this is even less supported then the previous case. 353 354 // If there is a wait context, we need to consume it and mark it as consumed after 355 // If there is no context then we can skip the in progress phase 356 struct oneshot * want = expected == 0p ? 1p : 2p; 357 if(__atomic_compare_exchange_n(&this.ptr, &expected, want, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 358 if( expected == 0p ) { /* paranoid */ verify( this.ptr == 1p); return false; } 359 bool ret = post( *expected ); 360 __atomic_store_n( &this.ptr, 1p, __ATOMIC_SEQ_CST); 361 return ret; 362 } 363 } 364 365 } 366 367 // Wait for the future to be fulfilled 368 bool wait( future_t & this ) { 369 oneshot temp; 370 if( !setup(this, temp) ) return false; 371 372 // Wait context is setup, just wait on it 373 bool ret = wait( temp ); 374 375 // Wait for the future to tru 376 while( this.ptr == 2p ) Pause(); 377 // Make sure the state makes sense 378 // Should be fulfilled, could be in progress but it's out of date if so 379 // since if that is the case, the oneshot was fulfilled (unparking this thread) 380 // and the oneshot should not be needed any more 381 __attribute__((unused)) struct oneshot * was = this.ptr; 382 /* paranoid */ verifyf( was == 1p, "Expected this.ptr to be 1p, was %p\n", was ); 383 384 // Mark the future as fulfilled, to be consistent 385 // with potential calls to avail 386 // this.ptr = 1p; 387 return ret; 388 } 389 } 390 136 391 //----------------------------------------------------------------------- 137 392 // Statics call at the end of each thread to register statistics -
libcfa/src/concurrency/kernel/startup.cfa
r467c8b7 rc08c3cf 199 199 void ?{}(processor & this) with( this ) { 200 200 ( this.idle ){}; 201 ( this.terminated ){ 0};201 ( this.terminated ){}; 202 202 ( this.runner ){}; 203 203 init( this, "Main Processor", *mainCluster ); … … 528 528 void ?{}(processor & this, const char name[], cluster & _cltr) { 529 529 ( this.idle ){}; 530 ( this.terminated ){ 0};530 ( this.terminated ){}; 531 531 ( this.runner ){}; 532 532 … … 549 549 __wake_proc( &this ); 550 550 551 P( terminated );551 wait( terminated ); 552 552 /* paranoid */ verify( active_processor() != &this); 553 553 } -
libcfa/src/concurrency/locks.cfa
r467c8b7 rc08c3cf 7 7 //----------------------------------------------------------------------------- 8 8 // info_thread 9 forall( dtype L| is_blocking_lock(L)) {9 forall(L & | is_blocking_lock(L)) { 10 10 struct info_thread { 11 11 // used to put info_thread on a dl queue (aka sequence) … … 195 195 //----------------------------------------------------------------------------- 196 196 // alarm node wrapper 197 forall( dtype L| is_blocking_lock(L)) {197 forall(L & | is_blocking_lock(L)) { 198 198 struct alarm_node_wrap { 199 199 alarm_node_t alarm_node; … … 239 239 //----------------------------------------------------------------------------- 240 240 // condition variable 241 forall( dtype L| is_blocking_lock(L)) {241 forall(L & | is_blocking_lock(L)) { 242 242 243 243 void ?{}( condition_variable(L) & this ){ … … 356 356 bool wait( condition_variable(L) & this, L & l, uintptr_t info, Time time ) with(this) { WAIT_TIME( info, &l , time ) } 357 357 } 358 359 //----------------------------------------------------------------------------- 360 // Semaphore 361 void ?{}( semaphore & this, int count = 1 ) { 362 (this.lock){}; 363 this.count = count; 364 (this.waiting){}; 365 } 366 void ^?{}(semaphore & this) {} 367 368 bool P(semaphore & this) with( this ){ 369 lock( lock __cfaabi_dbg_ctx2 ); 370 count -= 1; 371 if ( count < 0 ) { 372 // queue current task 373 append( waiting, active_thread() ); 374 375 // atomically release spin lock and block 376 unlock( lock ); 377 park(); 378 return true; 379 } 380 else { 381 unlock( lock ); 382 return false; 383 } 384 } 385 386 bool V(semaphore & this) with( this ) { 387 $thread * thrd = 0p; 388 lock( lock __cfaabi_dbg_ctx2 ); 389 count += 1; 390 if ( count <= 0 ) { 391 // remove task at head of waiting list 392 thrd = pop_head( waiting ); 393 } 394 395 unlock( lock ); 396 397 // make new owner 398 unpark( thrd ); 399 400 return thrd != 0p; 401 } 402 403 bool V(semaphore & this, unsigned diff) with( this ) { 404 $thread * thrd = 0p; 405 lock( lock __cfaabi_dbg_ctx2 ); 406 int release = max(-count, (int)diff); 407 count += diff; 408 for(release) { 409 unpark( pop_head( waiting ) ); 410 } 411 412 unlock( lock ); 413 414 return thrd != 0p; 415 } -
libcfa/src/concurrency/locks.hfa
r467c8b7 rc08c3cf 13 13 //----------------------------------------------------------------------------- 14 14 // is_blocking_lock 15 trait is_blocking_lock( dtype L| sized(L)) {15 trait is_blocking_lock(L & | sized(L)) { 16 16 // For synchronization locks to use when acquiring 17 17 void on_notify( L &, struct $thread * ); … … 31 31 // the info thread is a wrapper around a thread used 32 32 // to store extra data for use in the condition variable 33 forall( dtype L| is_blocking_lock(L)) {33 forall(L & | is_blocking_lock(L)) { 34 34 struct info_thread; 35 35 … … 120 120 //----------------------------------------------------------------------------- 121 121 // Synchronization Locks 122 forall( dtype L| is_blocking_lock(L)) {122 forall(L & | is_blocking_lock(L)) { 123 123 struct condition_variable { 124 124 // Spin lock used for mutual exclusion … … 157 157 bool wait( condition_variable(L) & this, L & l, uintptr_t info, Time time ); 158 158 } 159 160 //----------------------------------------------------------------------------- 161 // Semaphore 162 struct semaphore { 163 __spinlock_t lock; 164 int count; 165 __queue_t($thread) waiting; 166 }; 167 168 void ?{}(semaphore & this, int count = 1); 169 void ^?{}(semaphore & this); 170 bool P (semaphore & this); 171 bool V (semaphore & this); 172 bool V (semaphore & this, unsigned count); -
libcfa/src/concurrency/monitor.cfa
r467c8b7 rc08c3cf 50 50 static inline [$thread *, int] search_entry_queue( const __waitfor_mask_t &, $monitor * monitors [], __lock_size_t count ); 51 51 52 forall( dtype T| sized( T ))52 forall(T & | sized( T )) 53 53 static inline __lock_size_t insert_unique( T * array [], __lock_size_t & size, T * val ); 54 54 static inline __lock_size_t count_max ( const __waitfor_mask_t & mask ); … … 949 949 } 950 950 951 forall( dtype T| sized( T ))951 forall(T & | sized( T )) 952 952 static inline __lock_size_t insert_unique( T * array [], __lock_size_t & size, T * val ) { 953 953 if( !val ) return size; -
libcfa/src/concurrency/monitor.hfa
r467c8b7 rc08c3cf 22 22 #include "stdlib.hfa" 23 23 24 trait is_monitor( dtype T) {24 trait is_monitor(T &) { 25 25 $monitor * get_monitor( T & ); 26 26 void ^?{}( T & mutex ); … … 59 59 void ^?{}( monitor_dtor_guard_t & this ); 60 60 61 static inline forall( dtype T| sized(T) | { void ^?{}( T & mutex ); } )61 static inline forall( T & | sized(T) | { void ^?{}( T & mutex ); } ) 62 62 void delete( T * th ) { 63 63 ^(*th){}; -
libcfa/src/concurrency/mutex.cfa
r467c8b7 rc08c3cf 164 164 } 165 165 166 forall( dtype L| is_lock(L))166 forall(L & | is_lock(L)) 167 167 void wait(condition_variable & this, L & l) { 168 168 lock( this.lock __cfaabi_dbg_ctx2 ); … … 176 176 //----------------------------------------------------------------------------- 177 177 // Scopes 178 forall( dtype L| is_lock(L))178 forall(L & | is_lock(L)) 179 179 void lock_all ( L * locks[], size_t count) { 180 180 // Sort locks based on addresses … … 188 188 } 189 189 190 forall( dtype L| is_lock(L))190 forall(L & | is_lock(L)) 191 191 void unlock_all( L * locks[], size_t count) { 192 192 // Lock all -
libcfa/src/concurrency/mutex.hfa
r467c8b7 rc08c3cf 70 70 void unlock(recursive_mutex_lock & this) __attribute__((deprecated("use concurrency/locks.hfa instead"))); 71 71 72 trait is_lock( dtype L| sized(L)) {72 trait is_lock(L & | sized(L)) { 73 73 void lock (L &); 74 74 void unlock(L &); … … 94 94 void wait(condition_variable & this) __attribute__((deprecated("use concurrency/locks.hfa instead"))); 95 95 96 forall( dtype L| is_lock(L))96 forall(L & | is_lock(L)) 97 97 void wait(condition_variable & this, L & l) __attribute__((deprecated("use concurrency/locks.hfa instead"))); 98 98 99 99 //----------------------------------------------------------------------------- 100 100 // Scopes 101 forall( dtype L| is_lock(L)) {101 forall(L & | is_lock(L)) { 102 102 #if !defined( __TUPLE_ARRAYS_EXIST__ ) 103 103 void lock ( L * locks [], size_t count); -
libcfa/src/concurrency/preemption.cfa
r467c8b7 rc08c3cf 616 616 } 617 617 618 // Prevent preemption since we are about to start terminating things 619 void __kernel_abort_lock(void) { 620 signal_block( SIGUSR1 ); 621 } 622 618 623 // Raii ctor/dtor for the preemption_scope 619 624 // Used by thread to control when they want to receive preemption signals -
libcfa/src/concurrency/thread.cfa
r467c8b7 rc08c3cf 62 62 } 63 63 64 FORALL_DATA_INSTANCE(ThreadCancelled, ( dtype thread_t), (thread_t))64 FORALL_DATA_INSTANCE(ThreadCancelled, (thread_t &), (thread_t)) 65 65 66 forall( dtype T)66 forall(T &) 67 67 void copy(ThreadCancelled(T) * dst, ThreadCancelled(T) * src) { 68 68 dst->virtual_table = src->virtual_table; … … 71 71 } 72 72 73 forall( dtype T)73 forall(T &) 74 74 const char * msg(ThreadCancelled(T) *) { 75 75 return "ThreadCancelled"; 76 76 } 77 77 78 forall( dtype T)78 forall(T &) 79 79 static void default_thread_cancel_handler(ThreadCancelled(T) & ) { 80 80 abort( "Unhandled thread cancellation.\n" ); 81 81 } 82 82 83 forall( dtype T| is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T)))83 forall(T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T))) 84 84 void ?{}( thread_dtor_guard_t & this, 85 85 T & thrd, void(*cancelHandler)(ThreadCancelled(T) &)) { … … 124 124 //----------------------------------------------------------------------------- 125 125 // Starting and stopping threads 126 forall( dtype T| is_thread(T) )126 forall( T & | is_thread(T) ) 127 127 void __thrd_start( T & this, void (*main_p)(T &) ) { 128 128 $thread * this_thrd = get_thread(this); … … 140 140 //----------------------------------------------------------------------------- 141 141 // Support for threads that don't ues the thread keyword 142 forall( dtype T| sized(T) | is_thread(T) | { void ?{}(T&); } )142 forall( T & | sized(T) | is_thread(T) | { void ?{}(T&); } ) 143 143 void ?{}( scoped(T)& this ) with( this ) { 144 144 handle{}; … … 146 146 } 147 147 148 forall( dtype T, ttype P| sized(T) | is_thread(T) | { void ?{}(T&, P); } )148 forall( T &, P... | sized(T) | is_thread(T) | { void ?{}(T&, P); } ) 149 149 void ?{}( scoped(T)& this, P params ) with( this ) { 150 150 handle{ params }; … … 152 152 } 153 153 154 forall( dtype T| sized(T) | is_thread(T) )154 forall( T & | sized(T) | is_thread(T) ) 155 155 void ^?{}( scoped(T)& this ) with( this ) { 156 156 ^handle{}; … … 158 158 159 159 //----------------------------------------------------------------------------- 160 forall( dtype T| is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T)))160 forall(T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T))) 161 161 T & join( T & this ) { 162 162 thread_dtor_guard_t guard = { this, defaultResumptionHandler }; -
libcfa/src/concurrency/thread.hfa
r467c8b7 rc08c3cf 26 26 //----------------------------------------------------------------------------- 27 27 // thread trait 28 trait is_thread( dtype T) {28 trait is_thread(T &) { 29 29 void ^?{}(T& mutex this); 30 30 void main(T& this); … … 32 32 }; 33 33 34 FORALL_DATA_EXCEPTION(ThreadCancelled, ( dtype thread_t), (thread_t)) (34 FORALL_DATA_EXCEPTION(ThreadCancelled, (thread_t &), (thread_t)) ( 35 35 thread_t * the_thread; 36 36 exception_t * the_exception; 37 37 ); 38 38 39 forall( dtype T)39 forall(T &) 40 40 void copy(ThreadCancelled(T) * dst, ThreadCancelled(T) * src); 41 41 42 forall( dtype T)42 forall(T &) 43 43 const char * msg(ThreadCancelled(T) *); 44 44 … … 47 47 48 48 // Inline getters for threads/coroutines/monitors 49 forall( dtype T| is_thread(T) )49 forall( T & | is_thread(T) ) 50 50 static inline $coroutine* get_coroutine(T & this) __attribute__((const)) { return &get_thread(this)->self_cor; } 51 51 52 forall( dtype T| is_thread(T) )52 forall( T & | is_thread(T) ) 53 53 static inline $monitor * get_monitor (T & this) __attribute__((const)) { return &get_thread(this)->self_mon; } 54 54 … … 60 60 extern struct cluster * mainCluster; 61 61 62 forall( dtype T| is_thread(T) )62 forall( T & | is_thread(T) ) 63 63 void __thrd_start( T & this, void (*)(T &) ); 64 64 … … 82 82 }; 83 83 84 forall( dtype T| is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T)) )84 forall( T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T)) ) 85 85 void ?{}( thread_dtor_guard_t & this, T & thrd, void(*)(ThreadCancelled(T) &) ); 86 86 void ^?{}( thread_dtor_guard_t & this ); … … 89 89 // thread runner 90 90 // Structure that actually start and stop threads 91 forall( dtype T| sized(T) | is_thread(T) )91 forall( T & | sized(T) | is_thread(T) ) 92 92 struct scoped { 93 93 T handle; 94 94 }; 95 95 96 forall( dtype T| sized(T) | is_thread(T) | { void ?{}(T&); } )96 forall( T & | sized(T) | is_thread(T) | { void ?{}(T&); } ) 97 97 void ?{}( scoped(T)& this ); 98 98 99 forall( dtype T, ttype P| sized(T) | is_thread(T) | { void ?{}(T&, P); } )99 forall( T &, P... | sized(T) | is_thread(T) | { void ?{}(T&, P); } ) 100 100 void ?{}( scoped(T)& this, P params ); 101 101 102 forall( dtype T| sized(T) | is_thread(T) )102 forall( T & | sized(T) | is_thread(T) ) 103 103 void ^?{}( scoped(T)& this ); 104 104 … … 115 115 void unpark( $thread * this ); 116 116 117 forall( dtype T| is_thread(T) )117 forall( T & | is_thread(T) ) 118 118 static inline void unpark( T & this ) { if(!&this) return; unpark( get_thread( this ) );} 119 119 … … 128 128 //---------- 129 129 // join 130 forall( dtype T| is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T)) )130 forall( T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T)) ) 131 131 T & join( T & this ); 132 132 -
libcfa/src/containers/list.hfa
r467c8b7 rc08c3cf 66 66 #define __DLISTED_MGD_JUSTIMPL(STRUCT) 67 67 68 forall( dtype tE) {68 forall( tE & ) { 69 69 struct $mgd_link { 70 70 tE *elem; … … 83 83 (this.is_terminator){ 1 }; 84 84 } 85 forall ( otypetInit | { void ?{}( $mgd_link(tE) &, tInit); } )85 forall ( tInit | { void ?{}( $mgd_link(tE) &, tInit); } ) 86 86 static inline void ?=?( $mgd_link(tE) &this, tInit i ) { 87 87 ^?{}( this ); … … 115 115 __DLISTED_MGD_COMMON(STRUCT, STRUCT, $links) 116 116 117 trait $dlistable( dtype Tnode, dtype Telem) {117 trait $dlistable(Tnode &, Telem &) { 118 118 $mgd_link(Telem) & $prev_link(Tnode &); 119 119 $mgd_link(Telem) & $next_link(Tnode &); … … 125 125 }; 126 126 127 forall ( dtype Tnode, dtype Telem| $dlistable(Tnode, Telem)) {127 forall (Tnode &, Telem & | $dlistable(Tnode, Telem)) { 128 128 129 129 // implemented as a sentinel item in an underlying cicrular list -
libcfa/src/containers/maybe.cfa
r467c8b7 rc08c3cf 18 18 19 19 20 forall( otypeT)20 forall(T) 21 21 void ?{}(maybe(T) & this) { 22 22 this.has_value = false; 23 23 } 24 24 25 forall( otypeT)25 forall(T) 26 26 void ?{}(maybe(T) & this, T value) { 27 27 this.has_value = true; … … 29 29 } 30 30 31 forall( otypeT)31 forall(T) 32 32 void ?{}(maybe(T) & this, maybe(T) other) { 33 33 this.has_value = other.has_value; … … 37 37 } 38 38 39 forall( otypeT)39 forall(T) 40 40 maybe(T) ?=?(maybe(T) & this, maybe(T) that) { 41 41 if (this.has_value && that.has_value) { … … 51 51 } 52 52 53 forall( otypeT)53 forall(T) 54 54 void ^?{}(maybe(T) & this) { 55 55 if (this.has_value) { … … 58 58 } 59 59 60 forall( otypeT)60 forall(T) 61 61 bool ?!=?(maybe(T) this, zero_t) { 62 62 return this.has_value; 63 63 } 64 64 65 forall( otypeT)65 forall(T) 66 66 maybe(T) maybe_value(T value) { 67 67 return (maybe(T)){value}; 68 68 } 69 69 70 forall( otypeT)70 forall(T) 71 71 maybe(T) maybe_none() { 72 72 return (maybe(T)){}; 73 73 } 74 74 75 forall( otypeT)75 forall(T) 76 76 bool has_value(maybe(T) * this) { 77 77 return this->has_value; 78 78 } 79 79 80 forall( otypeT)80 forall(T) 81 81 T get(maybe(T) * this) { 82 82 assertf(this->has_value, "attempt to get from maybe without value"); … … 84 84 } 85 85 86 forall( otypeT)86 forall(T) 87 87 void set(maybe(T) * this, T value) { 88 88 if (this->has_value) { … … 94 94 } 95 95 96 forall( otypeT)96 forall(T) 97 97 void set_none(maybe(T) * this) { 98 98 if (this->has_value) { -
libcfa/src/containers/maybe.hfa
r467c8b7 rc08c3cf 19 19 20 20 // DO NOT USE DIRECTLY! 21 forall( otypeT)21 forall(T) 22 22 struct maybe { 23 23 bool has_value; … … 26 26 27 27 28 forall( otypeT)28 forall(T) 29 29 void ?{}(maybe(T) & this); 30 30 31 forall( otypeT)31 forall(T) 32 32 void ?{}(maybe(T) & this, T value); 33 33 34 forall( otypeT)34 forall(T) 35 35 void ?{}(maybe(T) & this, maybe(T) other); 36 36 37 forall( otypeT)37 forall(T) 38 38 void ^?{}(maybe(T) & this); 39 39 40 forall( otypeT)40 forall(T) 41 41 maybe(T) ?=?(maybe(T) & this, maybe(T) other); 42 42 43 forall( otypeT)43 forall(T) 44 44 bool ?!=?(maybe(T) this, zero_t); 45 45 46 46 /* Waiting for bug#11 to be fixed. 47 forall( otypeT)47 forall(T) 48 48 maybe(T) maybe_value(T value); 49 49 50 forall( otypeT)50 forall(T) 51 51 maybe(T) maybe_none(); 52 52 */ 53 53 54 forall( otypeT)54 forall(T) 55 55 bool has_value(maybe(T) * this); 56 56 57 forall( otypeT)57 forall(T) 58 58 T get(maybe(T) * this); 59 59 60 forall( otypeT)60 forall(T) 61 61 void set(maybe(T) * this, T value); 62 62 63 forall( otypeT)63 forall(T) 64 64 void set_none(maybe(T) * this); 65 65 -
libcfa/src/containers/pair.cfa
r467c8b7 rc08c3cf 13 13 #include <containers/pair.hfa> 14 14 15 forall( otype R, otypeS15 forall(R, S 16 16 | { int ?==?(R, R); int ?<?(R, R); int ?<?(S, S); }) 17 17 int ?<?(pair(R, S) p, pair(R, S) q) { … … 19 19 } 20 20 21 forall( otype R, otypeS21 forall(R, S 22 22 | { int ?==?(R, R); int ?<?(R, R); int ?<=?(S, S); }) 23 23 int ?<=?(pair(R, S) p, pair(R, S) q) { … … 25 25 } 26 26 27 forall( otype R, otypeS | { int ?==?(R, R); int ?==?(S, S); })27 forall(R, S | { int ?==?(R, R); int ?==?(S, S); }) 28 28 int ?==?(pair(R, S) p, pair(R, S) q) { 29 29 return p.first == q.first && p.second == q.second; 30 30 } 31 31 32 forall( otype R, otypeS | { int ?!=?(R, R); int ?!=?(S, S); })32 forall(R, S | { int ?!=?(R, R); int ?!=?(S, S); }) 33 33 int ?!=?(pair(R, S) p, pair(R, S) q) { 34 34 return p.first != q.first || p.second != q.second; 35 35 } 36 36 37 forall( otype R, otypeS37 forall(R, S 38 38 | { int ?==?(R, R); int ?>?(R, R); int ?>?(S, S); }) 39 39 int ?>?(pair(R, S) p, pair(R, S) q) { … … 41 41 } 42 42 43 forall( otype R, otypeS43 forall(R, S 44 44 | { int ?==?(R, R); int ?>?(R, R); int ?>=?(S, S); }) 45 45 int ?>=?(pair(R, S) p, pair(R, S) q) { -
libcfa/src/containers/pair.hfa
r467c8b7 rc08c3cf 16 16 #pragma once 17 17 18 forall( otype R, otypeS) struct pair {18 forall(R, S) struct pair { 19 19 R first; 20 20 S second; 21 21 }; 22 22 23 forall( otype R, otypeS23 forall(R, S 24 24 | { int ?==?(R, R); int ?<?(R, R); int ?<?(S, S); }) 25 25 int ?<?(pair(R, S) p, pair(R, S) q); 26 26 27 forall( otype R, otypeS27 forall(R, S 28 28 | { int ?==?(R, R); int ?<?(R, R); int ?<=?(S, S); }) 29 29 int ?<=?(pair(R, S) p, pair(R, S) q); 30 30 31 forall( otype R, otypeS | { int ?==?(R, R); int ?==?(S, S); })31 forall(R, S | { int ?==?(R, R); int ?==?(S, S); }) 32 32 int ?==?(pair(R, S) p, pair(R, S) q); 33 33 34 forall( otype R, otypeS | { int ?!=?(R, R); int ?!=?(S, S); })34 forall(R, S | { int ?!=?(R, R); int ?!=?(S, S); }) 35 35 int ?!=?(pair(R, S) p, pair(R, S) q); 36 36 37 forall( otype R, otypeS37 forall(R, S 38 38 | { int ?==?(R, R); int ?>?(R, R); int ?>?(S, S); }) 39 39 int ?>?(pair(R, S) p, pair(R, S) q); 40 40 41 forall( otype R, otypeS41 forall(R, S 42 42 | { int ?==?(R, R); int ?>?(R, R); int ?>=?(S, S); }) 43 43 int ?>=?(pair(R, S) p, pair(R, S) q); -
libcfa/src/containers/result.cfa
r467c8b7 rc08c3cf 18 18 19 19 20 forall( otype T, otypeE)20 forall(T, E) 21 21 void ?{}(result(T, E) & this) { 22 22 this.has_value = false; … … 24 24 } 25 25 26 forall( otype T, otypeE)26 forall(T, E) 27 27 void ?{}(result(T, E) & this, one_t, T value) { 28 28 this.has_value = true; … … 30 30 } 31 31 32 forall( otype T, otypeE)32 forall(T, E) 33 33 void ?{}(result(T, E) & this, zero_t, E error) { 34 34 this.has_value = false; … … 36 36 } 37 37 38 forall( otype T, otypeE)38 forall(T, E) 39 39 void ?{}(result(T, E) & this, result(T, E) other) { 40 40 this.has_value = other.has_value; … … 46 46 } 47 47 48 forall( otype T, otypeE)48 forall(T, E) 49 49 result(T, E) ?=?(result(T, E) & this, result(T, E) that) { 50 50 if (this.has_value && that.has_value) { … … 63 63 } 64 64 65 forall( otype T, otypeE)65 forall(T, E) 66 66 void ^?{}(result(T, E) & this) { 67 67 if (this.has_value) { … … 72 72 } 73 73 74 forall( otype T, otypeE)74 forall(T, E) 75 75 bool ?!=?(result(T, E) this, zero_t) { 76 76 return this.has_value; 77 77 } 78 78 79 forall( otype T, otypeE)79 forall(T, E) 80 80 result(T, E) result_value(T value) { 81 81 return (result(T, E)){1, value}; 82 82 } 83 83 84 forall( otype T, otypeE)84 forall(T, E) 85 85 result(T, E) result_error(E error) { 86 86 return (result(T, E)){0, error}; 87 87 } 88 88 89 forall( otype T, otypeE)89 forall(T, E) 90 90 bool has_value(result(T, E) * this) { 91 91 return this->has_value; 92 92 } 93 93 94 forall( otype T, otypeE)94 forall(T, E) 95 95 T get(result(T, E) * this) { 96 96 assertf(this->has_value, "attempt to get from result without value"); … … 98 98 } 99 99 100 forall( otype T, otypeE)100 forall(T, E) 101 101 E get_error(result(T, E) * this) { 102 102 assertf(!this->has_value, "attempt to get from result without error"); … … 104 104 } 105 105 106 forall( otype T, otypeE)106 forall(T, E) 107 107 void set(result(T, E) * this, T value) { 108 108 if (this->has_value) { … … 115 115 } 116 116 117 forall( otype T, otypeE)117 forall(T, E) 118 118 void set_error(result(T, E) * this, E error) { 119 119 if (this->has_value) { -
libcfa/src/containers/result.hfa
r467c8b7 rc08c3cf 19 19 20 20 // DO NOT USE DIRECTLY! 21 forall( otype T, otypeE)21 forall(T, E) 22 22 union inner_result{ 23 23 T value; … … 25 25 }; 26 26 27 forall( otype T, otypeE)27 forall(T, E) 28 28 struct result { 29 29 bool has_value; … … 32 32 33 33 34 forall( otype T, otypeE)34 forall(T, E) 35 35 void ?{}(result(T, E) & this); 36 36 37 forall( otype T, otypeE)37 forall(T, E) 38 38 void ?{}(result(T, E) & this, one_t, T value); 39 39 40 forall( otype T, otypeE)40 forall(T, E) 41 41 void ?{}(result(T, E) & this, zero_t, E error); 42 42 43 forall( otype T, otypeE)43 forall(T, E) 44 44 void ?{}(result(T, E) & this, result(T, E) other); 45 45 46 forall( otype T, otypeE)46 forall(T, E) 47 47 void ^?{}(result(T, E) & this); 48 48 49 forall( otype T, otypeE)49 forall(T, E) 50 50 result(T, E) ?=?(result(T, E) & this, result(T, E) other); 51 51 52 forall( otype T, otypeE)52 forall(T, E) 53 53 bool ?!=?(result(T, E) this, zero_t); 54 54 55 55 /* Wating for bug#11 to be fixed. 56 forall( otype T, otypeE)56 forall(T, E) 57 57 result(T, E) result_value(T value); 58 58 59 forall( otype T, otypeE)59 forall(T, E) 60 60 result(T, E) result_error(E error); 61 61 */ 62 62 63 forall( otype T, otypeE)63 forall(T, E) 64 64 bool has_value(result(T, E) * this); 65 65 66 forall( otype T, otypeE)66 forall(T, E) 67 67 T get(result(T, E) * this); 68 68 69 forall( otype T, otypeE)69 forall(T, E) 70 70 E get_error(result(T, E) * this); 71 71 72 forall( otype T, otypeE)72 forall(T, E) 73 73 void set(result(T, E) * this, T value); 74 74 75 forall( otype T, otypeE)75 forall(T, E) 76 76 void set_error(result(T, E) * this, E error); 77 77 -
libcfa/src/containers/stackLockFree.hfa
r467c8b7 rc08c3cf 17 17 #include <stdint.h> 18 18 19 forall( dtype T)19 forall( T & ) 20 20 union Link { 21 21 struct { // 32/64-bit x 2 … … 31 31 }; // Link 32 32 33 forall( otypeT | sized(T) | { Link(T) * ?`next( T * ); } ) {33 forall( T | sized(T) | { Link(T) * ?`next( T * ); } ) { 34 34 struct StackLF { 35 35 Link(T) stack; -
libcfa/src/containers/vector.cfa
r467c8b7 rc08c3cf 18 18 #include <stdlib.hfa> 19 19 20 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))20 forall(T, allocator_t | allocator_c(T, allocator_t)) 21 21 void copy_internal(vector(T, allocator_t)* this, vector(T, allocator_t)* other); 22 22 23 23 //------------------------------------------------------------------------------ 24 24 //Initialization 25 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))25 forall(T, allocator_t | allocator_c(T, allocator_t)) 26 26 void ?{}(vector(T, allocator_t)& this) 27 27 { … … 30 30 } 31 31 32 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))32 forall(T, allocator_t | allocator_c(T, allocator_t)) 33 33 void ?{}(vector(T, allocator_t)& this, vector(T, allocator_t) rhs) 34 34 { … … 37 37 } 38 38 39 // forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))39 // forall(T, allocator_t | allocator_c(T, allocator_t)) 40 40 // vector(T, allocator_t) ?=?(vector(T, allocator_t)* this, vector(T, allocator_t) rhs) 41 41 // { … … 45 45 // } 46 46 47 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))47 forall(T, allocator_t | allocator_c(T, allocator_t)) 48 48 void ^?{}(vector(T, allocator_t)& this) 49 49 { … … 54 54 //------------------------------------------------------------------------------ 55 55 //Modifiers 56 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))56 forall(T, allocator_t | allocator_c(T, allocator_t)) 57 57 void push_back(vector(T, allocator_t)* this, T value) 58 58 { … … 62 62 } 63 63 64 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))64 forall(T, allocator_t | allocator_c(T, allocator_t)) 65 65 void pop_back(vector(T, allocator_t)* this) 66 66 { … … 69 69 } 70 70 71 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))71 forall(T, allocator_t | allocator_c(T, allocator_t)) 72 72 void clear(vector(T, allocator_t)* this) 73 73 { … … 82 82 //Internal Helpers 83 83 84 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))84 forall(T, allocator_t | allocator_c(T, allocator_t)) 85 85 void copy_internal(vector(T, allocator_t)* this, vector(T, allocator_t)* other) 86 86 { … … 93 93 //------------------------------------------------------------------------------ 94 94 //Allocator 95 forall( otypeT)95 forall(T) 96 96 void ?{}(heap_allocator(T)& this) 97 97 { … … 100 100 } 101 101 102 forall( otypeT)102 forall(T) 103 103 void ?{}(heap_allocator(T)& this, heap_allocator(T) rhs) 104 104 { … … 107 107 } 108 108 109 forall( otypeT)109 forall(T) 110 110 heap_allocator(T) ?=?(heap_allocator(T)& this, heap_allocator(T) rhs) 111 111 { … … 115 115 } 116 116 117 forall( otypeT)117 forall(T) 118 118 void ^?{}(heap_allocator(T)& this) 119 119 { … … 121 121 } 122 122 123 forall( otypeT)123 forall(T) 124 124 inline void realloc_storage(heap_allocator(T)* this, size_t size) 125 125 { -
libcfa/src/containers/vector.hfa
r467c8b7 rc08c3cf 20 20 //------------------------------------------------------------------------------ 21 21 //Allocator 22 forall( otypeT)22 forall(T) 23 23 struct heap_allocator 24 24 { … … 27 27 }; 28 28 29 forall( otypeT)29 forall(T) 30 30 void ?{}(heap_allocator(T)& this); 31 31 32 forall( otypeT)32 forall(T) 33 33 void ?{}(heap_allocator(T)& this, heap_allocator(T) rhs); 34 34 35 forall( otypeT)35 forall(T) 36 36 heap_allocator(T) ?=?(heap_allocator(T)& this, heap_allocator(T) rhs); 37 37 38 forall( otypeT)38 forall(T) 39 39 void ^?{}(heap_allocator(T)& this); 40 40 41 forall( otypeT)41 forall(T) 42 42 void realloc_storage(heap_allocator(T)* this, size_t size); 43 43 44 forall( otypeT)44 forall(T) 45 45 static inline T* data(heap_allocator(T)* this) 46 46 { … … 50 50 //------------------------------------------------------------------------------ 51 51 //Declaration 52 trait allocator_c( otype T, otypeallocator_t)52 trait allocator_c(T, allocator_t) 53 53 { 54 54 void realloc_storage(allocator_t*, size_t); … … 56 56 }; 57 57 58 forall( otype T, otypeallocator_t = heap_allocator(T) | allocator_c(T, allocator_t))58 forall(T, allocator_t = heap_allocator(T) | allocator_c(T, allocator_t)) 59 59 struct vector; 60 60 61 61 //------------------------------------------------------------------------------ 62 62 //Initialization 63 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))63 forall(T, allocator_t | allocator_c(T, allocator_t)) 64 64 void ?{}(vector(T, allocator_t)& this); 65 65 66 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))66 forall(T, allocator_t | allocator_c(T, allocator_t)) 67 67 void ?{}(vector(T, allocator_t)& this, vector(T, allocator_t) rhs); 68 68 69 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))69 forall(T, allocator_t | allocator_c(T, allocator_t)) 70 70 vector(T, allocator_t) ?=?(vector(T, allocator_t)& this, vector(T, allocator_t) rhs); 71 71 72 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))72 forall(T, allocator_t | allocator_c(T, allocator_t)) 73 73 void ^?{}(vector(T, allocator_t)& this); 74 74 75 forall( otype T, otypeallocator_t = heap_allocator(T) | allocator_c(T, allocator_t))75 forall(T, allocator_t = heap_allocator(T) | allocator_c(T, allocator_t)) 76 76 struct vector 77 77 { … … 82 82 //------------------------------------------------------------------------------ 83 83 //Capacity 84 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))84 forall(T, allocator_t | allocator_c(T, allocator_t)) 85 85 static inline bool empty(vector(T, allocator_t)* this) 86 86 { … … 88 88 } 89 89 90 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))90 forall(T, allocator_t | allocator_c(T, allocator_t)) 91 91 static inline size_t size(vector(T, allocator_t)* this) 92 92 { … … 94 94 } 95 95 96 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))96 forall(T, allocator_t | allocator_c(T, allocator_t)) 97 97 static inline void reserve(vector(T, allocator_t)* this, size_t size) 98 98 { … … 102 102 //------------------------------------------------------------------------------ 103 103 //Element access 104 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))104 forall(T, allocator_t | allocator_c(T, allocator_t)) 105 105 static inline T at(vector(T, allocator_t)* this, size_t index) 106 106 { … … 108 108 } 109 109 110 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))110 forall(T, allocator_t | allocator_c(T, allocator_t)) 111 111 static inline T ?[?](vector(T, allocator_t)* this, size_t index) 112 112 { … … 114 114 } 115 115 116 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))116 forall(T, allocator_t | allocator_c(T, allocator_t)) 117 117 static inline T front(vector(T, allocator_t)* this) 118 118 { … … 120 120 } 121 121 122 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))122 forall(T, allocator_t | allocator_c(T, allocator_t)) 123 123 static inline T back(vector(T, allocator_t)* this) 124 124 { … … 128 128 //------------------------------------------------------------------------------ 129 129 //Modifiers 130 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))130 forall(T, allocator_t | allocator_c(T, allocator_t)) 131 131 void push_back(vector(T, allocator_t)* this, T value); 132 132 133 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))133 forall(T, allocator_t | allocator_c(T, allocator_t)) 134 134 void pop_back(vector(T, allocator_t)* this); 135 135 136 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))136 forall(T, allocator_t | allocator_c(T, allocator_t)) 137 137 void clear(vector(T, allocator_t)* this); 138 138 139 139 //------------------------------------------------------------------------------ 140 140 //Iterators 141 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))141 forall(T, allocator_t | allocator_c(T, allocator_t)) 142 142 static inline T* begin(vector(T, allocator_t)* this) 143 143 { … … 145 145 } 146 146 147 // forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))147 // forall(T, allocator_t | allocator_c(T, allocator_t)) 148 148 // static inline const T* cbegin(const vector(T, allocator_t)* this) 149 149 // { … … 151 151 // } 152 152 153 forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))153 forall(T, allocator_t | allocator_c(T, allocator_t)) 154 154 static inline T* end(vector(T, allocator_t)* this) 155 155 { … … 157 157 } 158 158 159 // forall( otype T, otypeallocator_t | allocator_c(T, allocator_t))159 // forall(T, allocator_t | allocator_c(T, allocator_t)) 160 160 // static inline const T* cend(const vector(T, allocator_t)* this) 161 161 // { -
libcfa/src/exception.h
r467c8b7 rc08c3cf 101 101 // implemented in the .c file either so they all have to be inline. 102 102 103 trait is_exception( dtype exceptT, dtype virtualT) {103 trait is_exception(exceptT &, virtualT &) { 104 104 /* The first field must be a pointer to a virtual table. 105 105 * That virtual table must be a decendent of the base exception virtual table. … … 109 109 }; 110 110 111 trait is_termination_exception( dtype exceptT, dtype virtualT| is_exception(exceptT, virtualT)) {111 trait is_termination_exception(exceptT &, virtualT & | is_exception(exceptT, virtualT)) { 112 112 void defaultTerminationHandler(exceptT &); 113 113 }; 114 114 115 trait is_resumption_exception( dtype exceptT, dtype virtualT| is_exception(exceptT, virtualT)) {115 trait is_resumption_exception(exceptT &, virtualT & | is_exception(exceptT, virtualT)) { 116 116 void defaultResumptionHandler(exceptT &); 117 117 }; 118 118 119 forall( dtype exceptT, dtype virtualT| is_termination_exception(exceptT, virtualT))119 forall(exceptT &, virtualT & | is_termination_exception(exceptT, virtualT)) 120 120 static inline void $throw(exceptT & except) { 121 121 __cfaehm_throw_terminate( … … 125 125 } 126 126 127 forall( dtype exceptT, dtype virtualT| is_resumption_exception(exceptT, virtualT))127 forall(exceptT &, virtualT & | is_resumption_exception(exceptT, virtualT)) 128 128 static inline void $throwResume(exceptT & except) { 129 129 __cfaehm_throw_resume( … … 133 133 } 134 134 135 forall( dtype exceptT, dtype virtualT| is_exception(exceptT, virtualT))135 forall(exceptT &, virtualT & | is_exception(exceptT, virtualT)) 136 136 static inline void cancel_stack(exceptT & except) __attribute__((noreturn)) { 137 137 __cfaehm_cancel_stack( (exception_t *)&except ); 138 138 } 139 139 140 forall( dtype exceptT, dtype virtualT| is_exception(exceptT, virtualT))140 forall(exceptT &, virtualT & | is_exception(exceptT, virtualT)) 141 141 static inline void defaultTerminationHandler(exceptT & except) { 142 142 return cancel_stack( except ); 143 143 } 144 144 145 forall( dtype exceptT, dtype virtualT| is_exception(exceptT, virtualT))145 forall(exceptT &, virtualT & | is_exception(exceptT, virtualT)) 146 146 static inline void defaultResumptionHandler(exceptT & except) { 147 147 throw except; -
libcfa/src/executor.cfa
r467c8b7 rc08c3cf 7 7 #include <containers/list.hfa> 8 8 9 forall( dtype T| $dlistable(T, T) ) {9 forall( T & | $dlistable(T, T) ) { 10 10 monitor Buffer { // unbounded buffer 11 11 dlist( T, T ) queue; // unbounded list of work requests -
libcfa/src/gmp.hfa
r467c8b7 rc08c3cf 255 255 256 256 // I/O 257 forall( dtype istype| istream( istype ) )257 forall( istype & | istream( istype ) ) 258 258 istype & ?|?( istype & is, Int & mp ) { 259 259 gmp_scanf( "%Zd", &mp ); … … 261 261 } // ?|? 262 262 263 forall( dtype ostype| ostream( ostype ) ) {263 forall( ostype & | ostream( ostype ) ) { 264 264 ostype & ?|?( ostype & os, Int mp ) { 265 265 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); -
libcfa/src/interpose.cfa
r467c8b7 rc08c3cf 125 125 126 126 // Failure handler 127 __cfaabi_sigaction( SIGSEGV, sigHandler_segv, SA_SIGINFO | SA_ONSTACK ); 128 __cfaabi_sigaction( SIGBUS , sigHandler_segv, SA_SIGINFO | SA_ONSTACK ); 129 __cfaabi_sigaction( SIGILL , sigHandler_ill , SA_SIGINFO | SA_ONSTACK ); 130 __cfaabi_sigaction( SIGFPE , sigHandler_fpe , SA_SIGINFO | SA_ONSTACK ); 131 __cfaabi_sigaction( SIGTERM, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // one shot handler, return to default 132 __cfaabi_sigaction( SIGINT , sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); 133 __cfaabi_sigaction( SIGABRT, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); 134 __cfaabi_sigaction( SIGHUP , sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // terminal hangup 127 // internal errors 128 __cfaabi_sigaction( SIGSEGV, sigHandler_segv, SA_SIGINFO | SA_ONSTACK ); // Invalid memory reference (default: Core) 129 __cfaabi_sigaction( SIGBUS , sigHandler_segv, SA_SIGINFO | SA_ONSTACK ); // Bus error, bad memory access (default: Core) 130 __cfaabi_sigaction( SIGILL , sigHandler_ill , SA_SIGINFO | SA_ONSTACK ); // Illegal Instruction (default: Core) 131 __cfaabi_sigaction( SIGFPE , sigHandler_fpe , SA_SIGINFO | SA_ONSTACK ); // Floating-point exception (default: Core) 132 133 // handlers to outside errors 134 // reset in-case they insist and send it over and over 135 __cfaabi_sigaction( SIGTERM, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // Termination signal (default: Term) 136 __cfaabi_sigaction( SIGINT , sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // Interrupt from keyboard (default: Term) 137 __cfaabi_sigaction( SIGHUP , sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // Hangup detected on controlling terminal or death of controlling process (default: Term) 138 __cfaabi_sigaction( SIGQUIT, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // Quit from keyboard (default: Core) 139 __cfaabi_sigaction( SIGABRT, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // Abort signal from abort(3) (default: Core) 135 140 } 136 141 } … … 163 168 } 164 169 165 void * kernel_abort( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 0p; } 166 void kernel_abort_msg( void * data, char buffer[], int size) __attribute__(( __nothrow__, __leaf__, __weak__ )) {}167 // See concurrency/kernel.cfa for strong definition used in multi-processor mode. 168 int kernel_abort_lastframe( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 4; }170 // See concurrency/kernel.cfa and concurrency/preemption.cfa for strong definition used in multi-processor mode. 171 void __kernel_abort_lock( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) {} 172 void __kernel_abort_msg( char buffer[], int size ) __attribute__(( __nothrow__, __leaf__, __weak__ )) {} 173 int __kernel_abort_lastframe( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 4; } 169 174 170 175 enum { abort_text_size = 1024 }; … … 173 178 static void __cfaabi_backtrace( int start ) { 174 179 enum { Frames = 50, }; // maximum number of stack frames 175 int last = kernel_abort_lastframe(); // skip last N stack frames180 int last = __kernel_abort_lastframe(); // skip last N stack frames 176 181 177 182 void * array[Frames]; … … 220 225 } 221 226 222 static volatile int __abort_stage= 0;227 static volatile bool __abort_first = 0; 223 228 224 229 // Cannot forward va_list. 225 230 void __abort( bool signalAbort, const char fmt[], va_list args ) { 226 int stage = __atomic_add_fetch( &__abort_stage, 1, __ATOMIC_SEQ_CST ); 227 228 // First stage: stop the cforall kernel and print 229 if(stage == 1) { 230 // increment stage 231 stage = __atomic_add_fetch( &__abort_stage, 1, __ATOMIC_SEQ_CST ); 232 233 // must be done here to lock down kernel 234 void * kernel_data = kernel_abort(); 235 int len; 236 237 signal( SIGABRT, SIG_DFL ); // prevent final "real" abort from recursing to handler 238 239 len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld) ", (long int)getpid() ); // use UNIX pid (versus getPid) 240 __cfaabi_bits_write( STDERR_FILENO, abort_text, len ); 241 242 assert( fmt ); 243 len = vsnprintf( abort_text, abort_text_size, fmt, args ); 244 __cfaabi_bits_write( STDERR_FILENO, abort_text, len ); 245 246 // add optional newline if missing at the end of the format text 247 if ( fmt[strlen( fmt ) - 1] != '\n' ) { 248 __cfaabi_bits_write( STDERR_FILENO, "\n", 1 ); 249 } // if 250 kernel_abort_msg( kernel_data, abort_text, abort_text_size ); 251 } 252 253 // Second stage: print the backtrace 254 if(stage == 2) { 255 // increment stage 256 stage = __atomic_add_fetch( &__abort_stage, 1, __ATOMIC_SEQ_CST ); 257 258 // print stack trace in handler 259 __cfaabi_backtrace( signalAbort ? 4 : 2 ); 260 } 261 262 do { 263 // Finally call abort 231 // Multiple threads can come here from multiple paths 232 // To make sure this is safe any concurrent/subsequent call to abort is redirected to libc-abort 233 bool first = ! __atomic_test_and_set( &__abort_first, __ATOMIC_SEQ_CST); 234 235 // Prevent preemption from kicking-in and messing with the abort 236 __kernel_abort_lock(); 237 238 // first to abort ? 239 if ( !first ) { 240 // We aren't the first to abort just let C handle it 241 signal( SIGABRT, SIG_DFL ); // restore default in case we came here through the function. 264 242 __cabi_libc.abort(); 265 266 // Loop so that we never return 267 } while(true); 243 } 244 245 int len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld) ", (long int)getpid() ); // use UNIX pid (versus getPid) 246 __cfaabi_bits_write( STDERR_FILENO, abort_text, len ); 247 248 // print the cause of the error 249 assert( fmt ); 250 len = vsnprintf( abort_text, abort_text_size, fmt, args ); 251 __cfaabi_bits_write( STDERR_FILENO, abort_text, len ); 252 253 // add optional newline if missing at the end of the format text 254 if ( fmt[strlen( fmt ) - 1] != '\n' ) { 255 __cfaabi_bits_write( STDERR_FILENO, "\n", 1 ); 256 } // if 257 258 // Give the kernel the chance to add some data in here 259 __kernel_abort_msg( abort_text, abort_text_size ); 260 261 // print stack trace in handler 262 __cfaabi_backtrace( signalAbort ? 4 : 2 ); 263 264 // Finally call abort 265 __cabi_libc.abort(); 266 268 267 } 269 268 … … 282 281 // CONTROL NEVER REACHES HERE! 283 282 va_end( args ); 284 }285 286 extern "C" {287 void __cfaabi_real_abort(void) {288 __cabi_libc.abort();289 }290 283 } 291 284 -
libcfa/src/iostream.cfa
r467c8b7 rc08c3cf 36 36 37 37 38 forall( dtype ostype| ostream( ostype ) ) {38 forall( ostype & | ostream( ostype ) ) { 39 39 ostype & ?|?( ostype & os, bool b ) { 40 40 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); … … 407 407 408 408 // tuples 409 forall( dtype ostype, otype T, ttype Params| writeable( T, ostype ) | { ostype & ?|?( ostype &, Params ); } ) {409 forall( ostype &, T, Params... | writeable( T, ostype ) | { ostype & ?|?( ostype &, Params ); } ) { 410 410 ostype & ?|?( ostype & os, T arg, Params rest ) { 411 411 (ostype &)(os | arg); // print first argument … … 426 426 427 427 // writes the range [begin, end) to the given stream 428 forall( dtype ostype, otype elt_type | writeable( elt_type, ostype ), otypeiterator_type | iterator( iterator_type, elt_type ) ) {428 forall( ostype &, elt_type | writeable( elt_type, ostype ), iterator_type | iterator( iterator_type, elt_type ) ) { 429 429 void write( iterator_type begin, iterator_type end, ostype & os ) { 430 430 void print( elt_type i ) { os | i; } … … 447 447 // Default prefix for non-decimal prints is 0b, 0, 0x. 448 448 #define IntegralFMTImpl( T, IFMTNP, IFMTP ) \ 449 forall( dtype ostype| ostream( ostype ) ) { \449 forall( ostype & | ostream( ostype ) ) { \ 450 450 ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \ 451 451 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \ … … 540 540 // Default prefix for non-decimal prints is 0b, 0, 0x. 541 541 #define IntegralFMTImpl128( T, SIGNED, CODE, IFMTNP, IFMTP ) \ 542 forall( dtype ostype| ostream( ostype ) ) \542 forall( ostype & | ostream( ostype ) ) \ 543 543 static void base10_128( ostype & os, _Ostream_Manip(T) f ) { \ 544 544 if ( f.val > UINT64_MAX ) { \ … … 557 557 } /* if */ \ 558 558 } /* base10_128 */ \ 559 forall( dtype ostype| ostream( ostype ) ) { \559 forall( ostype & | ostream( ostype ) ) { \ 560 560 ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \ 561 561 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \ … … 659 659 #if defined( __SIZEOF_INT128__ ) 660 660 // Default prefix for non-decimal prints is 0b, 0, 0x. 661 forall( dtype ostype| ostream( ostype ) )661 forall( ostype & | ostream( ostype ) ) 662 662 static inline void base_128( ostype & os, unsigned int128 val, unsigned int128 power, _Ostream_Manip(uint64_t) & f, unsigned int maxdig, unsigned int bits, unsigned int cnt = 0 ) { 663 663 int wd = 1; // f.wd is never 0 because 0 implies left-pad … … 724 724 725 725 #define IntegralFMTImpl128( T ) \ 726 forall( dtype ostype| ostream( ostype ) ) { \726 forall( ostype & | ostream( ostype ) ) { \ 727 727 ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \ 728 728 _Ostream_Manip(uint64_t) fmt; \ … … 772 772 773 773 #define FloatingPointFMTImpl( T, DFMTNP, DFMTP ) \ 774 forall( dtype ostype| ostream( ostype ) ) { \774 forall( ostype & | ostream( ostype ) ) { \ 775 775 ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \ 776 776 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \ … … 806 806 // *********************************** character *********************************** 807 807 808 forall( dtype ostype| ostream( ostype ) ) {808 forall( ostype & | ostream( ostype ) ) { 809 809 ostype & ?|?( ostype & os, _Ostream_Manip(char) f ) { 810 810 if ( f.base != 'c' ) { // bespoke binary/octal/hex format … … 839 839 // *********************************** C string *********************************** 840 840 841 forall( dtype ostype| ostream( ostype ) ) {841 forall( ostype & | ostream( ostype ) ) { 842 842 ostype & ?|?( ostype & os, _Ostream_Manip(const char *) f ) { 843 843 if ( ! f.val ) return os; // null pointer ? … … 887 887 888 888 889 forall( dtype istype| istream( istype ) ) {889 forall( istype & | istream( istype ) ) { 890 890 istype & ?|?( istype & is, bool & b ) { 891 891 char val[6]; … … 1053 1053 // *********************************** manipulators *********************************** 1054 1054 1055 forall( dtype istype| istream( istype ) )1055 forall( istype & | istream( istype ) ) 1056 1056 istype & ?|?( istype & is, _Istream_Cstr f ) { 1057 1057 // skip xxx … … 1088 1088 } // ?|? 1089 1089 1090 forall( dtype istype| istream( istype ) )1090 forall( istype & | istream( istype ) ) 1091 1091 istype & ?|?( istype & is, _Istream_Char f ) { 1092 1092 fmt( is, "%*c" ); // argument variable unused … … 1095 1095 1096 1096 #define InputFMTImpl( T, CODE ) \ 1097 forall( dtype istype| istream( istype ) ) \1097 forall( istype & | istream( istype ) ) \ 1098 1098 istype & ?|?( istype & is, _Istream_Manip(T) f ) { \ 1099 1099 enum { size = 16 }; \ … … 1124 1124 InputFMTImpl( long double, "Lf" ) 1125 1125 1126 forall( dtype istype| istream( istype ) )1126 forall( istype & | istream( istype ) ) 1127 1127 istype & ?|?( istype & is, _Istream_Manip(float _Complex) fc ) { 1128 1128 float re, im; … … 1135 1135 } // ?|? 1136 1136 1137 forall( dtype istype| istream( istype ) )1137 forall( istype & | istream( istype ) ) 1138 1138 istype & ?|?( istype & is, _Istream_Manip(double _Complex) dc ) { 1139 1139 double re, im; … … 1146 1146 } // ?|? 1147 1147 1148 forall( dtype istype| istream( istype ) )1148 forall( istype & | istream( istype ) ) 1149 1149 istype & ?|?( istype & is, _Istream_Manip(long double _Complex) ldc ) { 1150 1150 long double re, im; -
libcfa/src/iostream.hfa
r467c8b7 rc08c3cf 22 22 23 23 24 trait ostream( dtype ostype) {24 trait ostream( ostype & ) { 25 25 // private 26 26 bool $sepPrt( ostype & ); // get separator state (on/off) … … 57 57 }; // ostream 58 58 59 // trait writeable( otypeT ) {60 // forall( dtype ostype| ostream( ostype ) ) ostype & ?|?( ostype &, T );59 // trait writeable( T ) { 60 // forall( ostype & | ostream( ostype ) ) ostype & ?|?( ostype &, T ); 61 61 // }; // writeable 62 62 63 trait writeable( otype T, dtype ostype| ostream( ostype ) ) {63 trait writeable( T, ostype & | ostream( ostype ) ) { 64 64 ostype & ?|?( ostype &, T ); 65 65 }; // writeable … … 67 67 // implement writable for intrinsic types 68 68 69 forall( dtype ostype| ostream( ostype ) ) {69 forall( ostype & | ostream( ostype ) ) { 70 70 ostype & ?|?( ostype &, bool ); 71 71 void ?|?( ostype &, bool ); … … 142 142 143 143 // tuples 144 forall( dtype ostype, otype T, ttype Params| writeable( T, ostype ) | { ostype & ?|?( ostype &, Params ); } ) {144 forall( ostype &, T, Params... | writeable( T, ostype ) | { ostype & ?|?( ostype &, Params ); } ) { 145 145 ostype & ?|?( ostype & os, T arg, Params rest ); 146 146 void ?|?( ostype & os, T arg, Params rest ); … … 148 148 149 149 // writes the range [begin, end) to the given stream 150 forall( dtype ostype, otype elt_type | writeable( elt_type, ostype ), otypeiterator_type | iterator( iterator_type, elt_type ) ) {150 forall( ostype &, elt_type | writeable( elt_type, ostype ), iterator_type | iterator( iterator_type, elt_type ) ) { 151 151 void write( iterator_type begin, iterator_type end, ostype & os ); 152 152 void write_reverse( iterator_type begin, iterator_type end, ostype & os ); … … 155 155 // *********************************** manipulators *********************************** 156 156 157 forall( otypeT )157 forall( T ) 158 158 struct _Ostream_Manip { 159 159 T val; // polymorphic base-type … … 195 195 _Ostream_Manip(T) & sign( _Ostream_Manip(T) & fmt ) { fmt.flags.sign = true; return fmt; } \ 196 196 } /* distribution */ \ 197 forall( dtype ostype| ostream( ostype ) ) { \197 forall( ostype & | ostream( ostype ) ) { \ 198 198 ostype & ?|?( ostype & os, _Ostream_Manip(T) f ); \ 199 199 void ?|?( ostype & os, _Ostream_Manip(T) f ); \ … … 236 236 _Ostream_Manip(T) & nodp( _Ostream_Manip(T) & fmt ) { fmt.flags.nobsdp = true; return fmt; } \ 237 237 } /* distribution */ \ 238 forall( dtype ostype| ostream( ostype ) ) { \238 forall( ostype & | ostream( ostype ) ) { \ 239 239 ostype & ?|?( ostype & os, _Ostream_Manip(T) f ); \ 240 240 void ?|?( ostype & os, _Ostream_Manip(T) f ); \ … … 256 256 _Ostream_Manip(char) & nobase( _Ostream_Manip(char) & fmt ) { fmt.flags.nobsdp = true; return fmt; } 257 257 } // distribution 258 forall( dtype ostype| ostream( ostype ) ) {258 forall( ostype & | ostream( ostype ) ) { 259 259 ostype & ?|?( ostype & os, _Ostream_Manip(char) f ); 260 260 void ?|?( ostype & os, _Ostream_Manip(char) f ); … … 274 274 _Ostream_Manip(const char *) & nobase( _Ostream_Manip(const char *) & fmt ) { fmt.flags.nobsdp = true; return fmt; } 275 275 } // distribution 276 forall( dtype ostype| ostream( ostype ) ) {276 forall( ostype & | ostream( ostype ) ) { 277 277 ostype & ?|?( ostype & os, _Ostream_Manip(const char *) f ); 278 278 void ?|?( ostype & os, _Ostream_Manip(const char *) f ); … … 283 283 284 284 285 trait istream( dtype istype) {285 trait istream( istype & ) { 286 286 void nlOn( istype & ); // read newline 287 287 void nlOff( istype & ); // scan newline … … 296 296 }; // istream 297 297 298 trait readable( otypeT ) {299 forall( dtype istype| istream( istype ) ) istype & ?|?( istype &, T );298 trait readable( T ) { 299 forall( istype & | istream( istype ) ) istype & ?|?( istype &, T ); 300 300 }; // readable 301 301 302 forall( dtype istype| istream( istype ) ) {302 forall( istype & | istream( istype ) ) { 303 303 istype & ?|?( istype &, bool & ); 304 304 … … 365 365 _Istream_Cstr & wdi( unsigned int w, _Istream_Cstr & fmt ) { fmt.wd = w; return fmt; } 366 366 } // distribution 367 forall( dtype istype| istream( istype ) ) istype & ?|?( istype & is, _Istream_Cstr f );367 forall( istype & | istream( istype ) ) istype & ?|?( istype & is, _Istream_Cstr f ); 368 368 369 369 struct _Istream_Char { … … 375 375 _Istream_Char & ignore( _Istream_Char & fmt ) { fmt.ignore = true; return fmt; } 376 376 } // distribution 377 forall( dtype istype| istream( istype ) ) istype & ?|?( istype & is, _Istream_Char f );378 379 forall( dtype T| sized( T ) )377 forall( istype & | istream( istype ) ) istype & ?|?( istype & is, _Istream_Char f ); 378 379 forall( T & | sized( T ) ) 380 380 struct _Istream_Manip { 381 381 T & val; // polymorphic base-type … … 391 391 _Istream_Manip(T) & wdi( unsigned int w, _Istream_Manip(T) & fmt ) { fmt.wd = w; return fmt; } \ 392 392 } /* distribution */ \ 393 forall( dtype istype| istream( istype ) ) { \393 forall( istype & | istream( istype ) ) { \ 394 394 istype & ?|?( istype & is, _Istream_Manip(T) f ); \ 395 395 } // ?|? … … 420 420 #include <time_t.hfa> // Duration (constructors) / Time (constructors) 421 421 422 forall( dtype ostype| ostream( ostype ) ) {422 forall( ostype & | ostream( ostype ) ) { 423 423 ostype & ?|?( ostype & os, Duration dur ); 424 424 void ?|?( ostype & os, Duration dur ); -
libcfa/src/iterator.cfa
r467c8b7 rc08c3cf 16 16 #include "iterator.hfa" 17 17 18 forall( otype iterator_type, otypeelt_type | iterator( iterator_type, elt_type ) )18 forall( iterator_type, elt_type | iterator( iterator_type, elt_type ) ) 19 19 void for_each( iterator_type begin, iterator_type end, void (* func)( elt_type ) ) { 20 20 for ( iterator_type i = begin; i != end; ++i ) { … … 23 23 } // for_each 24 24 25 forall( otype iterator_type, otypeelt_type | iterator( iterator_type, elt_type ) )25 forall( iterator_type, elt_type | iterator( iterator_type, elt_type ) ) 26 26 void for_each_reverse( iterator_type begin, iterator_type end, void (* func)( elt_type ) ) { 27 27 for ( iterator_type i = end; i != begin; ) { -
libcfa/src/iterator.hfa
r467c8b7 rc08c3cf 17 17 18 18 // An iterator can be used to traverse a data structure. 19 trait iterator( otype iterator_type, otypeelt_type ) {19 trait iterator( iterator_type, elt_type ) { 20 20 // point to the next element 21 21 // iterator_type ?++( iterator_type & ); … … 31 31 }; 32 32 33 trait iterator_for( otype iterator_type, otype collection_type, otypeelt_type | iterator( iterator_type, elt_type ) ) {33 trait iterator_for( iterator_type, collection_type, elt_type | iterator( iterator_type, elt_type ) ) { 34 34 // [ iterator_type begin, iterator_type end ] get_iterators( collection_type ); 35 35 iterator_type begin( collection_type ); … … 37 37 }; 38 38 39 forall( otype iterator_type, otypeelt_type | iterator( iterator_type, elt_type ) )39 forall( iterator_type, elt_type | iterator( iterator_type, elt_type ) ) 40 40 void for_each( iterator_type begin, iterator_type end, void (* func)( elt_type ) ); 41 41 42 forall( otype iterator_type, otypeelt_type | iterator( iterator_type, elt_type ) )42 forall( iterator_type, elt_type | iterator( iterator_type, elt_type ) ) 43 43 void for_each_reverse( iterator_type begin, iterator_type end, void (* func)( elt_type ) ); 44 44 -
libcfa/src/math.hfa
r467c8b7 rc08c3cf 286 286 unsigned long long int floor( unsigned long long int n, unsigned long long int align ) { return n / align * align; } 287 287 288 // forall( otypeT | { T ?/?( T, T ); T ?*?( T, T ); } )288 // forall( T | { T ?/?( T, T ); T ?*?( T, T ); } ) 289 289 // T floor( T n, T align ) { return n / align * align; } 290 290 … … 300 300 unsigned long long int ceiling_div( unsigned long long int n, unsigned long long int align ) { return (n + (align - 1)) / align; } 301 301 302 // forall( otypeT | { T ?+?( T, T ); T ?-?( T, T ); T ?%?( T, T ); } )302 // forall( T | { T ?+?( T, T ); T ?-?( T, T ); T ?%?( T, T ); } ) 303 303 // T ceiling_div( T n, T align ) { verify( is_pow2( align ) );return (n + (align - 1)) / align; } 304 304 … … 315 315 unsigned long long int ceiling( unsigned long long int n, unsigned long long int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); } 316 316 317 // forall( otypeT | { void ?{}( T &, one_t ); T ?+?( T, T ); T ?-?( T, T ); T ?/?( T, T ); } )317 // forall( T | { void ?{}( T &, one_t ); T ?+?( T, T ); T ?-?( T, T ); T ?/?( T, T ); } ) 318 318 // T ceiling( T n, T align ) { return return floor( n + (n % align != 0 ? align - 1 : 0), align ); *} 319 319 … … 414 414 415 415 static inline { 416 forall( otypeT | { void ?{}( T &, one_t ); T ?+?( T, T ); T ?-?( T, T );T ?*?( T, T ); } )416 forall( T | { void ?{}( T &, one_t ); T ?+?( T, T ); T ?-?( T, T );T ?*?( T, T ); } ) 417 417 T lerp( T x, T y, T a ) { return x * ((T){1} - a) + y * a; } 418 418 419 forall( otypeT | { void ?{}( T &, zero_t ); void ?{}( T &, one_t ); int ?<?( T, T ); } )419 forall( T | { void ?{}( T &, zero_t ); void ?{}( T &, one_t ); int ?<?( T, T ); } ) 420 420 T step( T edge, T x ) { return x < edge ? (T){0} : (T){1}; } 421 421 422 forall( otypeT | { void ?{}( T &, int ); T clamp( T, T, T ); T ?-?( T, T ); T ?*?( T, T ); T ?/?( T, T ); } )422 forall( T | { void ?{}( T &, int ); T clamp( T, T, T ); T ?-?( T, T ); T ?*?( T, T ); T ?/?( T, T ); } ) 423 423 T smoothstep( T edge0, T edge1, T x ) { T t = clamp( (x - edge0) / (edge1 - edge0), (T){0}, (T){1} ); return t * t * ((T){3} - (T){2} * t); } 424 424 } // distribution -
libcfa/src/memory.cfa
r467c8b7 rc08c3cf 18 18 19 19 // Internal data object. 20 forall( dtype T | sized(T), ttype Args| { void ?{}(T &, Args); })20 forall(T & | sized(T), Args... | { void ?{}(T &, Args); }) 21 21 void ?{}(counter_data(T) & this, Args args) { 22 22 (this.counter){1}; … … 24 24 } 25 25 26 forall( dtype T| sized(T) | { void ^?{}(T &); })26 forall(T & | sized(T) | { void ^?{}(T &); }) 27 27 void ^?{}(counter_data(T) & this) { 28 28 assert(0 == this.counter); … … 31 31 32 32 // This is one of many pointers keeping this alive. 33 forall( dtype T| sized(T))33 forall(T & | sized(T)) 34 34 void ?{}(counter_ptr(T) & this) { 35 35 this.data = 0p; 36 36 } 37 37 38 forall( dtype T| sized(T))38 forall(T & | sized(T)) 39 39 void ?{}(counter_ptr(T) & this, zero_t) { 40 40 this.data = 0p; 41 41 } 42 42 43 forall( dtype T| sized(T) | { void ^?{}(T &); })43 forall(T & | sized(T) | { void ^?{}(T &); }) 44 44 static void internal_decrement(counter_ptr(T) & this) { 45 45 if (this.data && 0 == --this.data->counter) { … … 48 48 } 49 49 50 forall( dtype T| sized(T))50 forall(T & | sized(T)) 51 51 static void internal_copy(counter_ptr(T) & this, counter_ptr(T) & that) { 52 52 this.data = that.data; … … 56 56 } 57 57 58 forall( dtype T| sized(T) | { void ^?{}(T &); })58 forall(T & | sized(T) | { void ^?{}(T &); }) 59 59 void ?{}(counter_ptr(T) & this, counter_ptr(T) that) { 60 60 // `that` is a copy but it should have neither a constructor … … 64 64 } 65 65 66 forall( dtype T | sized(T), ttype Args| { void ?{}(T&, Args); })66 forall(T & | sized(T), Args... | { void ?{}(T&, Args); }) 67 67 void ?{}(counter_ptr(T) & this, Args args) { 68 68 this.data = (counter_data(T)*)new(args); 69 69 } 70 70 71 forall( dtype T| sized(T) | { void ^?{}(T &); })71 forall(T & | sized(T) | { void ^?{}(T &); }) 72 72 void ^?{}(counter_ptr(T) & this) { 73 73 internal_decrement(this); 74 74 } 75 75 76 forall( dtype T| sized(T))76 forall(T & | sized(T)) 77 77 T & *?(counter_ptr(T) & this) { 78 78 return *((this.data) ? &this.data->object : 0p); 79 79 } 80 80 81 forall( dtype T| sized(T) | { void ^?{}(T &); })81 forall(T & | sized(T) | { void ^?{}(T &); }) 82 82 void ?=?(counter_ptr(T) & this, counter_ptr(T) that) { 83 83 if (this.data != that.data) { … … 87 87 } 88 88 89 forall( dtype T| sized(T) | { void ^?{}(T &); })89 forall(T & | sized(T) | { void ^?{}(T &); }) 90 90 void ?=?(counter_ptr(T) & this, zero_t) { 91 91 internal_decrement(this); … … 93 93 } 94 94 95 forall( dtype T| sized(T))95 forall(T & | sized(T)) 96 96 int ?==?(counter_ptr(T) const & this, counter_ptr(T) const & that) { 97 97 return this.data == that.data; 98 98 } 99 99 100 forall( dtype T| sized(T))100 forall(T & | sized(T)) 101 101 int ?!=?(counter_ptr(T) const & this, counter_ptr(T) const & that) { 102 102 return !?==?(this, that); 103 103 } 104 104 105 forall( dtype T| sized(T))105 forall(T & | sized(T)) 106 106 int ?==?(counter_ptr(T) const & this, zero_t) { 107 107 return this.data == 0; 108 108 } 109 109 110 forall( dtype T| sized(T))110 forall(T & | sized(T)) 111 111 int ?!=?(counter_ptr(T) const & this, zero_t) { 112 112 return !?==?(this, (zero_t)0); … … 114 114 115 115 // This is the only pointer that keeps this alive. 116 forall( dtype T)116 forall(T &) 117 117 void ?{}(unique_ptr(T) & this) { 118 118 this.data = 0p; 119 119 } 120 120 121 forall( dtype T)121 forall(T &) 122 122 void ?{}(unique_ptr(T) & this, zero_t) { 123 123 this.data = 0p; 124 124 } 125 125 126 forall( dtype T | sized(T), ttype Args| { void ?{}(T &, Args); })126 forall(T & | sized(T), Args... | { void ?{}(T &, Args); }) 127 127 void ?{}(unique_ptr(T) & this, Args args) { 128 128 this.data = (T *)new(args); 129 129 } 130 130 131 forall( dtype T| { void ^?{}(T &); })131 forall(T & | { void ^?{}(T &); }) 132 132 void ^?{}(unique_ptr(T) & this) { 133 133 delete(this.data); 134 134 } 135 135 136 forall( dtype T)136 forall(T &) 137 137 T & *?(unique_ptr(T) & this) { 138 138 return *this.data; 139 139 } 140 140 141 forall( dtype T| { void ^?{}(T &); })141 forall(T & | { void ^?{}(T &); }) 142 142 void ?=?(unique_ptr(T) & this, zero_t) { 143 143 delete(this.data); … … 145 145 } 146 146 147 forall( dtype T| { void ^?{}(T &); })147 forall(T & | { void ^?{}(T &); }) 148 148 void move(unique_ptr(T) & this, unique_ptr(T) & that) { 149 149 delete(this.data); … … 152 152 } 153 153 154 forall( dtype T)154 forall(T &) 155 155 int ?==?(unique_ptr(T) const & this, unique_ptr(T) const & that) { 156 156 return this.data == that.data; 157 157 } 158 158 159 forall( dtype T)159 forall(T &) 160 160 int ?!=?(unique_ptr(T) const & this, unique_ptr(T) const & that) { 161 161 return !?==?(this, that); 162 162 } 163 163 164 forall( dtype T)164 forall(T &) 165 165 int ?==?(unique_ptr(T) const & this, zero_t) { 166 166 return this.data == 0; 167 167 } 168 168 169 forall( dtype T)169 forall(T &) 170 170 int ?!=?(unique_ptr(T) const & this, zero_t) { 171 171 return !?==?(this, (zero_t)0); -
libcfa/src/memory.hfa
r467c8b7 rc08c3cf 17 17 18 18 // Internal data object. 19 forall( dtype T| sized(T)) {19 forall(T & | sized(T)) { 20 20 struct counter_data { 21 21 unsigned int counter; … … 23 23 }; 24 24 25 forall( ttype Args| { void ?{}(T &, Args); })25 forall(Args... | { void ?{}(T &, Args); }) 26 26 void ?{}(counter_data(T) & this, Args args); 27 27 … … 31 31 32 32 // This is one of many pointers keeping this alive. 33 forall( dtype T| sized(T)) {33 forall(T & | sized(T)) { 34 34 struct counter_ptr { 35 35 counter_data(T) * data; … … 40 40 forall( | { void ^?{}(T &); }) 41 41 void ?{}(counter_ptr(T) & this, counter_ptr(T) that); 42 forall( ttype Args| { void ?{}(T&, Args); })42 forall(Args... | { void ?{}(T&, Args); }) 43 43 void ?{}(counter_ptr(T) & this, Args args); 44 44 … … 60 60 61 61 // This is the only pointer that keeps this alive. 62 forall( dtype T) {62 forall(T &) { 63 63 struct unique_ptr { 64 64 T * data; … … 68 68 void ?{}(unique_ptr(T) & this, zero_t); 69 69 void ?{}(unique_ptr(T) & this, unique_ptr(T) that) = void; 70 forall( | sized(T), ttype Args| { void ?{}(T &, Args); })70 forall( | sized(T), Args... | { void ?{}(T &, Args); }) 71 71 void ?{}(unique_ptr(T) & this, Args args); 72 72 -
libcfa/src/parseargs.hfa
r467c8b7 rc08c3cf 14 14 static inline void ?{}( cfa_option & this ) {} 15 15 16 forall( dtype T| { bool parse(const char *, T & ); })16 forall(T & | { bool parse(const char *, T & ); }) 17 17 static inline void ?{}( cfa_option & this, char short_name, const char * long_name, const char * help, T & variable ) { 18 18 this.val = 0; … … 24 24 } 25 25 26 forall( dtype T)26 forall(T &) 27 27 static inline void ?{}( cfa_option & this, char short_name, const char * long_name, const char * help, T & variable, bool (*parse)(const char *, T & )) { 28 28 this.val = 0; -
libcfa/src/rational.cfa
r467c8b7 rc08c3cf 18 18 #include "stdlib.hfa" 19 19 20 forall( otypeRationalImpl | arithmetic( RationalImpl ) ) {20 forall( RationalImpl | arithmetic( RationalImpl ) ) { 21 21 // helper routines 22 22 … … 159 159 // I/O 160 160 161 forall( dtype istype| istream( istype ) | { istype & ?|?( istype &, RationalImpl & ); } )161 forall( istype & | istream( istype ) | { istype & ?|?( istype &, RationalImpl & ); } ) 162 162 istype & ?|?( istype & is, Rational(RationalImpl) & r ) { 163 163 is | r.numerator | r.denominator; … … 168 168 } // ?|? 169 169 170 forall( dtype ostype| ostream( ostype ) | { ostype & ?|?( ostype &, RationalImpl ); } ) {170 forall( ostype & | ostream( ostype ) | { ostype & ?|?( ostype &, RationalImpl ); } ) { 171 171 ostype & ?|?( ostype & os, Rational(RationalImpl) r ) { 172 172 return os | r.numerator | '/' | r.denominator; … … 179 179 } // distribution 180 180 181 forall( otypeRationalImpl | arithmetic( RationalImpl ) | { RationalImpl ?\?( RationalImpl, unsigned long ); } )181 forall( RationalImpl | arithmetic( RationalImpl ) | { RationalImpl ?\?( RationalImpl, unsigned long ); } ) 182 182 Rational(RationalImpl) ?\?( Rational(RationalImpl) x, long int y ) { 183 183 if ( y < 0 ) { … … 190 190 // conversion 191 191 192 forall( otypeRationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )192 forall( RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } ) 193 193 double widen( Rational(RationalImpl) r ) { 194 194 return convert( r.numerator ) / convert( r.denominator ); 195 195 } // widen 196 196 197 forall( otypeRationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double ); } )197 forall( RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double ); } ) 198 198 Rational(RationalImpl) narrow( double f, RationalImpl md ) { 199 199 // http://www.ics.uci.edu/~eppstein/numth/frap.c -
libcfa/src/rational.hfa
r467c8b7 rc08c3cf 20 20 #include "iostream.hfa" 21 21 22 trait scalar( otypeT ) {22 trait scalar( T ) { 23 23 }; 24 24 25 trait arithmetic( otypeT | scalar( T ) ) {25 trait arithmetic( T | scalar( T ) ) { 26 26 int !?( T ); 27 27 int ?==?( T, T ); … … 46 46 // implementation 47 47 48 forall( otypeRationalImpl | arithmetic( RationalImpl ) ) {48 forall( RationalImpl | arithmetic( RationalImpl ) ) { 49 49 struct Rational { 50 50 RationalImpl numerator, denominator; // invariant: denominator > 0 … … 89 89 90 90 // I/O 91 forall( dtype istype| istream( istype ) | { istype & ?|?( istype &, RationalImpl & ); } )91 forall( istype & | istream( istype ) | { istype & ?|?( istype &, RationalImpl & ); } ) 92 92 istype & ?|?( istype &, Rational(RationalImpl) & ); 93 93 94 forall( dtype ostype| ostream( ostype ) | { ostype & ?|?( ostype &, RationalImpl ); } ) {94 forall( ostype & | ostream( ostype ) | { ostype & ?|?( ostype &, RationalImpl ); } ) { 95 95 ostype & ?|?( ostype &, Rational(RationalImpl) ); 96 96 void ?|?( ostype &, Rational(RationalImpl) ); … … 98 98 } // distribution 99 99 100 forall( otypeRationalImpl | arithmetic( RationalImpl ) |{RationalImpl ?\?( RationalImpl, unsigned long );} )100 forall( RationalImpl | arithmetic( RationalImpl ) |{RationalImpl ?\?( RationalImpl, unsigned long );} ) 101 101 Rational(RationalImpl) ?\?( Rational(RationalImpl) x, long int y ); 102 102 103 103 // conversion 104 forall( otypeRationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )104 forall( RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } ) 105 105 double widen( Rational(RationalImpl) r ); 106 forall( otypeRationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double );} )106 forall( RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double );} ) 107 107 Rational(RationalImpl) narrow( double f, RationalImpl md ); 108 108 -
libcfa/src/stdlib.cfa
r467c8b7 rc08c3cf 28 28 // Cforall allocation/deallocation and constructor/destructor, array types 29 29 30 forall( dtype T | sized(T), ttype TT| { void ?{}( T &, TT ); } )30 forall( T & | sized(T), TT... | { void ?{}( T &, TT ); } ) 31 31 T * anew( size_t dim, TT p ) { 32 32 T * arr = alloc( dim ); … … 37 37 } // anew 38 38 39 forall( dtype T| sized(T) | { void ^?{}( T & ); } )39 forall( T & | sized(T) | { void ^?{}( T & ); } ) 40 40 void adelete( T arr[] ) { 41 41 if ( arr ) { // ignore null … … 48 48 } // adelete 49 49 50 forall( dtype T | sized(T) | { void ^?{}( T & ); }, ttype TT| { void adelete( TT ); } )50 forall( T & | sized(T) | { void ^?{}( T & ); }, TT... | { void adelete( TT ); } ) 51 51 void adelete( T arr[], TT rest ) { 52 52 if ( arr ) { // ignore null … … 97 97 //--------------------------------------- 98 98 99 forall( otypeE | { int ?<?( E, E ); } ) {99 forall( E | { int ?<?( E, E ); } ) { 100 100 E * bsearch( E key, const E * vals, size_t dim ) { 101 101 int cmp( const void * t1, const void * t2 ) { … … 156 156 157 157 158 forall( otype K, otypeE | { int ?<?( K, K ); K getKey( const E & ); } ) {158 forall( K, E | { int ?<?( K, K ); K getKey( const E & ); } ) { 159 159 E * bsearch( K key, const E * vals, size_t dim ) { 160 160 int cmp( const void * t1, const void * t2 ) { -
libcfa/src/stdlib.hfa
r467c8b7 rc08c3cf 48 48 else return (T *)alignment( _Alignof(T), dim, sizeof(T) ) 49 49 50 static inline forall( dtype T| sized(T) ) {50 static inline forall( T & | sized(T) ) { 51 51 // CFA safe equivalents, i.e., implicit size specification 52 52 … … 108 108 109 109 1. Replace the current forall-block that contains defintions of S_fill and S_realloc with following: 110 forall( dtype T| sized(T) ) {110 forall( T & | sized(T) ) { 111 111 union U_fill { char c; T * a; T t; }; 112 112 struct S_fill { char tag; U_fill(T) fill; }; … … 151 151 typedef struct S_resize { inline void *; } T_resize; 152 152 153 forall( dtype T) {153 forall( T & ) { 154 154 struct S_fill { char tag; char c; size_t size; T * at; char t[50]; }; 155 155 struct S_realloc { inline T *; }; … … 159 159 static inline T_resize ?`resize ( void * a ) { return (T_resize){a}; } 160 160 161 static inline forall( dtype T| sized(T) ) {161 static inline forall( T & | sized(T) ) { 162 162 S_fill(T) ?`fill ( T t ) { 163 163 S_fill(T) ret = { 't' }; … … 207 207 } // $alloc_internal 208 208 209 forall( ttype TT| { T * $alloc_internal( void *, T *, size_t, size_t, S_fill(T), TT ); } ) {209 forall( TT... | { T * $alloc_internal( void *, T *, size_t, size_t, S_fill(T), TT ); } ) { 210 210 211 211 T * $alloc_internal( void * , T * Realloc, size_t Align, size_t Dim, S_fill(T) Fill, T_resize Resize, TT rest) { … … 236 236 } // distribution T 237 237 238 static inline forall( dtype T| sized(T) ) {238 static inline forall( T & | sized(T) ) { 239 239 // CFA safe initialization/copy, i.e., implicit size specification, non-array types 240 240 T * memset( T * dest, char fill ) { … … 257 257 258 258 // CFA deallocation for multiple objects 259 static inline forall( dtype T) // FIX ME, problems with 0p in list259 static inline forall( T & ) // FIX ME, problems with 0p in list 260 260 void free( T * ptr ) { 261 261 free( (void *)ptr ); // C free 262 262 } // free 263 static inline forall( dtype T, ttype TT| { void free( TT ); } )263 static inline forall( T &, TT... | { void free( TT ); } ) 264 264 void free( T * ptr, TT rest ) { 265 265 free( ptr ); … … 268 268 269 269 // CFA allocation/deallocation and constructor/destructor, non-array types 270 static inline forall( dtype T | sized(T), ttype TT| { void ?{}( T &, TT ); } )270 static inline forall( T & | sized(T), TT... | { void ?{}( T &, TT ); } ) 271 271 T * new( TT p ) { 272 272 return &(*(T *)malloc()){ p }; // run constructor 273 273 } // new 274 274 275 static inline forall( dtype T| { void ^?{}( T & ); } )275 static inline forall( T & | { void ^?{}( T & ); } ) 276 276 void delete( T * ptr ) { 277 277 // special case for 0-sized object => always call destructor … … 281 281 free( ptr ); // always call free 282 282 } // delete 283 static inline forall( dtype T, ttype TT| { void ^?{}( T & ); void delete( TT ); } )283 static inline forall( T &, TT... | { void ^?{}( T & ); void delete( TT ); } ) 284 284 void delete( T * ptr, TT rest ) { 285 285 delete( ptr ); … … 288 288 289 289 // CFA allocation/deallocation and constructor/destructor, array types 290 forall( dtype T | sized(T), ttype TT| { void ?{}( T &, TT ); } ) T * anew( size_t dim, TT p );291 forall( dtype T| sized(T) | { void ^?{}( T & ); } ) void adelete( T arr[] );292 forall( dtype T | sized(T) | { void ^?{}( T & ); }, ttype TT| { void adelete( TT ); } ) void adelete( T arr[], TT rest );290 forall( T & | sized(T), TT... | { void ?{}( T &, TT ); } ) T * anew( size_t dim, TT p ); 291 forall( T & | sized(T) | { void ^?{}( T & ); } ) void adelete( T arr[] ); 292 forall( T & | sized(T) | { void ^?{}( T & ); }, TT... | { void adelete( TT ); } ) void adelete( T arr[], TT rest ); 293 293 294 294 //--------------------------------------- … … 330 330 //--------------------------------------- 331 331 332 forall( otypeE | { int ?<?( E, E ); } ) {332 forall( E | { int ?<?( E, E ); } ) { 333 333 E * bsearch( E key, const E * vals, size_t dim ); 334 334 size_t bsearch( E key, const E * vals, size_t dim ); … … 339 339 } // distribution 340 340 341 forall( otype K, otypeE | { int ?<?( K, K ); K getKey( const E & ); } ) {341 forall( K, E | { int ?<?( K, K ); K getKey( const E & ); } ) { 342 342 E * bsearch( K key, const E * vals, size_t dim ); 343 343 size_t bsearch( K key, const E * vals, size_t dim ); … … 348 348 } // distribution 349 349 350 forall( otypeE | { int ?<?( E, E ); } ) {350 forall( E | { int ?<?( E, E ); } ) { 351 351 void qsort( E * vals, size_t dim ); 352 352 } // distribution -
libcfa/src/time.cfa
r467c8b7 rc08c3cf 31 31 32 32 33 forall( dtype ostype| ostream( ostype ) ) {33 forall( ostype & | ostream( ostype ) ) { 34 34 ostype & ?|?( ostype & os, Duration dur ) with( dur ) { 35 35 (ostype &)(os | tn / TIMEGRAN); // print seconds … … 136 136 } // strftime 137 137 138 forall( dtype ostype| ostream( ostype ) ) {138 forall( ostype & | ostream( ostype ) ) { 139 139 ostype & ?|?( ostype & os, Time time ) with( time ) { 140 140 char buf[32]; // at least 26 -
libcfa/src/vec/vec.hfa
r467c8b7 rc08c3cf 18 18 #include <math.hfa> 19 19 20 trait fromint( otypeT) {20 trait fromint(T) { 21 21 void ?{}(T&, int); 22 22 }; 23 trait zeroinit( otypeT) {23 trait zeroinit(T) { 24 24 void ?{}(T&, zero_t); 25 25 }; 26 trait zero_assign( otypeT) {26 trait zero_assign(T) { 27 27 T ?=?(T&, zero_t); 28 28 }; 29 trait subtract( otypeT) {29 trait subtract(T) { 30 30 T ?-?(T, T); 31 31 }; 32 trait negate( otypeT) {32 trait negate(T) { 33 33 T -?(T); 34 34 }; 35 trait add( otypeT) {35 trait add(T) { 36 36 T ?+?(T, T); 37 37 }; 38 trait multiply( otypeT) {38 trait multiply(T) { 39 39 T ?*?(T, T); 40 40 }; 41 trait divide( otypeT) {41 trait divide(T) { 42 42 T ?/?(T, T); 43 43 }; 44 trait lessthan( otypeT) {44 trait lessthan(T) { 45 45 int ?<?(T, T); 46 46 }; 47 trait equality( otypeT) {47 trait equality(T) { 48 48 int ?==?(T, T); 49 49 }; 50 trait sqrt( otypeT) {50 trait sqrt(T) { 51 51 T sqrt(T); 52 52 }; … … 68 68 } 69 69 70 trait dottable( otype V, otypeT) {70 trait dottable(V, T) { 71 71 T dot(V, V); 72 72 }; … … 74 74 static inline { 75 75 76 forall( otype T | sqrt(T), otypeV | dottable(V, T))76 forall(T | sqrt(T), V | dottable(V, T)) 77 77 T length(V v) { 78 78 return sqrt(dot(v, v)); 79 79 } 80 80 81 forall( otype T, otypeV | dottable(V, T))81 forall(T, V | dottable(V, T)) 82 82 T length_squared(V v) { 83 83 return dot(v, v); 84 84 } 85 85 86 forall( otype T, otypeV | { T length(V); } | subtract(V))86 forall(T, V | { T length(V); } | subtract(V)) 87 87 T distance(V v1, V v2) { 88 88 return length(v1 - v2); 89 89 } 90 90 91 forall( otype T, otypeV | { T length(V); V ?/?(V, T); })91 forall(T, V | { T length(V); V ?/?(V, T); }) 92 92 V normalize(V v) { 93 93 return v / length(v); … … 95 95 96 96 // Project vector u onto vector v 97 forall( otype T, otypeV | dottable(V, T) | { V normalize(V); V ?*?(V, T); })97 forall(T, V | dottable(V, T) | { V normalize(V); V ?*?(V, T); }) 98 98 V project(V u, V v) { 99 99 V v_norm = normalize(v); … … 102 102 103 103 // Reflect incident vector v with respect to surface with normal n 104 forall( otype T | fromint(T), otypeV | { V project(V, V); V ?*?(T, V); V ?-?(V,V); })104 forall(T | fromint(T), V | { V project(V, V); V ?*?(T, V); V ?-?(V,V); }) 105 105 V reflect(V v, V n) { 106 106 return v - (T){2} * project(v, n); … … 111 111 // entering material (i.e., from air to water, eta = 1/1.33) 112 112 // v and n must already be normalized 113 forall( otypeT | fromint(T) | subtract(T) | multiply(T) | add(T) | lessthan(T) | sqrt(T),114 otypeV | dottable(V, T) | { V ?*?(T, V); V ?-?(V,V); void ?{}(V&, zero_t); })113 forall(T | fromint(T) | subtract(T) | multiply(T) | add(T) | lessthan(T) | sqrt(T), 114 V | dottable(V, T) | { V ?*?(T, V); V ?-?(V,V); void ?{}(V&, zero_t); }) 115 115 V refract(V v, V n, T eta) { 116 116 T dotValue = dot(n, v); … … 128 128 // i is the incident vector 129 129 // ng is the geometric normal of the surface 130 forall( otype T | lessthan(T) | zeroinit(T), otypeV | dottable(V, T) | negate(V))130 forall(T | lessthan(T) | zeroinit(T), V | dottable(V, T) | negate(V)) 131 131 V faceforward(V n, V i, V ng) { 132 132 return dot(ng, i) < (T){0} ? n : -n; -
libcfa/src/vec/vec2.hfa
r467c8b7 rc08c3cf 19 19 #include "vec.hfa" 20 20 21 forall ( otypeT) {21 forall (T) { 22 22 struct vec2 { 23 23 T x, y; … … 25 25 } 26 26 27 forall ( otypeT) {27 forall (T) { 28 28 static inline { 29 29 … … 279 279 } 280 280 281 forall( dtype ostype, otypeT | writeable(T, ostype)) {281 forall(ostype &, T | writeable(T, ostype)) { 282 282 ostype & ?|?(ostype & os, vec2(T) v) with (v) { 283 283 return os | '<' | x | ',' | y | '>'; -
libcfa/src/vec/vec3.hfa
r467c8b7 rc08c3cf 19 19 #include "vec.hfa" 20 20 21 forall ( otypeT) {21 forall (T) { 22 22 struct vec3 { 23 23 T x, y, z; … … 25 25 } 26 26 27 forall ( otypeT) {27 forall (T) { 28 28 static inline { 29 29 … … 288 288 } 289 289 290 forall( dtype ostype, otypeT | writeable(T, ostype)) {290 forall(ostype &, T | writeable(T, ostype)) { 291 291 ostype & ?|?(ostype & os, vec3(T) v) with (v) { 292 292 return os | '<' | x | ',' | y | ',' | z | '>'; -
libcfa/src/vec/vec4.hfa
r467c8b7 rc08c3cf 19 19 #include "vec.hfa" 20 20 21 forall ( otypeT) {21 forall (T) { 22 22 struct vec4 { 23 23 T x, y, z, w; … … 25 25 } 26 26 27 forall ( otypeT) {27 forall (T) { 28 28 static inline { 29 29 … … 283 283 } 284 284 285 forall( dtype ostype, otypeT | writeable(T, ostype)) {285 forall(ostype &, T | writeable(T, ostype)) { 286 286 ostype & ?|?(ostype & os, vec4(T) v) with (v) { 287 287 return os | '<' | x | ',' | y | ',' | z | ',' | w | '>'; -
src/Parser/parser.yy
r467c8b7 rc08c3cf 2441 2441 type_parameter: // CFA 2442 2442 type_class identifier_or_type_name 2443 { typedefTable.addToScope( *$2, TYPEDEFname, "9" ); } 2443 { typedefTable.addToScope( *$2, TYPEDEFname, "9" ); 2444 if ( $1 == TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated" ); } 2445 if ( $1 == TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated" ); } 2446 if ( $1 == TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated" ); } 2447 } 2444 2448 type_initializer_opt assertion_list_opt 2445 2449 { $$ = DeclarationNode::newTypeParam( $1, $2 )->addTypeInitializer( $4 )->addAssertions( $5 ); } -
tests/avltree/avl-private.cfa
r467c8b7 rc08c3cf 11 11 // an AVL tree's height is easy to compute 12 12 // just follow path with the larger balance 13 forall( otype K | Comparable(K), otypeV)13 forall(K | Comparable(K), V) 14 14 int height(tree(K, V) * t){ 15 15 int helper(tree(K, V) * t, int ht){ … … 27 27 } 28 28 29 forall( otype K | Comparable(K), otypeV)29 forall(K | Comparable(K), V) 30 30 int calcBalance(tree(K, V) * t){ 31 31 int l = height(t->left); … … 36 36 37 37 // re-establish the link between parent and child 38 forall( otype K | Comparable(K), otypeV)38 forall(K | Comparable(K), V) 39 39 void relinkToParent(tree(K, V) * t){ 40 40 tree(K, V) * parent = t->parent; // FIX ME!! … … 49 49 50 50 // rotate left from t 51 forall( otype K | Comparable(K), otypeV)51 forall(K | Comparable(K), V) 52 52 tree(K, V) * rotateLeft(tree(K, V) * t){ 53 53 tree(K, V) * newRoot = t->right; … … 68 68 69 69 // rotate right from t 70 forall( otype K | Comparable(K), otypeV)70 forall(K | Comparable(K), V) 71 71 tree(K, V) * rotateRight(tree(K, V) * t){ 72 72 tree(K, V) * newRoot = t->left; … … 87 87 88 88 // balances a node that has balance factor -2 or 2 89 forall( otype K | Comparable(K), otypeV)89 forall(K | Comparable(K), V) 90 90 tree(K, V) * fix(tree(K, V) * t){ 91 91 // ensure that t's balance factor is one of … … 113 113 114 114 // attempt to fix the tree, if necessary 115 forall( otype K | Comparable(K), otypeV)115 forall(K | Comparable(K), V) 116 116 tree(K, V) * tryFix(tree(K, V) * t){ 117 117 int b = calcBalance(t); … … 126 126 127 127 // sets parent field of c to be p 128 forall( otype K | Comparable(K), otypeV)128 forall(K | Comparable(K), V) 129 129 void setParent(tree(K, V) * c, tree(K, V) * p){ 130 130 if (! empty(c)){ -
tests/avltree/avl-private.h
r467c8b7 rc08c3cf 5 5 6 6 // attempt to fix the tree, if necessary 7 forall( otype K | Comparable(K), otypeV)7 forall(K | Comparable(K), V) 8 8 tree(K, V) * tryFix(tree(K, V) * t); 9 9 10 10 // sets parent field of c to be p 11 forall( otype K | Comparable(K), otypeV)11 forall(K | Comparable(K), V) 12 12 void setParent(tree(K, V) * c, tree(K, V) * p); 13 13 14 forall( otype K | Comparable(K), otypeV)14 forall(K | Comparable(K), V) 15 15 int height(tree(K, V) * t); -
tests/avltree/avl.h
r467c8b7 rc08c3cf 9 9 // #include <lib.h> 10 10 11 trait Comparable( otypeT) {11 trait Comparable(T) { 12 12 int ?<?(T, T); 13 13 }; 14 14 15 forall( otypeT | Comparable(T))15 forall(T | Comparable(T)) 16 16 int ?==?(T t1, T t2); 17 17 18 forall( otypeT | Comparable(T))18 forall(T | Comparable(T)) 19 19 int ?>?(T t1, T t2); 20 20 … … 41 41 42 42 // temporary: need forward decl to get around typedef problem 43 forall( otype K | Comparable(K), otypeV)43 forall(K | Comparable(K), V) 44 44 struct tree; 45 45 46 forall( otype K | Comparable(K), otypeV)46 forall(K | Comparable(K), V) 47 47 struct tree { 48 48 K key; … … 54 54 }; 55 55 56 forall( otype K | Comparable(K), otypeV)56 forall(K | Comparable(K), V) 57 57 void ?{}(tree(K, V) &t, K key, V value); 58 58 59 forall( otype K | Comparable(K), otypeV)59 forall(K | Comparable(K), V) 60 60 void ^?{}(tree(K, V) & t); 61 61 62 forall( otype K | Comparable(K), otypeV)62 forall(K | Comparable(K), V) 63 63 tree(K, V) * create(K key, V value); 64 64 65 forall( otype K | Comparable(K), otypeV)65 forall(K | Comparable(K), V) 66 66 V * find(tree(K, V) * t, K key); 67 67 68 forall( otype K | Comparable(K), otypeV)68 forall(K | Comparable(K), V) 69 69 int empty(tree(K, V) * t); 70 70 71 71 // returns the root of the tree 72 forall( otype K | Comparable(K), otypeV)72 forall(K | Comparable(K), V) 73 73 int insert(tree(K, V) ** t, K key, V value); 74 74 75 forall( otype K | Comparable(K), otypeV)75 forall(K | Comparable(K), V) 76 76 int remove(tree(K, V) ** t, K key); 77 77 78 forall( otype K | Comparable(K), otypeV)78 forall(K | Comparable(K), V) 79 79 void copy(tree(K, V) * src, tree(K, V) ** ret); 80 80 81 forall( otype K | Comparable(K), otypeV)81 forall(K | Comparable(K), V) 82 82 void for_each(tree(K, V) * t, void (*func)(V)); 83 83 -
tests/avltree/avl0.cfa
r467c8b7 rc08c3cf 1 1 #include "avl.h" 2 2 3 forall( otypeT | Comparable(T))3 forall(T | Comparable(T)) 4 4 int ?==?(T t1, T t2) { 5 5 return !(t1 < t2) && !(t2 < t1); 6 6 } 7 7 8 forall( otypeT | Comparable(T))