1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-01-30 19:03:04 +00:00

perf: batch up calls to the RNG (#3537)

This commit is contained in:
Charles Kerr 2022-07-28 10:01:59 -05:00 committed by GitHub
parent 88e898b005
commit 15056045bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 111 additions and 77 deletions

View file

@ -6,6 +6,7 @@
#ifndef TR_CRYPTO_UTILS_H
#define TR_CRYPTO_UTILS_H
#include <array>
#include <cstddef> // size_t
#include <optional>
#include <string>
@ -190,6 +191,31 @@ std::string tr_sha256_to_string(tr_sha256_digest_t const&);
*/
std::optional<tr_sha256_digest_t> tr_sha256_from_string(std::string_view hex);
// Convenience utility to efficiently get many random small values.
// Use this instead of making a lot of calls to tr_rand_int().
class tr_salt_shaker
{
public:
[[nodiscard]] auto operator()() noexcept
{
if (pos == std::size(buf))
{
pos = 0U;
}
if (pos == 0U)
{
tr_rand_buffer(std::data(buf), std::size(buf));
}
return buf[pos++];
}
private:
size_t pos = 0;
std::array<uint8_t, 1024U> buf;
};
/** @} */
#endif /* TR_CRYPTO_UTILS_H */

View file

@ -87,15 +87,14 @@ std::vector<Candidate> getCandidates(Wishlist::Mediator const& mediator)
}
// transform them into candidates
auto salter = tr_salt_shaker{};
auto const n = std::size(wanted_pieces);
auto saltbuf = std::vector<char>(n);
tr_rand_buffer(std::data(saltbuf), n);
auto candidates = std::vector<Candidate>{};
candidates.reserve(n);
for (size_t i = 0; i < n; ++i)
{
auto const [piece, n_missing] = wanted_pieces[i];
candidates.emplace_back(piece, n_missing, mediator.priority(piece), saltbuf[i]);
candidates.emplace_back(piece, n_missing, mediator.priority(piece), salter());
}
return candidates;

View file

@ -1869,9 +1869,10 @@ enum tr_rechoke_state
struct tr_rechoke_info
{
tr_rechoke_info(tr_peerMsgs* peer_in, int rechoke_state_in)
tr_rechoke_info(tr_peerMsgs* peer_in, int rechoke_state_in, uint8_t salt_in)
: peer{ peer_in }
, rechoke_state{ rechoke_state_in }
, salt{ salt_in }
{
}
@ -1882,7 +1883,12 @@ struct tr_rechoke_info
return this->rechoke_state - that.rechoke_state;
}
return this->salt - that.salt;
if (this->salt != that.salt)
{
return this->salt < that.salt ? -1 : 1;
}
return 0;
}
[[nodiscard]] constexpr auto operator<(tr_rechoke_info const& that) const noexcept
@ -1892,7 +1898,7 @@ struct tr_rechoke_info
tr_peerMsgs* peer;
int rechoke_state;
int salt = tr_rand_int_weak(INT_MAX);
uint8_t salt;
};
} // namespace
@ -1908,6 +1914,7 @@ void rechokeDownloads(tr_swarm* s)
uint16_t max_peers = 0;
auto rechoke = std::vector<tr_rechoke_info>{};
auto salter = tr_salt_shaker{};
/* some cases where this function isn't necessary */
if (s->tor->isDone() || !s->tor->clientCanDownload())
@ -2035,7 +2042,7 @@ void rechokeDownloads(tr_swarm* s)
rechoke_state = RECHOKE_STATE_BAD;
}
rechoke.emplace_back(peer, rechoke_state);
rechoke.emplace_back(peer, rechoke_state, salter());
}
}
@ -2083,7 +2090,7 @@ struct ChokeData
bool wasChoked;
bool isChoked;
int rate;
int salt;
uint8_t salt;
tr_peerMsgs* msgs;
[[nodiscard]] constexpr auto compare(ChokeData const& that) const noexcept // <=>
@ -2100,7 +2107,7 @@ struct ChokeData
if (this->salt != that.salt) // random order
{
return this->salt - that.salt;
return this->salt < that.salt ? -1 : 1;
}
return 0;
@ -2169,6 +2176,7 @@ void rechokeUploads(tr_swarm* s, uint64_t const now)
int size = 0;
/* sort the peers by preference and rate */
auto salter = tr_salt_shaker{};
for (auto* const peer : peers)
{
if (peer->isSeed())
@ -2188,7 +2196,7 @@ void rechokeUploads(tr_swarm* s, uint64_t const now)
n->isInterested = peer->is_peer_interested();
n->wasChoked = peer->is_peer_choked();
n->rate = getRateBps(s->tor, peer, now);
n->salt = tr_rand_int_weak(INT_MAX);
n->salt = salter();
n->isChoked = true;
}
}
@ -2753,6 +2761,7 @@ struct peer_candidate
candidates.reserve(atom_count);
/* populate the candidate array */
auto salter = tr_salt_shaker{};
for (auto* tor : session->torrents())
{
if (!tor->swarm->is_running)
@ -2784,8 +2793,7 @@ struct peer_candidate
{
if (isPeerCandidate(tor, atom, now))
{
uint8_t const salt = tr_rand_int_weak(1024);
candidates.push_back({ getPeerCandidateScore(tor, atom, salt), tor, &atom });
candidates.push_back({ getPeerCandidateScore(tor, atom, salter()), tor, &atom });
}
}
}

