@@ -1270,6 +1270,29 @@ Settings - Memory Function Selectors
12701270/** Helper for simple `for` loops, where `i` is the variable name to use. */
12711271#define FIO_FOR (i , count ) for (size_t i = 0; i < (count); ++i)
12721272#endif
1273+
1274+ /* *****************************************************************************
1275+ SIMD Vector Looping Helper
1276+ ***************************************************************************** */
1277+
1278+ /* Internal - bytes per constant iterative loop for compiler optimization */
1279+ #define FIO___SIMD_BYTES ((size_t)256U)
1280+ /* Internal - looping macro that separates */
1281+ #define FIO_FOR_UNROLL (itterations , size_of_loop , i , action ) \
1282+ do { \
1283+ size_t i = 0; \
1284+ /* handle odd length vectors, not multiples of FIO___LOG2V */ \
1285+ if ((itterations & ((FIO___SIMD_BYTES / size_of_loop ) - 1 ))) \
1286+ for (; i < (itterations & ((FIO___SIMD_BYTES / size_of_loop ) - 1 )); ++ i ) \
1287+ action ; \
1288+ if (itterations ) \
1289+ for (; i < itterations ;) \
1290+ for (size_t j__loop__ = 0 ; \
1291+ j__loop__ < (FIO___SIMD_BYTES / size_of_loop ); \
1292+ ++ j__loop__ , ++ i ) /* dear compiler, please vectorize */ \
1293+ action ; \
1294+ } while (0 )
1295+
12731296/* *****************************************************************************
12741297Memory Copying Primitives (the basis for unaligned memory access for numbers)
12751298***************************************************************************** */
@@ -2126,6 +2149,12 @@ FIO_SFUNC _Bool fio_ct_is_eq(const void *a_, const void *b_, size_t bytes) {
21262149 return !flag ;
21272150}
21282151
2152+ /** A timing attack resistant memory comparison function. */
2153+ FIO_IFUNC void fio_secure_zero (const void * a_ , size_t bytes ) {
2154+ volatile uint8_t * buf = (volatile uint8_t * )(a_ );
2155+ FIO_FOR_UNROLL (bytes , 1 , i , buf [i ] = 0 );
2156+ }
2157+
21292158/* *****************************************************************************
21302159Bit rotation
21312160***************************************************************************** */
@@ -3468,28 +3497,6 @@ FIO___VMATH_DEF_LARGE_MUL(4096, 2048)
34683497#undef FIO___VMATH_DEF_LARGE_ADD_SUB
34693498#undef FIO___VMATH_DEF_LARGE_MUL
34703499
3471- /* *****************************************************************************
3472- SIMD Vector Looping Helper
3473- ***************************************************************************** */
3474-
3475- /* Internal - bytes per constant iterative loop for compiler optimization */
3476- #define FIO___SIMD_BYTES ((size_t)256U)
3477- /* Internal - looping macro that separates */
3478- #define FIO_FOR_UNROLL (itterations , size_of_loop , i , action ) \
3479- do { \
3480- size_t i = 0; \
3481- /* handle odd length vectors, not multiples of FIO___LOG2V */ \
3482- if ((itterations & ((FIO___SIMD_BYTES / size_of_loop ) - 1 ))) \
3483- for (; i < (itterations & ((FIO___SIMD_BYTES / size_of_loop ) - 1 )); ++ i ) \
3484- action ; \
3485- if (itterations ) \
3486- for (; i < itterations ;) \
3487- for (size_t j__loop__ = 0 ; \
3488- j__loop__ < (FIO___SIMD_BYTES / size_of_loop ); \
3489- ++ j__loop__ , ++ i ) /* dear compiler, please vectorize */ \
3490- action ; \
3491- } while (0 )
3492-
34933500/* *****************************************************************************
34943501SIMD Vector Operations
34953502***************************************************************************** */
@@ -3539,6 +3546,24 @@ SIMD Vector Operations
35393546Defining a Pseudo-Random Number Generator Function (deterministic / not)
35403547**************************************************************************** */
35413548
3549+ #if defined(__x86_64__ ) || defined(__i386__ )
3550+ FIO_IFUNC uint64_t fio_cycle_counter (void ) {
3551+ uint64_t r = 0 ;
3552+ uint32_t lo , hi ;
3553+ __asm__ volatile ("rdtsc" : "=a" (lo ), "=d" (hi ));
3554+ r = ((uint64_t )hi << 32 ) | lo ;
3555+ return r ;
3556+ }
3557+ #elif defined(__aarch64__ )
3558+ FIO_IFUNC uint64_t fio_cycle_counter (void ) {
3559+ uint64_t r ;
3560+ __asm__ volatile ("mrs %0, cntvct_el0" : "=r" (r ));
3561+ return r ;
3562+ }
3563+ #else
3564+ FIO_IFUNC uint64_t fio_cycle_counter (void ) { return (uint64_t )0 ; }
3565+ #endif
3566+
35423567/**
35433568 * Defines a semi-deterministic Pseudo-Random 128 bit Number Generator function.
35443569 *
@@ -3570,47 +3595,59 @@ Defining a Pseudo-Random Number Generator Function (deterministic / not)
35703595 name##___state[3] = 0x95561f0927ad7ecdULL; \
35713596 name##___state[4] = 0; \
35723597 } \
3573- FIO_SFUNC void name##___state_reseed(uint64_t *state ) { \
3574- const size_t jitter_samples = 8 | (state [0] & 15); \
3598+ extern void name##_reseed(void ) { \
3599+ const size_t jitter_samples = 16 | (name##___state [0] & 15); \
35753600 for (size_t i = 0; i < jitter_samples; ++i) { \
35763601 struct timespec t; \
35773602 clock_gettime(CLOCK_MONOTONIC, &t); \
3578- uint64_t clk[2]; \
3579- clk[0] = (uint64_t)((t.tv_sec << 30) + (int64_t)t.tv_nsec); \
3603+ uint64_t clk[2] = {(uint64_t)(uintptr_t)&clk + (uint64_t)(uintptr_t) & \
3604+ (name##_reseed), \
3605+ 0}; \
3606+ clk[0] += (uint64_t)((t.tv_sec << 30) + (int64_t)t.tv_nsec); \
35803607 clk[0] = fio_math_mulc64(clk[0], FIO_U64_HASH_PRIME0, clk + 1); \
35813608 clk[1] += FIO_U64_HASH_PRIME0; \
35823609 clk[0] += fio_lrot64(clk[0], 27); \
35833610 clk[0] += fio_lrot64(clk[0], 49); \
35843611 clk[1] += fio_lrot64(clk[1], 27); \
35853612 clk[1] += fio_lrot64(clk[1], 49); \
3586- state [0] += clk[0]; \
3587- state [1] += clk[1]; \
3588- state [2] += clk[0]; \
3589- state [3] += clk[1]; \
3613+ name##___state [0] += clk[0] + fio_cycle_counter(); \
3614+ name##___state [1] += clk[1] + fio_cycle_counter(); \
3615+ name##___state [2] += clk[0] + fio_cycle_counter(); \
3616+ name##___state [3] += clk[1] + fio_cycle_counter(); \
35903617 } \
35913618 } \
35923619 /** Re-seeds the PNGR so forked processes don't match. */ \
35933620 extern __attribute__((unused )) void name ##_on_fork (void * is_null ) { \
35943621 (void )is_null ; \
3595- name ##___state_reseed ( name ## ___state ); \
3622+ name ##_reseed (); \
35963623 } \
35973624 /** Returns a 128 bit pseudo-random number. */ \
35983625 extern __attribute__((unused )) fio_u128 name ##128 (void) { \
35993626 fio_u256 r; \
3600- if (!((name##___state[4]++) & ((1ULL << reseed_log) - 1)) && \
3627+ if (!(fio_atomic_add(name##___state + 4, 1) & \
3628+ ((1ULL << reseed_log) - 1)) && \
36013629 ((size_t)(reseed_log - 1) < 63)) \
3602- name##___state_reseed(name##___state); \
3630+ name##_reseed(); \
36033631 uint64_t s1[4]; \
36043632 { /* load state to registers and roll, mul, add */ \
3605- const uint64_t s0 [] = {name ##___state [0 ], \
3606- name ##___state [1 ], \
3607- name ##___state [2 ], \
3608- name ##___state [3 ]}; \
3633+ const uint64_t cycles = \
3634+ reseed_log ? fio_cycle_counter () + (uint64_t )(uintptr_t )& cycles \
3635+ : 0xB5ULL ; \
3636+ const uint64_t variation = \
3637+ 0x4E55788DULL + \
3638+ (reseed_log ? (uint64_t )(uintptr_t )& name ##_reseed : 0 ); \
3639+ const uint64_t s0 [] = {(name ##___state [0 ] + cycles ), \
3640+ (name ##___state [1 ] + cycles ), \
3641+ (name ##___state [2 ] + cycles ), \
3642+ (name ##___state [3 ] + cycles )}; \
36093643 const uint64_t mulp [] = {0x37701261ED6C16C7ULL , \
36103644 0x764DBBB75F3B3E0DULL , \
36113645 ~(0x37701261ED6C16C7ULL ), \
36123646 ~(0x764DBBB75F3B3E0DULL )}; \
3613- const uint64_t addc [] = {name ##___state [4 ], 0 , name ##___state [4 ], 0 }; \
3647+ const uint64_t addc [] = {name ##___state [4 ], \
3648+ seed_offset + 0x59DD1C23ULL , \
3649+ name ##___state [4 ] + cycles , \
3650+ variation }; \
36143651 for (size_t i = 0 ; i < 4 ; ++ i ) { \
36153652 s1 [i ] = fio_lrot64 (s0 [i ], 33 ); \
36163653 s1 [i ] += addc [i ]; \
0 commit comments