Changeset 2dcd80a for libcfa/src
- Timestamp:
- Dec 14, 2022, 12:23:42 PM (17 months ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- 441a6a7
- Parents:
- 7d9598d (diff), d8bdf13 (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. - Location:
- libcfa/src
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/bits/random.hfa
r7d9598d r2dcd80a 10 10 // Created On : Fri Jan 14 07:18:11 2022 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jan 14 07:18:58 202213 // Update Count : 1 12 // Last Modified On : Sun Dec 11 18:43:58 2022 13 // Update Count : 171 14 14 // 15 15 … … 18 18 #include <stdint.h> 19 19 20 // Pipelined to allow out-of-order overlap with reduced dependencies. Critically, the current random state is returned 21 // (copied), and then compute and store the next random value. 22 23 #if defined(__SIZEOF_INT128__) 24 //-------------------------------------------------- 20 #define GLUE2( x, y ) x##y 21 #define GLUE( x, y ) GLUE2( x, y ) 22 23 // Set default PRNG for architecture size. 24 #ifdef __x86_64__ // 64-bit architecture 25 // 64-bit generators 26 #define LEHMER64 27 //#define XORSHIFT_12_25_27 28 //#define XOSHIRO256PP 29 //#define KISS_64 30 31 // 32-bit generators 32 #define XORSHIFT_6_21_7 33 //#define XOSHIRO128PP 34 #else // 32-bit architecture 35 // 64-bit generators 36 #define XORSHIFT_13_7_17 37 38 // 32-bit generators 39 #define XORSHIFT_6_21_7 40 #endif // __x86_64__ 41 42 // Define C/CFA PRNG name and random-state. 43 44 // SKULLDUGGERY: typedefs name struct and typedef with the same name to deal with CFA typedef numbering problem. 45 46 #ifdef XOSHIRO256PP 47 #define PRNG_NAME_64 xoshiro256pp 48 #define PRNG_STATE_64_T GLUE(PRNG_NAME_64,_t) 49 typedef struct PRNG_STATE_64_T { uint64_t s[4]; } PRNG_STATE_64_T; 50 #endif // XOSHIRO256PP 51 52 #ifdef XOSHIRO128PP 53 #define PRNG_NAME_32 xoshiro128pp 54 #define PRNG_STATE_32_T GLUE(PRNG_NAME_32,_t) 55 typedef struct PRNG_STATE_32_T { uint32_t s[4]; } PRNG_STATE_32_T; 56 #endif // XOSHIRO128PP 57 58 #ifdef LEHMER64 59 #define PRNG_NAME_64 lehmer64 60 #define PRNG_STATE_64_T __uint128_t 61 #endif // LEHMER64 62 63 #ifdef WYHASH64 64 #define PRNG_NAME_64 wyhash64 65 #define PRNG_STATE_64_T uint64_t 66 #endif // LEHMER64 67 68 #ifdef XORSHIFT_13_7_17 69 #define PRNG_NAME_64 xorshift_13_7_17 70 #define PRNG_STATE_64_T uint64_t 71 #endif // XORSHIFT_13_7_17 72 73 #ifdef XORSHIFT_6_21_7 74 #define PRNG_NAME_32 xorshift_6_21_7 75 #define PRNG_STATE_32_T uint32_t 76 #endif // XORSHIFT_6_21_7 77 78 #ifdef XORSHIFT_12_25_27 79 #define PRNG_NAME_64 xorshift_12_25_27 80 #define PRNG_STATE_64_T uint64_t 81 #endif // XORSHIFT_12_25_27 82 83 #ifdef KISS_64 84 #define PRNG_NAME_64 kiss_64 85 #define PRNG_STATE_64_T GLUE(PRNG_NAME_64,_t) 86 typedef struct PRNG_STATE_64_T { uint64_t z, w, jsr, jcong; } PRNG_STATE_64_T; 87 #endif // KISS_^64 88 89 #ifdef XORWOW 90 #define PRNG_NAME_32 xorwow 91 #define PRNG_STATE_32_T GLUE(PRNG_NAME_32,_t) 92 typedef struct PRNG_STATE_32_T { uint32_t a, b, c, d, counter; } PRNG_STATE_32_T; 93 #endif // XOSHIRO128PP 94 95 #define PRNG_SET_SEED_64 GLUE(PRNG_NAME_64,_set_seed) 96 #define PRNG_SET_SEED_32 GLUE(PRNG_NAME_32,_set_seed) 97 98 99 // Default PRNG used by runtime. 100 #ifdef __x86_64__ // 64-bit architecture 101 #define PRNG_NAME PRNG_NAME_64 102 #define PRNG_STATE_T PRNG_STATE_64_T 103 #else // 32-bit architecture 104 #define PRNG_NAME PRNG_NAME_32 105 #define PRNG_STATE_T PRNG_STATE_32_T 106 #endif // __x86_64__ 107 108 #define PRNG_SET_SEED GLUE(PRNG_NAME,_set_seed) 109 110 111 // ALL PRNG ALGORITHMS ARE OPTIMIZED SO THAT THE PRNG LOGIC CAN HAPPEN IN PARALLEL WITH THE USE OF THE RESULT. 112 // Therefore, the set_seed routine primes the PRNG by calling it with the state so the seed is not return as the 113 // first random value. 114 115 #ifdef __cforall // don't include in C code (invoke.h) 116 117 // https://prng.di.unimi.it/xoshiro256starstar.c 118 // 119 // This is xoshiro256++ 1.0, one of our all-purpose, rock-solid generators. It has excellent (sub-ns) speed, a state 120 // (256 bits) that is large enough for any parallel application, and it passes all tests we are aware of. 121 // 122 // For generating just floating-point numbers, xoshiro256+ is even faster. 123 // 124 // The state must be seeded so that it is not everywhere zero. If you have a 64-bit seed, we suggest to seed a 125 // splitmix64 generator and use its output to fill s. 126 127 #ifndef XOSHIRO256PP 128 typedef struct xoshiro256pp_t { uint64_t s[4]; } xoshiro256pp_t; 129 #endif // ! XOSHIRO256PP 130 131 static inline uint64_t xoshiro256pp( xoshiro256pp_t & rs ) with(rs) { 132 inline uint64_t rotl(const uint64_t x, int k) { 133 return (x << k) | (x >> (64 - k)); 134 } // rotl 135 136 const uint64_t result = rotl( s[0] + s[3], 23 ) + s[0]; 137 const uint64_t t = s[1] << 17; 138 139 s[2] ^= s[0]; 140 s[3] ^= s[1]; 141 s[1] ^= s[2]; 142 s[0] ^= s[3]; 143 s[2] ^= t; 144 s[3] = rotl( s[3], 45 ); 145 return result; 146 } // xoshiro256pp 147 148 static inline void xoshiro256pp_set_seed( xoshiro256pp_t & state, uint64_t seed ) { 149 state = (xoshiro256pp_t){ {seed, seed, seed, seed} }; 150 xoshiro256pp( state ); 151 } // xoshiro256pp_set_seed 152 153 // https://prng.di.unimi.it/xoshiro128plusplus.c 154 // 155 // This is xoshiro128++ 1.0, one of our 32-bit all-purpose, rock-solid generators. It has excellent speed, a state size 156 // (128 bits) that is large enough for mild parallelism, and it passes all tests we are aware of. 157 // 158 // For generating just single-precision (i.e., 32-bit) floating-point numbers, xoshiro128+ is even faster. 159 // 160 // The state must be seeded so that it is not everywhere zero. 161 162 #ifndef XOSHIRO128PP 163 typedef struct xoshiro128pp_t { uint32_t s[4]; } xoshiro128pp_t; 164 #endif // ! XOSHIRO128PP 165 166 static inline uint32_t xoshiro128pp( xoshiro128pp_t & rs ) with(rs) { 167 inline uint32_t rotl( const uint32_t x, int k ) { 168 return (x << k) | (x >> (32 - k)); 169 } // rotl 170 171 const uint32_t result = rotl( s[0] + s[3], 7 ) + s[0]; 172 const uint32_t t = s[1] << 9; 173 174 s[2] ^= s[0]; 175 s[3] ^= s[1]; 176 s[1] ^= s[2]; 177 s[0] ^= s[3]; 178 s[2] ^= t; 179 s[3] = rotl( s[3], 11 ); 180 return result; 181 } // xoshiro128pp 182 183 static inline void xoshiro128pp_set_seed( xoshiro128pp_t & state, uint32_t seed ) { 184 state = (xoshiro128pp_t){ {seed, seed, seed, seed} }; 185 xoshiro128pp( state ); // prime 186 } // xoshiro128pp_set_seed 187 188 #ifdef __SIZEOF_INT128__ 189 // Pipelined to allow out-of-order overlap with reduced dependencies. Critically, the current random state is 190 // returned (copied), and then compute and store the next random value. 191 //-------------------------------------------------- 25 192 static inline uint64_t lehmer64( __uint128_t & state ) { 26 193 __uint128_t ret = state; 27 194 state *= 0xda942042e4dd58b5; 28 195 return ret >> 64; 29 } 30 31 //-------------------------------------------------- 196 } // lehmer64 197 198 static inline void lehmer64_set_seed( __uint128_t & state, uint64_t seed ) { 199 state = seed; 200 lehmer64( state ); 201 } // lehmer64_set_seed 202 203 //-------------------------------------------------- 32 204 static inline uint64_t wyhash64( uint64_t & state ) { 33 state += 0x60bee2bee120fc15; 205 uint64_t ret = state; 206 state += 0x_60be_e2be_e120_fc15; 34 207 __uint128_t tmp; 35 tmp = (__uint128_t) state * 0xa3b195354a39b70d;208 tmp = (__uint128_t) ret * 0x_a3b1_9535_4a39_b70d; 36 209 uint64_t m1 = (tmp >> 64) ^ tmp; 37 tmp = (__uint128_t)m1 * 0x 1b03738712fad5c9;210 tmp = (__uint128_t)m1 * 0x_1b03_7387_12fa_d5c9; 38 211 uint64_t m2 = (tmp >> 64) ^ tmp; 39 212 return m2; 40 } 41 #endif 213 } // wyhash64 214 215 static inline void wyhash64_set_seed( uint64_t & state, uint64_t seed ) { 216 state = seed; 217 wyhash64( state ); // prime 218 } // wyhash64_set_seed 219 #endif // __SIZEOF_INT128__ 42 220 43 221 //-------------------------------------------------- … … 48 226 state ^= state << 17; 49 227 return ret; 50 } 51 52 //-------------------------------------------------- 228 } // xorshift_13_7_17 229 230 static inline void xorshift_13_7_17_set_seed( uint64_t & state, uint64_t seed ) { 231 state = seed; 232 xorshift_13_7_17( state ); // prime 233 } // xorshift_13_7_17_set_seed 234 235 //-------------------------------------------------- 236 // Marsaglia shift-XOR PRNG with thread-local state 237 // Period is 4G-1 238 // 0 is absorbing and must be avoided 239 // Low-order bits are not particularly random 53 240 static inline uint32_t xorshift_6_21_7( uint32_t & state ) { 54 241 uint32_t ret = state; … … 59 246 } // xorshift_6_21_7 60 247 61 //-------------------------------------------------- 62 typedef struct { 63 uint32_t a, b, c, d; 64 uint32_t counter; 65 } xorwow__state_t; 66 67 // The state array must be initialized to not be all zero in the first four words. 68 static inline uint32_t xorwow( xorwow__state_t & state ) { 248 static inline void xorshift_6_21_7_set_seed( uint32_t & state, uint32_t seed ) { 249 state = seed; 250 xorshift_6_21_7( state ); // prime 251 } // xorshift_6_21_7_set_seed 252 253 //-------------------------------------------------- 254 // The state must be seeded with a nonzero value. 255 static inline uint64_t xorshift_12_25_27( uint64_t & state ) { 256 uint64_t ret = state; 257 state ^= state >> 12; 258 state ^= state << 25; 259 state ^= state >> 27; 260 return ret * 0x_2545_F491_4F6C_DD1D; 261 } // xorshift_12_25_27 262 263 static inline void xorshift_12_25_27_set_seed( uint64_t & state, uint64_t seed ) { 264 state = seed; 265 xorshift_12_25_27( state ); // prime 266 } // xorshift_12_25_27_set_seed 267 268 //-------------------------------------------------- 269 // The state must be seeded with a nonzero value. 270 #ifndef KISS_64 271 typedef struct kiss_64_t { uint64_t z, w, jsr, jcong; } kiss_64_t; 272 #endif // ! KISS_64 273 274 static inline uint64_t kiss_64( kiss_64_t & state ) with(state) { 275 kiss_64_t ret = state; 276 z = 36969 * (z & 65535) + (z >> 16); 277 w = 18000 * (w & 65535) + (w >> 16); 278 jsr ^= (jsr << 17); 279 jsr ^= (jsr << 13); 280 jsr ^= (jsr << 5); 281 jcong = 69069 * jcong + 1234567; 282 return (((ret.z << 16) + ret.w) ^ ret.jcong) + ret.jsr; 283 } // kiss_64 284 285 static inline void kiss_64_set_seed( kiss_64_t & state, uint64_t seed ) with(state) { 286 z = 1; w = 1; jsr = 4; jcong = seed; 287 kiss_64( state ); // prime 288 } // kiss_64_set_seed 289 290 //-------------------------------------------------- 291 // The state array must be initialized to non-zero in the first four words. 292 #ifndef XORWOW 293 typedef struct xorwow_t { uint32_t a, b, c, d, counter; } xorwow_t; 294 #endif // ! XORWOW 295 296 static inline uint32_t xorwow( xorwow_t & state ) with(state) { 69 297 // Algorithm "xorwow" from p. 5 of Marsaglia, "Xorshift RNGs". 70 uint32_t ret = state.a + state.counter;71 uint32_t t = state.d;72 73 uint32_t const s = state.a;74 state.d = state.c;75 state.c = state.b;76 state.b = s;298 uint32_t ret = a + counter; 299 uint32_t t = d; 300 301 uint32_t const s = a; 302 d = c; 303 c = b; 304 b = s; 77 305 78 306 t ^= t >> 2; 79 307 t ^= t << 1; 80 308 t ^= s ^ (s << 4); 81 state.a = t; 82 83 state.counter += 362437; 309 a = t; 310 counter += 362437; 84 311 return ret; 85 } 86 87 //-------------------------------------------------- 88 static inline uint32_t LCG( uint32_t & state ) { // linear congruential generator 89 uint32_t ret = state; 90 state = 36969 * (state & 65535) + (state >> 16); // 36969 is NOT prime! No not change it! 91 return ret; 92 } // LCG 93 94 //-------------------------------------------------- 312 } // xorwow 313 314 static inline void xorwow_set_seed( xorwow_t & state, uint32_t seed ) { 315 state = (xorwow_t){ seed, seed, seed, seed, 0 }; 316 xorwow( state ); // prime 317 } // xorwow_set_seed 318 319 //-------------------------------------------------- 320 // Used in __tls_rand_fwd 95 321 #define M (1_l64u << 48_l64u) 96 322 #define A (25214903917_l64u) … … 103 329 state = (A * state + C) & (M - 1); 104 330 return state >> D; 105 } 331 } // LCGBI_fwd 106 332 107 333 static inline uint32_t LCGBI_bck( uint64_t & state ) { … … 109 335 state = AI * (state - C) & (M - 1); 110 336 return r; 111 } 337 } // LCGBI_bck 112 338 113 339 #undef M … … 116 342 #undef C 117 343 #undef D 344 345 #endif // __cforall -
libcfa/src/concurrency/invoke.h
r7d9598d r2dcd80a 10 10 // Created On : Tue Jan 17 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Jan 9 19:06:45202213 // Update Count : 4812 // Last Modified On : Tue Nov 29 20:42:21 2022 13 // Update Count : 56 14 14 // 15 15 … … 17 17 #include "bits/defs.hfa" 18 18 #include "bits/locks.hfa" 19 #include "bits/random.hfa" 19 20 #include "kernel/fwd.hfa" 20 21 … … 222 223 struct processor * last_proc; 223 224 224 uint32_t random_state;// fast random numbers225 PRNG_STATE_T random_state; // fast random numbers 225 226 226 227 #if defined( __CFA_WITH_VERIFY__ ) -
libcfa/src/concurrency/kernel.cfa
r7d9598d r2dcd80a 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Aug 31 07:08:20 202013 // Update Count : 7 112 // Last Modified On : Wed Nov 30 18:14:08 2022 13 // Update Count : 76 14 14 // 15 15 … … 151 151 // Because of a bug, we couldn't initialized the seed on construction 152 152 // Do it here 153 __cfaabi_tls.rand_seed ^= rdtscl();153 PRNG_SET_SEED( __cfaabi_tls.random_state, rdtscl() ); 154 154 __cfaabi_tls.ready_rng.fwd_seed = 25214903917_l64u * (rdtscl() ^ (uintptr_t)&runner); 155 155 __tls_rand_advance_bck(); -
libcfa/src/concurrency/kernel/fwd.hfa
r7d9598d r2dcd80a 46 46 } preemption_state; 47 47 48 #if defined(__SIZEOF_INT128__) 49 __uint128_t rand_seed; 50 #else 51 uint64_t rand_seed; 52 #endif 48 PRNG_STATE_T random_state; 49 53 50 struct { 54 51 uint64_t fwd_seed; … … 57 54 58 55 struct __stats_t * volatile this_stats; 59 60 56 61 57 #ifdef __CFA_WITH_VERIFY__ … … 76 72 #define publicTLS_get( member ) ((typeof(__cfaabi_tls.member))__cfatls_get( __builtin_offsetof(KernelThreadData, member) )) 77 73 78 static inline uint64_t __tls_rand() { 79 return 80 #if defined(__SIZEOF_INT128__) 81 lehmer64( kernelTLS().rand_seed ); 82 #else 83 xorshift_13_7_17( kernelTLS().rand_seed ); 84 #endif 74 static inline 75 #ifdef __x86_64__ // 64-bit architecture 76 uint64_t 77 #else // 32-bit architecture 78 uint32_t 79 #endif // __x86_64__ 80 __tls_rand() { 81 return PRNG_NAME( kernelTLS().random_state ); 85 82 } 86 83 … … 120 117 121 118 // Yield: yield N times 122 static inline void yield( unsignedtimes ) {119 static inline void yield( size_t times ) { 123 120 for( times ) { 124 121 yield(); -
libcfa/src/concurrency/kernel/startup.cfa
r7d9598d r2dcd80a 39 39 #include "limits.hfa" 40 40 #include "math.hfa" 41 #include "bits/random.hfa" // prng 41 42 42 43 #define CFA_PROCESSOR_USE_MMAP 0 … … 107 108 extern void __wake_proc(processor *); 108 109 extern int cfa_main_returned; // from interpose.cfa 109 uint32_t __global_random_prime = 4_294_967_291u, __global_random_mask = false; 110 size_t __global_random_prime = 4_294_967_291u; 111 bool __global_random_mask = false; 110 112 111 113 //----------------------------------------------------------------------------- … … 133 135 // Global state 134 136 __thread struct KernelThreadData __cfaabi_tls __attribute__ ((tls_model ( "initial-exec" ))) @= { 135 NULL,// cannot use 0p136 NULL,137 false,138 { 1, false,false },139 0,140 { 0,0 },141 NULL,137 .this_thread : NULL, // cannot use 0p 138 .this_processor : NULL, 139 .sched_lock : false, 140 .preemption_state : { .disable_count : 1, .enabled : false, .in_progress : false }, 141 // random_state uninitialized 142 .ready_rng : { .fwd_seed : 0, .bck_seed : 0 }, 143 .this_stats : NULL, 142 144 #ifdef __CFA_WITH_VERIFY__ 143 false,144 0,145 .in_sched_lock : false, 146 .sched_id : 0, 145 147 #endif 146 148 }; … … 513 515 rdy_link.next = 0p; 514 516 rdy_link.ts = MAX; 517 user_link.next = 0p; 518 user_link.prev = 0p; 519 cltr_link.next = 0p; 520 cltr_link.prev = 0p; 515 521 preferred = ready_queue_new_preferred(); 516 522 last_proc = 0p; 517 random_state = __global_random_mask ? __global_random_prime : __global_random_prime ^ rdtscl();523 PRNG_SET_SEED( random_state, __global_random_mask ? __global_random_prime : __global_random_prime ^ rdtscl() ); 518 524 #if defined( __CFA_WITH_VERIFY__ ) 519 525 executing = 0p; -
libcfa/src/concurrency/stats.cfa
r7d9598d r2dcd80a 48 48 stats->io.submit.eagr = 0; 49 49 stats->io.submit.nblk = 0; 50 stats->io.submit.extr = 0; 50 51 stats->io.flush.external = 0; 52 stats->io.flush.signal = 0; 51 53 stats->io.flush.dirty = 0; 52 54 stats->io.flush.full = 0; … … 120 122 tally_one( &cltr->io.submit.eagr , &proc->io.submit.eagr ); 121 123 tally_one( &cltr->io.submit.nblk , &proc->io.submit.nblk ); 124 tally_one( &cltr->io.submit.extr , &proc->io.submit.extr ); 122 125 tally_one( &cltr->io.flush.external , &proc->io.flush.external ); 126 tally_one( &cltr->io.flush.signal , &proc->io.flush.signal ); 123 127 tally_one( &cltr->io.flush.dirty , &proc->io.flush.dirty ); 124 128 tally_one( &cltr->io.flush.full , &proc->io.flush.full ); … … 199 203 if(io.alloc.slow) { 200 204 double avgfasts = (100.0 * (double)io.submit.fast) / total_submits; 201 sstr | "fast," | eng3(io.submit.slow) | "slow (" | ws(3, 3, avgfasts) | "%) " | nonl;205 sstr | "fast," | eng3(io.submit.slow) | "slow (" | ws(3, 3, avgfasts) | "%)," | eng3(io.submit.extr) | "external" | nonl; 202 206 } 203 207 sstr | " - eager" | eng3(io.submit.eagr) | nonl; … … 217 221 | " - cmp " | eng3(io.calls.locked) | "locked, " | eng3(io.calls.helped) | "helped" 218 222 | " - " | eng3(io.calls.errors.busy) | " EBUSY"; 219 sstr | " - sub: " | eng3(io.flush.full) | "full, " | eng3(io.flush.dirty) | "drty, " | eng3(io.flush.idle) | "idle, " | eng3(io.flush.eager) | "eagr, " | eng3(io.flush.external) | "ext";223 sstr | " - sub: " | eng3(io.flush.full) | "full, " | eng3(io.flush.dirty) | "drty, " | eng3(io.flush.idle) | "idle, " | eng3(io.flush.eager) | "eagr, " | eng3(io.flush.external) | '/' | eng3(io.flush.signal) | "ext"; 220 224 sstr | "- ops blk: " 221 225 | " sk rd: " | eng3(io.ops.sockread) | "epll: " | eng3(io.ops.epllread) -
libcfa/src/concurrency/stats.hfa
r7d9598d r2dcd80a 94 94 volatile uint64_t eagr; 95 95 volatile uint64_t nblk; 96 volatile uint64_t extr; 96 97 } submit; 97 98 struct { 98 99 volatile uint64_t external; 100 volatile uint64_t signal; 99 101 volatile uint64_t dirty; 100 102 volatile uint64_t full; -
libcfa/src/concurrency/thread.cfa
r7d9598d r2dcd80a 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : S at Feb 12 15:24:18202213 // Update Count : 6612 // Last Modified On : Sun Dec 11 20:56:54 2022 13 // Update Count : 102 14 14 // 15 15 … … 26 26 #include "invoke.h" 27 27 28 extern uint32_t __global_random_seed, __global_random_prime, __global_random_mask; 28 extern size_t __global_random_seed; 29 extern size_t __global_random_prime; 30 extern bool __global_random_mask; 29 31 30 32 #pragma GCC visibility push(default) … … 46 48 rdy_link.next = 0p; 47 49 rdy_link.ts = MAX; 50 user_link.next = 0p; 51 user_link.prev = 0p; 52 cltr_link.next = 0p; 53 cltr_link.prev = 0p; 48 54 preferred = ready_queue_new_preferred(); 49 55 last_proc = 0p; 50 random_state = __global_random_mask ? __global_random_prime : __global_random_prime ^ rdtscl();56 PRNG_SET_SEED( random_state, __global_random_mask ? __global_random_prime : __global_random_prime ^ rdtscl() ); 51 57 #if defined( __CFA_WITH_VERIFY__ ) 52 58 executing = 0p; … … 176 182 //----------------------------------------------------------------------------- 177 183 bool migrate( thread$ * thrd, struct cluster & cl ) { 178 179 184 monitor$ * tmon = get_monitor(thrd); 180 185 monitor$ * __monitors[] = { tmon }; 181 186 monitor_guard_t __guard = { __monitors, 1 }; 182 183 184 187 { 185 188 // if nothing needs to be done, return false … … 221 224 222 225 //----------------------------------------------------------------------------- 223 #define GENERATOR LCG 224 225 void set_seed( uint32_t seed ) { 226 uint32_t & state = active_thread()->random_state; 227 state = __global_random_seed = seed; 228 GENERATOR( state ); 229 __global_random_prime = state; 226 227 void set_seed( size_t seed ) { 228 PRNG_STATE_T & state = active_thread()->random_state; 229 PRNG_SET_SEED( state, seed ); 230 __global_random_seed = seed; 231 __global_random_prime = seed; 230 232 __global_random_mask = true; 231 233 } // set_seed 232 234 233 uint32_t prng( void ) { // [0,UINT_MAX] 234 uint32_t & state = active_thread()->random_state; 235 return GENERATOR( state ); 235 size_t prng( void ) { // [0,UINT_MAX] 236 return PRNG_NAME( active_thread()->random_state ); 236 237 } // prng 237 238 -
libcfa/src/concurrency/thread.hfa
r7d9598d r2dcd80a 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Feb 11 16:34:07202213 // Update Count : 2012 // Last Modified On : Tue Nov 22 22:18:34 2022 13 // Update Count : 35 14 14 // 15 15 … … 23 23 #include "monitor.hfa" 24 24 #include "exception.hfa" 25 #include "bits/random.hfa" 25 26 26 27 //----------------------------------------------------------------------------- … … 141 142 //---------- 142 143 // prng 144 void set_seed( size_t seed ); 143 145 static inline { 144 uint32_t prng( thread$ & th ) __attribute__(( warn_unused_result )) { return LCG( th.random_state ); } // [0,UINT_MAX]145 uint32_t prng( thread$ & th, uint32_t u ) __attribute__(( warn_unused_result )) { return prng( th ) % u; } // [0,u)146 uint32_t prng( thread$ & th, uint32_t l, uint32_t u ) __attribute__(( warn_unused_result )) { return prng( th, u - l + 1 ) + l; } // [l,u]146 size_t prng( thread$ & th ) __attribute__(( warn_unused_result )) { return PRNG_NAME( th.random_state ); } // [0,UINT_MAX] 147 size_t prng( thread$ & th, size_t u ) __attribute__(( warn_unused_result )) { return prng( th ) % u; } // [0,u) 148 size_t prng( thread$ & th, size_t l, size_t u ) __attribute__(( warn_unused_result )) { return prng( th, u - l + 1 ) + l; } // [l,u] 147 149 forall( T & | is_thread(T) ) { 148 uint32_t prng( T & th ) __attribute__(( warn_unused_result )) { return prng( (thread &)th ); } // [0,UINT_MAX]149 uint32_t prng( T & th, uint32_t u ) __attribute__(( warn_unused_result )) { return prng( th ) % u; } // [0,u)150 uint32_t prng( T & th, uint32_t l, uint32_t u ) __attribute__(( warn_unused_result )) { return prng( th, u - l + 1 ) + l; } // [l,u]150 size_t prng( T & th ) __attribute__(( warn_unused_result )) { return prng( (thread &)th ); } // [0,UINT_MAX] 151 size_t prng( T & th, size_t u ) __attribute__(( warn_unused_result )) { return prng( th ) % u; } // [0,u) 152 size_t prng( T & th, size_t l, size_t u ) __attribute__(( warn_unused_result )) { return prng( th, u - l + 1 ) + l; } // [l,u] 151 153 } // distribution 152 154 } // distribution -
libcfa/src/exception.h
r7d9598d r2dcd80a 143 143 } 144 144 145 forall(exceptT &, virtualT & | is_ exception(exceptT, virtualT))145 forall(exceptT &, virtualT & | is_termination_exception(exceptT, virtualT)) 146 146 static inline void defaultResumptionHandler(exceptT & except) { 147 147 throw except; -
libcfa/src/startup.cfa
r7d9598d r2dcd80a 10 10 // Created On : Tue Jul 24 16:21:57 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Oct 6 13:51:57202213 // Update Count : 5712 // Last Modified On : Mon Dec 5 11:41:58 2022 13 // Update Count : 73 14 14 // 15 15 … … 18 18 #include <stdlib.h> // getenv 19 19 #include "bits/defs.hfa" // rdtscl 20 #include "bits/random.hfa" // rdtscl 20 21 #include "startup.hfa" 21 22 22 extern uint32_t __global_random_seed;// sequential/concurrent23 extern uint32_t __global_random_state;// sequential23 extern size_t __global_random_seed; // sequential/concurrent 24 extern PRNG_STATE_T __global_random_state; // sequential 24 25 25 26 extern "C" { … … 68 69 void __cfaabi_core_startup( void ) __attribute__(( constructor( STARTUP_PRIORITY_CORE ) )); 69 70 void __cfaabi_core_startup( void ) { 70 __global_random_state = __global_random_seed = rdtscl(); 71 __global_random_seed = rdtscl(); 72 PRNG_SET_SEED( __global_random_state, __global_random_seed ); 73 71 74 __cfaabi_interpose_startup(); 72 75 __cfaabi_device_startup(); -
libcfa/src/stdlib.cfa
r7d9598d r2dcd80a 10 10 // Created On : Thu Jan 28 17:10:29 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Aug 25 22:41:14202213 // Update Count : 6 0412 // Last Modified On : Fri Dec 9 15:11:30 2022 13 // Update Count : 631 14 14 // 15 15 … … 225 225 //--------------------------------------- 226 226 227 #define GENERATOR LCG228 229 227 // would be cool to make hidden but it's needed for libcfathread 230 __attribute__((visibility("default"))) uint32_t __global_random_seed; // sequential/concurrent 231 __attribute__((visibility("hidden"))) uint32_t __global_random_state; // sequential only 232 233 void set_seed( PRNG & prng, uint32_t seed_ ) with( prng ) { state = seed = seed_; GENERATOR( state ); } // set seed 234 235 void set_seed( uint32_t seed ) { __global_random_state = __global_random_seed = seed; GENERATOR( __global_random_state ); } 236 uint32_t get_seed() { return __global_random_seed; } 237 uint32_t prng( void ) { return GENERATOR( __global_random_state ); } // [0,UINT_MAX] 228 __attribute__((visibility("default"))) size_t __global_random_seed; // sequential/concurrent 229 __attribute__((visibility("hidden"))) PRNG_STATE_T __global_random_state; // sequential only 230 231 void set_seed( size_t seed ) { 232 __global_random_seed = seed; 233 PRNG_SET_SEED( __global_random_state, seed ); 234 } // set_seed 235 236 size_t get_seed() { return __global_random_seed; } 237 size_t prng( void ) { return PRNG_NAME( __global_random_state ); } // [0,UINT_MAX] 238 238 239 239 //--------------------------------------- -
libcfa/src/stdlib.hfa
r7d9598d r2dcd80a 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Aug 25 18:07:06202213 // Update Count : 64512 // Last Modified On : Sun Dec 11 18:25:53 2022 13 // Update Count : 765 14 14 // 15 15 … … 404 404 // calls( sprng ); 405 405 406 struct PRNG { 406 trait basic_prng( PRNG &, R ) { 407 void set_seed( PRNG & prng, R seed ); // set seed 408 R get_seed( PRNG & prng ); // get seed 409 R prng( PRNG & prng ); 410 void ?{}( PRNG & prng ); // random seed 411 void ?{}( PRNG & prng, R seed ); // fixed seed 412 }; // basic_prng 413 414 static inline forall( PRNG &, R | basic_prng( PRNG, R ) | { R ?%?( R, R ); } ) { 415 R prng( PRNG & prng, R u ) { return prng( prng ) % u; } // [0,u) 416 } 417 static inline forall( PRNG &, R | basic_prng( PRNG, R ) | { R ?+?( R, R ); R ?-?( R, R ); R ?%?( R, R ); void ?{}( R &, one_t ); } ) { 418 R prng( PRNG & prng, R l, R u ) { return prng( prng, u - l + (R){1} ) + l; } // [l,u] 419 } 420 421 struct PRNG32 { 407 422 uint32_t callcnt; // call count 408 423 uint32_t seed; // current seed 409 uint32_t state;// random state424 PRNG_STATE_32_T state; // random state 410 425 }; // PRNG 411 426 412 void set_seed( PRNG & prng, uint32_t seed_ ); 413 static inline { 414 void ?{}( PRNG & prng ) with( prng ) { callcnt = 0; set_seed( prng, rdtscl() ); } // random seed 415 void ?{}( PRNG & prng, uint32_t seed ) with( prng ) { callcnt = 0; set_seed( prng, seed ); } // fixed seed 416 uint32_t get_seed( PRNG & prng ) __attribute__(( warn_unused_result )) with( prng ) { return seed; } // get seed 417 uint32_t prng( PRNG & prng ) __attribute__(( warn_unused_result )) with( prng ) { callcnt += 1; return LCG( state ); } // [0,UINT_MAX] 418 uint32_t prng( PRNG & prng, uint32_t u ) __attribute__(( warn_unused_result )) { return prng( prng ) % u; } // [0,u) 419 uint32_t prng( PRNG & prng, uint32_t l, uint32_t u ) __attribute__(( warn_unused_result )) { return prng( prng, u - l + 1 ) + l; } // [l,u] 420 uint32_t calls( PRNG & prng ) __attribute__(( warn_unused_result )) with( prng ) { return callcnt; } 427 static inline { 428 void set_seed( PRNG32 & prng, uint32_t seed_ ) with( prng ) { seed = seed_; PRNG_SET_SEED_32( state, seed ); } 429 uint32_t get_seed( PRNG32 & prng ) __attribute__(( warn_unused_result )) with( prng ) { return seed; } 430 uint32_t prng( PRNG32 & prng ) __attribute__(( warn_unused_result )) with( prng ) { callcnt += 1; return PRNG_NAME_32( state ); } // [0,UINT_MAX] 431 uint32_t prng( PRNG32 & prng, uint32_t u ) __attribute__(( warn_unused_result )) { return prng( prng ) % u; } // [0,u) 432 uint32_t prng( PRNG32 & prng, uint32_t l, uint32_t u ) __attribute__(( warn_unused_result )) { return prng( prng, u - l + 1 ) + l; } // [l,u] 433 uint32_t calls( PRNG32 & prng ) __attribute__(( warn_unused_result )) with( prng ) { return callcnt; } 434 void ?{}( PRNG32 & prng ) with( prng ) { callcnt = 0; set_seed( prng, rdtscl() ); } // random seed 435 void ?{}( PRNG32 & prng, uint32_t seed ) with( prng ) { callcnt = 0; set_seed( prng, seed ); } // fixed seed 436 } // distribution 437 438 struct PRNG64 { 439 uint64_t callcnt; // call count 440 uint64_t seed; // current seed 441 PRNG_STATE_64_T state; // random state 442 }; // PRNG 443 444 static inline { 445 void set_seed( PRNG64 & prng, uint64_t seed_ ) with( prng ) { seed = seed_; PRNG_SET_SEED_64( state, seed ); } 446 uint64_t get_seed( PRNG64 & prng ) __attribute__(( warn_unused_result )) with( prng ) { return seed; } 447 uint64_t prng( PRNG64 & prng ) __attribute__(( warn_unused_result )) with( prng ) { callcnt += 1; return PRNG_NAME_64( state ); } // [0,UINT_MAX] 448 uint64_t prng( PRNG64 & prng, uint64_t u ) __attribute__(( warn_unused_result )) { return prng( prng ) % u; } // [0,u) 449 uint64_t prng( PRNG64 & prng, uint64_t l, uint64_t u ) __attribute__(( warn_unused_result )) { return prng( prng, u - l + 1 ) + l; } // [l,u] 450 uint64_t calls( PRNG64 & prng ) __attribute__(( warn_unused_result )) with( prng ) { return callcnt; } 451 void ?{}( PRNG64 & prng ) with( prng ) { callcnt = 0; set_seed( prng, rdtscl() ); } // random seed 452 void ?{}( PRNG64 & prng, uint64_t seed ) with( prng ) { callcnt = 0; set_seed( prng, seed ); } // fixed seed 421 453 } // distribution 422 454 … … 435 467 // prng( 5, 21 ); 436 468 437 void set_seed( uint32_t seed_ ) OPTIONAL_THREAD; 438 uint32_t get_seed() __attribute__(( warn_unused_result )); 439 uint32_t prng( void ) __attribute__(( warn_unused_result )) OPTIONAL_THREAD; // [0,UINT_MAX] 440 static inline { 441 uint32_t prng( uint32_t u ) __attribute__(( warn_unused_result )) { return prng() % u; } // [0,u) 442 uint32_t prng( uint32_t l, uint32_t u ) __attribute__(( warn_unused_result )) { return prng( u - l + 1 ) + l; } // [l,u] 469 // Harmonize with concurrency/thread.hfa. 470 void set_seed( size_t seed_ ) OPTIONAL_THREAD; // set global seed 471 size_t get_seed() __attribute__(( warn_unused_result )); // get global seed 472 size_t prng( void ) __attribute__(( warn_unused_result )) OPTIONAL_THREAD; // [0,UINT_MAX] 473 static inline { 474 size_t prng( size_t u ) __attribute__(( warn_unused_result )) { return prng() % u; } // [0,u) 475 size_t prng( size_t l, size_t u ) __attribute__(( warn_unused_result )) { return prng( u - l + 1 ) + l; } // [l,u] 443 476 } // distribution 444 477
Note: See TracChangeset
for help on using the changeset viewer.