View file

@ -479,8 +479,6 @@ static void addPeers(tr_torrent const* tor, tr_variant* list)
static void initField(tr_torrent const* const tor, tr_stat const* const st, tr_variant* const initme, tr_quark key)
{
char* str = nullptr;
switch (key)
{
case TR_KEY_activityDate:

View file

@ -10,30 +10,21 @@
#ifdef CRYPTO_REFERENCE_CHECK
#define tr_sha1_ctx_t tr_sha1_ctx_t_
#define tr_ssl_ctx_t tr_ssl_ctx_t_
#define tr_x509_store_t tr_x509_store_t_
#define tr_x509_cert_t tr_x509_cert_t_
#define tr_sha1 tr_sha1_
#define tr_sha1_init tr_sha1_init_
#define tr_sha1_update tr_sha1_update_
#define tr_sha1_final tr_sha1_final_
#define tr_ssl_get_x509_store tr_ssl_get_x509_store_
#define tr_x509_store_add tr_x509_store_add_
#define tr_x509_cert_new tr_x509_cert_new_
#define tr_x509_cert_free tr_x509_cert_free_
#define tr_rand_int tr_rand_int_
#define tr_rand_int_weak tr_rand_int_weak_
#define tr_rand_buffer tr_rand_buffer_
#define tr_ssha1 tr_ssha1_
#define tr_ssha1_matches tr_ssha1_matches_
#define tr_ssha1_test tr_ssha1_test_
#define tr_base64_encode tr_base64_encode_
#define tr_base64_encode_impl tr_base64_encode_impl_
#define tr_base64_decode tr_base64_decode_
#define tr_base64_decode_impl tr_base64_decode_impl_
#define tr_sha1_to_string tr_sha1_to_string_
#define tr_base64_encode tr_base64_encode_
#define tr_base64_encode_impl tr_base64_encode_impl_
#define tr_rand_buffer tr_rand_buffer_
#define tr_rand_int tr_rand_int_
#define tr_rand_int_weak tr_rand_int_weak_
#define tr_salt_shaker tr_salt_shaker_
#define tr_sha1 tr_sha1_
#define tr_sha1_ctx_t tr_sha1_ctx_t_
#define tr_sha1_final tr_sha1_final_
#define tr_sha1_from_string tr_sha1_from_string_
#define tr_sha1_init tr_sha1_init_
#define tr_sha1_to_string tr_sha1_to_string_
#define tr_sha1_update tr_sha1_update_
#define tr_sha256 tr_sha256_
#define tr_sha256_ctx_t tr_sha256_ctx_t_
#define tr_sha256_final tr_sha256_final_
@ -41,6 +32,16 @@
#define tr_sha256_init tr_sha256_init_
#define tr_sha256_to_string tr_sha256_to_string_
#define tr_sha256_update tr_sha256_update_
#define tr_ssha1 tr_ssha1_
#define tr_ssha1_matches tr_ssha1_matches_
#define tr_ssha1_test tr_ssha1_test_
#define tr_ssl_ctx_t tr_ssl_ctx_t_
#define tr_ssl_get_x509_store tr_ssl_get_x509_store_
#define tr_x509_cert_free tr_x509_cert_free_
#define tr_x509_cert_new tr_x509_cert_new_
#define tr_x509_cert_t tr_x509_cert_t_
#define tr_x509_store_add tr_x509_store_add_
#define tr_x509_store_t tr_x509_store_t_
#undef TR_ENCRYPTION_H
#undef TR_CRYPTO_UTILS_H
@ -49,30 +50,21 @@
#include "crypto-utils.cc"
#include "crypto-utils-openssl.cc"
#undef tr_sha1_ctx_t
#undef tr_ssl_ctx_t
#undef tr_x509_store_t
#undef tr_x509_cert_t
#undef tr_sha1
#undef tr_sha1_init
#undef tr_sha1_update
#undef tr_sha1_final
#undef tr_ssl_get_x509_store
#undef tr_x509_store_add
#undef tr_x509_cert_new
#undef tr_x509_cert_free
#undef tr_rand_int
#undef tr_rand_int_weak
#undef tr_rand_buffer
#undef tr_ssha1
#undef tr_ssha1_matches
#undef tr_ssha1_test
#undef tr_base64_encode
#undef tr_base64_encode_impl
#undef tr_base64_decode
#undef tr_base64_decode_impl
#undef tr_sha1_to_string
#undef tr_base64_encode
#undef tr_base64_encode_impl
#undef tr_rand_buffer
#undef tr_rand_int
#undef tr_rand_int_weak
#undef tr_salt_shaker
#undef tr_sha1
#undef tr_sha1_ctx_t
#undef tr_sha1_final
#undef tr_sha1_from_string
#undef tr_sha1_init
#undef tr_sha1_to_string
#undef tr_sha1_update
#undef tr_sha256
#undef tr_sha256_ctx_t
#undef tr_sha256_final
@ -80,33 +72,34 @@
#undef tr_sha256_init
#undef tr_sha256_to_string
#undef tr_sha256_update
#undef tr_ssha1
#undef tr_ssha1_matches
#undef tr_ssha1_test
#undef tr_ssl_ctx_t
#undef tr_ssl_get_x509_store
#undef tr_x509_cert_free
#undef tr_x509_cert_new
#undef tr_x509_cert_t
#undef tr_x509_store_add
#undef tr_x509_store_t
#else /* CRYPTO_REFERENCE_CHECK */
#define tr_sha1_ctx_t_ tr_sha1_ctx_t
#define tr_ssl_ctx_t_ tr_ssl_ctx_t
#define tr_x509_store_t_ tr_x509_store_t
#define tr_x509_cert_t_ tr_x509_cert_t
#define tr_sha1_ tr_sha1
#define tr_sha1_init_ tr_sha1_init
#define tr_sha1_update_ tr_sha1_update
#define tr_sha1_final_ tr_sha1_final
#define tr_ssl_get_x509_store_ tr_ssl_get_x509_store
#define tr_x509_store_add_ tr_x509_store_add
#define tr_x509_cert_new_ tr_x509_cert_new
#define tr_x509_cert_free_ tr_x509_cert_free
#define tr_rand_int_ tr_rand_int
#define tr_rand_int_weak_ tr_rand_int_weak
#define tr_rand_buffer_ tr_rand_buffer
#define tr_ssha1_ tr_ssha1
#define tr_ssha1_matches_ tr_ssha1_matches
#define tr_ssha1_test_ tr_ssha1_test
#define tr_base64_encode_ tr_base64_encode
#define tr_base64_encode_impl_ tr_base64_encode_impl
#define tr_base64_decode_ tr_base64_decode
#define tr_base64_decode_impl_ tr_base64_decode_impl
#define tr_sha1_to_string_ tr_sha1_to_string
#define tr_base64_encode_ tr_base64_encode
#define tr_base64_encode_impl_ tr_base64_encode_impl
#define tr_rand_buffer_ tr_rand_buffer
#define tr_rand_int_ tr_rand_int
#define tr_rand_int_weak_ tr_rand_int_weak
#define tr_salt_shaker_ tr_salt_shaker
#define tr_sha1_ tr_sha1
#define tr_sha1_ctx_t_ tr_sha1_ctx_t
#define tr_sha1_final_ tr_sha1_final
#define tr_sha1_from_string_ tr_sha1_from_string
#define tr_sha1_init_ tr_sha1_init
#define tr_sha1_to_string_ tr_sha1_to_string
#define tr_sha1_update_ tr_sha1_update
#define tr_sha256_ tr_sha256
#define tr_sha256_ctx_t_ tr_sha256_ctx_t
#define tr_sha256_final_ tr_sha256_final
@ -114,6 +107,16 @@
#define tr_sha256_init_ tr_sha256_init
#define tr_sha256_to_string_ tr_sha256_to_string
#define tr_sha256_update_ tr_sha256_update
#define tr_ssha1_ tr_ssha1
#define tr_ssha1_matches_ tr_ssha1_matches
#define tr_ssha1_test_ tr_ssha1_test
#define tr_ssl_ctx_t_ tr_ssl_ctx_t
#define tr_ssl_get_x509_store_ tr_ssl_get_x509_store
#define tr_x509_cert_free_ tr_x509_cert_free
#define tr_x509_cert_new_ tr_x509_cert_new
#define tr_x509_cert_t_ tr_x509_cert_t
#define tr_x509_store_add_ tr_x509_store_add
#define tr_x509_store_t_ tr_x509_store_t
#endif /* CRYPTO_REFERENCE_CHECK */