Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/libc/src/__support/HashTable/randomness.h
213799 views
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 "hdr/errno_macros.h"
18
#include "src/__support/OSUtil/linux/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
size_t count = sizeof(entropy);
39
uint8_t *buffer = reinterpret_cast<uint8_t *>(entropy);
40
while (count > 0) {
41
auto len = internal::getrandom(buffer, count, 0);
42
if (!len.has_value()) {
43
if (len.error() == ENOSYS)
44
break;
45
continue;
46
}
47
count -= len.value();
48
buffer += len.value();
49
}
50
#endif
51
state.update(&entropy, sizeof(entropy));
52
}
53
state.update(&counter, sizeof(counter));
54
counter++;
55
return state.finish();
56
}
57
58
} // namespace randomness
59
} // namespace internal
60
} // namespace LIBC_NAMESPACE_DECL
61
#endif // LLVM_LIBC_SRC___SUPPORT_HASHTABLE_RANDOMNESS_H
62
63