Warning: This file is not a C or C++ file. It does not have highlighting.
| 1 | //===-- HashTable Randomness ------------------------------------*- C++ -*-===// |
|---|---|
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #ifndef LLVM_LIBC_SRC___SUPPORT_HASHTABLE_RANDOMNESS_H |
| 10 | #define LLVM_LIBC_SRC___SUPPORT_HASHTABLE_RANDOMNESS_H |
| 11 | |
| 12 | #include "src/__support/common.h" |
| 13 | #include "src/__support/hash.h" |
| 14 | #include "src/__support/macros/attributes.h" |
| 15 | #include "src/__support/macros/config.h" |
| 16 | #if defined(LIBC_HASHTABLE_USE_GETRANDOM) |
| 17 | #include "src/__support/libc_errno.h" |
| 18 | #include "src/sys/random/getrandom.h" |
| 19 | #endif |
| 20 | |
| 21 | namespace LIBC_NAMESPACE_DECL { |
| 22 | namespace internal { |
| 23 | namespace randomness { |
| 24 | // We need an initial state for the hash function. More entropy are to be added |
| 25 | // at the first use and each round of reseeding. The following random numbers |
| 26 | // are generated from https://www.random.org/cgi-bin/randbyte?nbytes=64&format=h |
| 27 | LIBC_INLINE_VAR thread_local HashState state = { |
| 28 | 0x38049a7ea6f5a79b, 0x45cb02147c3f718a, 0x53eb431c12770718, |
| 29 | 0x5b55742bd20a2fcb}; |
| 30 | LIBC_INLINE_VAR thread_local uint64_t counter = 0; |
| 31 | LIBC_INLINE_VAR constexpr uint64_t RESEED_PERIOD = 1024; |
| 32 | LIBC_INLINE uint64_t next_random_seed() { |
| 33 | if (counter % RESEED_PERIOD == 0) { |
| 34 | uint64_t entropy[2]; |
| 35 | entropy[0] = reinterpret_cast<uint64_t>(&entropy); |
| 36 | entropy[1] = reinterpret_cast<uint64_t>(&state); |
| 37 | #if defined(LIBC_HASHTABLE_USE_GETRANDOM) |
| 38 | int errno_backup = libc_errno; |
| 39 | size_t count = sizeof(entropy); |
| 40 | uint8_t *buffer = reinterpret_cast<uint8_t *>(entropy); |
| 41 | while (count > 0) { |
| 42 | ssize_t len = getrandom(buffer, count, 0); |
| 43 | if (len == -1) { |
| 44 | if (libc_errno == ENOSYS) |
| 45 | break; |
| 46 | continue; |
| 47 | } |
| 48 | count -= len; |
| 49 | buffer += len; |
| 50 | } |
| 51 | libc_errno = errno_backup; |
| 52 | #endif |
| 53 | state.update(&entropy, sizeof(entropy)); |
| 54 | } |
| 55 | state.update(&counter, sizeof(counter)); |
| 56 | counter++; |
| 57 | return state.finish(); |
| 58 | } |
| 59 | |
| 60 | } // namespace randomness |
| 61 | } // namespace internal |
| 62 | } // namespace LIBC_NAMESPACE_DECL |
| 63 | #endif // LLVM_LIBC_SRC___SUPPORT_HASHTABLE_RANDOMNESS_H |
| 64 |
Warning: This file is not a C or C++ file. It does not have highlighting.
