Changeset 2dcd80a for libcfa/src


Ignore:
Timestamp:
Dec 14, 2022, 12:23:42 PM (17 months ago)
Author:
caparson <caparson@…>
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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
libcfa/src
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/bits/random.hfa

    r7d9598d r2dcd80a  
    1010// Created On       : Fri Jan 14 07:18:11 2022
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jan 14 07:18:58 2022
    13 // Update Count     : 1
     12// Last Modified On : Sun Dec 11 18:43:58 2022
     13// Update Count     : 171
    1414//
    1515
     
    1818#include <stdint.h>
    1919
    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)
     49typedef 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)
     55typedef 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)
     86typedef 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)
     92typedef 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
     128typedef struct xoshiro256pp_t { uint64_t s[4]; } xoshiro256pp_t;
     129#endif // ! XOSHIRO256PP
     130
     131static 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
     148static 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
     163typedef struct xoshiro128pp_t { uint32_t s[4]; } xoshiro128pp_t;
     164#endif // ! XOSHIRO128PP
     165
     166static 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
     183static 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        //--------------------------------------------------
    25192        static inline uint64_t lehmer64( __uint128_t & state ) {
    26193                __uint128_t ret = state;
    27194                state *= 0xda942042e4dd58b5;
    28195                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        //--------------------------------------------------
    32204        static inline uint64_t wyhash64( uint64_t & state ) {
    33                 state += 0x60bee2bee120fc15;
     205                uint64_t ret = state;
     206                state += 0x_60be_e2be_e120_fc15;
    34207                __uint128_t tmp;
    35                 tmp = (__uint128_t) state * 0xa3b195354a39b70d;
     208                tmp = (__uint128_t) ret * 0x_a3b1_9535_4a39_b70d;
    36209                uint64_t m1 = (tmp >> 64) ^ tmp;
    37                 tmp = (__uint128_t)m1 * 0x1b03738712fad5c9;
     210                tmp = (__uint128_t)m1 * 0x_1b03_7387_12fa_d5c9;
    38211                uint64_t m2 = (tmp >> 64) ^ tmp;
    39212                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__
    42220
    43221//--------------------------------------------------
     
    48226        state ^= state << 17;
    49227        return ret;
    50 }
    51 
    52 //--------------------------------------------------
     228} // xorshift_13_7_17
     229
     230static 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
    53240static inline uint32_t xorshift_6_21_7( uint32_t & state ) {
    54241        uint32_t ret = state;
     
    59246} // xorshift_6_21_7
    60247
    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 ) {
     248static 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.
     255static 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
     263static 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
     271typedef struct kiss_64_t { uint64_t z, w, jsr, jcong; } kiss_64_t;
     272#endif // ! KISS_64
     273
     274static 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
     285static 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
     293typedef struct xorwow_t { uint32_t a, b, c, d, counter; } xorwow_t;
     294#endif // ! XORWOW
     295
     296static inline uint32_t xorwow( xorwow_t & state ) with(state) {
    69297        // 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;
    77305
    78306        t ^= t >> 2;
    79307        t ^= t << 1;
    80308        t ^= s ^ (s << 4);
    81         state.a = t;
    82 
    83         state.counter += 362437;
     309        a = t;
     310        counter += 362437;
    84311        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
     314static 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
    95321#define M  (1_l64u << 48_l64u)
    96322#define A  (25214903917_l64u)
     
    103329        state = (A * state + C) & (M - 1);
    104330        return state >> D;
    105 }
     331} // LCGBI_fwd
    106332
    107333static inline uint32_t LCGBI_bck( uint64_t & state ) {
     
    109335        state = AI * (state - C) & (M - 1);
    110336        return r;
    111 }
     337} // LCGBI_bck
    112338
    113339#undef M
     
    116342#undef C
    117343#undef D
     344
     345#endif // __cforall
  • libcfa/src/concurrency/invoke.h

    r7d9598d r2dcd80a  
    1010// Created On       : Tue Jan 17 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jan  9 19:06:45 2022
    13 // Update Count     : 48
     12// Last Modified On : Tue Nov 29 20:42:21 2022
     13// Update Count     : 56
    1414//
    1515
     
    1717#include "bits/defs.hfa"
    1818#include "bits/locks.hfa"
     19#include "bits/random.hfa"
    1920#include "kernel/fwd.hfa"
    2021
     
    222223                struct processor * last_proc;
    223224
    224                 uint32_t random_state;                                                  // fast random numbers
     225                PRNG_STATE_T random_state;                                              // fast random numbers
    225226
    226227                #if defined( __CFA_WITH_VERIFY__ )
  • libcfa/src/concurrency/kernel.cfa

    r7d9598d r2dcd80a  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Aug 31 07:08:20 2020
    13 // Update Count     : 71
     12// Last Modified On : Wed Nov 30 18:14:08 2022
     13// Update Count     : 76
    1414//
    1515
     
    151151        // Because of a bug, we couldn't initialized the seed on construction
    152152        // Do it here
    153         __cfaabi_tls.rand_seed ^= rdtscl();
     153        PRNG_SET_SEED( __cfaabi_tls.random_state, rdtscl() );
    154154        __cfaabi_tls.ready_rng.fwd_seed = 25214903917_l64u * (rdtscl() ^ (uintptr_t)&runner);
    155155        __tls_rand_advance_bck();
  • libcfa/src/concurrency/kernel/fwd.hfa

    r7d9598d r2dcd80a  
    4646                        } preemption_state;
    4747
    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
    5350                        struct {
    5451                                uint64_t fwd_seed;
     
    5754
    5855                        struct __stats_t        * volatile this_stats;
    59 
    6056
    6157                        #ifdef __CFA_WITH_VERIFY__
     
    7672                #define publicTLS_get( member ) ((typeof(__cfaabi_tls.member))__cfatls_get( __builtin_offsetof(KernelThreadData, member) ))
    7773
    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 );
    8582                }
    8683
     
    120117
    121118                // Yield: yield N times
    122                 static inline void yield( unsigned times ) {
     119                static inline void yield( size_t times ) {
    123120                        for( times ) {
    124121                                yield();
  • libcfa/src/concurrency/kernel/startup.cfa

    r7d9598d r2dcd80a  
    3939#include "limits.hfa"
    4040#include "math.hfa"
     41#include "bits/random.hfa"                                                              // prng
    4142
    4243#define CFA_PROCESSOR_USE_MMAP 0
     
    107108extern void __wake_proc(processor *);
    108109extern int cfa_main_returned;                                                   // from interpose.cfa
    109 uint32_t __global_random_prime = 4_294_967_291u, __global_random_mask = false;
     110size_t __global_random_prime = 4_294_967_291u;
     111bool __global_random_mask = false;
    110112
    111113//-----------------------------------------------------------------------------
     
    133135// Global state
    134136__thread struct KernelThreadData __cfaabi_tls __attribute__ ((tls_model ( "initial-exec" ))) @= {
    135         NULL,                                                                                           // cannot use 0p
    136         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,
    142144        #ifdef __CFA_WITH_VERIFY__
    143                 false,
    144                 0,
     145                .in_sched_lock : false,
     146                .sched_id : 0,
    145147        #endif
    146148};
     
    513515        rdy_link.next = 0p;
    514516        rdy_link.ts   = MAX;
     517        user_link.next = 0p;
     518        user_link.prev = 0p;
     519        cltr_link.next = 0p;
     520        cltr_link.prev = 0p;
    515521        preferred = ready_queue_new_preferred();
    516522        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() );
    518524        #if defined( __CFA_WITH_VERIFY__ )
    519525                executing = 0p;
  • libcfa/src/concurrency/stats.cfa

    r7d9598d r2dcd80a  
    4848                        stats->io.submit.eagr       = 0;
    4949                        stats->io.submit.nblk       = 0;
     50                        stats->io.submit.extr       = 0;
    5051                        stats->io.flush.external    = 0;
     52                        stats->io.flush.signal      = 0;
    5153                        stats->io.flush.dirty       = 0;
    5254                        stats->io.flush.full        = 0;
     
    120122                        tally_one( &cltr->io.submit.eagr      , &proc->io.submit.eagr       );
    121123                        tally_one( &cltr->io.submit.nblk      , &proc->io.submit.nblk       );
     124                        tally_one( &cltr->io.submit.extr      , &proc->io.submit.extr       );
    122125                        tally_one( &cltr->io.flush.external   , &proc->io.flush.external    );
     126                        tally_one( &cltr->io.flush.signal     , &proc->io.flush.signal      );
    123127                        tally_one( &cltr->io.flush.dirty      , &proc->io.flush.dirty       );
    124128                        tally_one( &cltr->io.flush.full       , &proc->io.flush.full        );
     
    199203                                if(io.alloc.slow) {
    200204                                        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;
    202206                                }
    203207                                sstr | " - eager" | eng3(io.submit.eagr) | nonl;
     
    217221                                     | " - cmp " | eng3(io.calls.locked) | "locked, " | eng3(io.calls.helped) | "helped"
    218222                                     | " - " | 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";
    220224                                sstr | "- ops blk: "
    221225                                     |   " sk rd: " | eng3(io.ops.sockread)  | "epll: " | eng3(io.ops.epllread)
  • libcfa/src/concurrency/stats.hfa

    r7d9598d r2dcd80a  
    9494                                volatile uint64_t eagr;
    9595                                volatile uint64_t nblk;
     96                                volatile uint64_t extr;
    9697                        } submit;
    9798                        struct {
    9899                                volatile uint64_t external;
     100                                volatile uint64_t signal;
    99101                                volatile uint64_t dirty;
    100102                                volatile uint64_t full;
  • libcfa/src/concurrency/thread.cfa

    r7d9598d r2dcd80a  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb 12 15:24:18 2022
    13 // Update Count     : 66
     12// Last Modified On : Sun Dec 11 20:56:54 2022
     13// Update Count     : 102
    1414//
    1515
     
    2626#include "invoke.h"
    2727
    28 extern uint32_t __global_random_seed, __global_random_prime, __global_random_mask;
     28extern size_t __global_random_seed;
     29extern size_t __global_random_prime;
     30extern bool __global_random_mask;
    2931
    3032#pragma GCC visibility push(default)
     
    4648        rdy_link.next = 0p;
    4749        rdy_link.ts   = MAX;
     50        user_link.next = 0p;
     51        user_link.prev = 0p;
     52        cltr_link.next = 0p;
     53        cltr_link.prev = 0p;
    4854        preferred = ready_queue_new_preferred();
    4955        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() );
    5157        #if defined( __CFA_WITH_VERIFY__ )
    5258                executing = 0p;
     
    176182//-----------------------------------------------------------------------------
    177183bool migrate( thread$ * thrd, struct cluster & cl ) {
    178 
    179184        monitor$ * tmon = get_monitor(thrd);
    180185        monitor$ * __monitors[] = { tmon };
    181186        monitor_guard_t __guard = { __monitors, 1 };
    182 
    183 
    184187        {
    185188                // if nothing needs to be done, return false
     
    221224
    222225//-----------------------------------------------------------------------------
    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
     227void 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;
    230232        __global_random_mask = true;
    231233} // set_seed
    232234
    233 uint32_t prng( void ) {                                                                 // [0,UINT_MAX]
    234         uint32_t & state = active_thread()->random_state;
    235         return GENERATOR( state );
     235size_t prng( void ) {                                                                   // [0,UINT_MAX]
     236        return PRNG_NAME( active_thread()->random_state );
    236237} // prng
    237238
  • libcfa/src/concurrency/thread.hfa

    r7d9598d r2dcd80a  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb 11 16:34:07 2022
    13 // Update Count     : 20
     12// Last Modified On : Tue Nov 22 22:18:34 2022
     13// Update Count     : 35
    1414//
    1515
     
    2323#include "monitor.hfa"
    2424#include "exception.hfa"
     25#include "bits/random.hfa"
    2526
    2627//-----------------------------------------------------------------------------
     
    141142//----------
    142143// prng
     144void set_seed( size_t seed );
    143145static 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]
    147149        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]
    151153        } // distribution
    152154} // distribution
  • libcfa/src/exception.h

    r7d9598d r2dcd80a  
    143143}
    144144
    145 forall(exceptT &, virtualT & | is_exception(exceptT, virtualT))
     145forall(exceptT &, virtualT & | is_termination_exception(exceptT, virtualT))
    146146static inline void defaultResumptionHandler(exceptT & except) {
    147147        throw except;
  • libcfa/src/startup.cfa

    r7d9598d r2dcd80a  
    1010// Created On       : Tue Jul 24 16:21:57 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Oct  6 13:51:57 2022
    13 // Update Count     : 57
     12// Last Modified On : Mon Dec  5 11:41:58 2022
     13// Update Count     : 73
    1414//
    1515
     
    1818#include <stdlib.h>                                                                             // getenv
    1919#include "bits/defs.hfa"                                                                // rdtscl
     20#include "bits/random.hfa"                                                              // rdtscl
    2021#include "startup.hfa"
    2122
    22 extern uint32_t __global_random_seed;                                   // sequential/concurrent
    23 extern uint32_t __global_random_state;                                  // sequential
     23extern size_t __global_random_seed;                                             // sequential/concurrent
     24extern PRNG_STATE_T __global_random_state;                              // sequential
    2425
    2526extern "C" {
     
    6869        void __cfaabi_core_startup( void ) __attribute__(( constructor( STARTUP_PRIORITY_CORE ) ));
    6970        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
    7174                __cfaabi_interpose_startup();
    7275                __cfaabi_device_startup();
  • libcfa/src/stdlib.cfa

    r7d9598d r2dcd80a  
    1010// Created On       : Thu Jan 28 17:10:29 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug 25 22:41:14 2022
    13 // Update Count     : 604
     12// Last Modified On : Fri Dec  9 15:11:30 2022
     13// Update Count     : 631
    1414//
    1515
     
    225225//---------------------------------------
    226226
    227 #define GENERATOR LCG
    228 
    229227// 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
     231void set_seed( size_t seed ) {
     232        __global_random_seed = seed;
     233        PRNG_SET_SEED( __global_random_state, seed );
     234} // set_seed
     235
     236size_t get_seed() { return __global_random_seed; }
     237size_t prng( void ) { return PRNG_NAME( __global_random_state ); } // [0,UINT_MAX]
    238238
    239239//---------------------------------------
  • libcfa/src/stdlib.hfa

    r7d9598d r2dcd80a  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug 25 18:07:06 2022
    13 // Update Count     : 645
     12// Last Modified On : Sun Dec 11 18:25:53 2022
     13// Update Count     : 765
    1414//
    1515
     
    404404//   calls( sprng );
    405405
    406 struct PRNG {
     406trait 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
     414static 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}
     417static 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
     421struct PRNG32 {
    407422        uint32_t callcnt;                                                                       // call count
    408423        uint32_t seed;                                                                          // current seed
    409         uint32_t state;                                                                         // random state
     424        PRNG_STATE_32_T state;                                                          // random state
    410425}; // PRNG
    411426
    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; }
     427static 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
     438struct PRNG64 {
     439        uint64_t callcnt;                                                                       // call count
     440        uint64_t seed;                                                                          // current seed
     441        PRNG_STATE_64_T state;                                                          // random state
     442}; // PRNG
     443
     444static 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
    421453} // distribution
    422454
     
    435467//   prng( 5, 21 );
    436468
    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.
     470void set_seed( size_t seed_ ) OPTIONAL_THREAD;                  // set global seed
     471size_t get_seed() __attribute__(( warn_unused_result )); // get global seed
     472size_t prng( void ) __attribute__(( warn_unused_result )) OPTIONAL_THREAD; // [0,UINT_MAX]
     473static 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]
    443476} // distribution
    444477
Note: See TracChangeset for help on using the changeset viewer.