More fine-grained locks in crypto cache

This commit is contained in:
SChernykh 2022-08-15 18:39:28 +02:00
parent 1438175477
commit 4c8dbee79d
3 changed files with 26 additions and 17 deletions

View file

@ -159,12 +159,16 @@ class Cache
public: public:
Cache() Cache()
{ {
uv_mutex_init_checked(&m); uv_mutex_init_checked(&derivations_lock);
uv_rwlock_init_checked(&public_keys_lock);
uv_rwlock_init_checked(&tx_keys_lock);
} }
~Cache() ~Cache()
{ {
uv_mutex_destroy(&m); uv_mutex_destroy(&derivations_lock);
uv_rwlock_destroy(&public_keys_lock);
uv_rwlock_destroy(&tx_keys_lock);
} }
bool get_derivation(const hash& key1, const hash& key2, size_t output_index, hash& derivation, uint8_t& view_tag) bool get_derivation(const hash& key1, const hash& key2, size_t output_index, hash& derivation, uint8_t& view_tag)
@ -174,7 +178,7 @@ public:
memcpy(index.data() + HASH_SIZE, key2.h, HASH_SIZE); memcpy(index.data() + HASH_SIZE, key2.h, HASH_SIZE);
{ {
MutexLock lock(m); MutexLock lock(derivations_lock);
auto it = derivations.find(index); auto it = derivations.find(index);
if (it != derivations.end()) { if (it != derivations.end()) {
derivation = it->second.m_derivation; derivation = it->second.m_derivation;
@ -197,7 +201,7 @@ public:
ge_tobytes(reinterpret_cast<uint8_t*>(&derivation), &point2); ge_tobytes(reinterpret_cast<uint8_t*>(&derivation), &point2);
{ {
MutexLock lock(m); MutexLock lock(derivations_lock);
auto result = derivations.emplace(index, DerivationEntry{ derivation, {} }); auto result = derivations.emplace(index, DerivationEntry{ derivation, {} });
view_tag = result.first->second.get_view_tag(output_index); view_tag = result.first->second.get_view_tag(output_index);
} }
@ -213,7 +217,7 @@ public:
memcpy(index.data() + HASH_SIZE * 2, &output_index, sizeof(size_t)); memcpy(index.data() + HASH_SIZE * 2, &output_index, sizeof(size_t));
{ {
MutexLock lock(m); ReadLock lock(public_keys_lock);
auto it = public_keys.find(index); auto it = public_keys.find(index);
if (it != public_keys.end()) { if (it != public_keys.end()) {
derived_key = it->second; derived_key = it->second;
@ -240,7 +244,7 @@ public:
ge_tobytes(derived_key.h, &point5); ge_tobytes(derived_key.h, &point5);
{ {
MutexLock lock(m); WriteLock lock(public_keys_lock);
public_keys.emplace(index, derived_key); public_keys.emplace(index, derived_key);
} }
@ -254,7 +258,7 @@ public:
memcpy(index.data() + HASH_SIZE, monero_block_id.h, HASH_SIZE); memcpy(index.data() + HASH_SIZE, monero_block_id.h, HASH_SIZE);
{ {
MutexLock lock(m); ReadLock lock(tx_keys_lock);
auto it = tx_keys.find(index); auto it = tx_keys.find(index);
if (it != tx_keys.end()) { if (it != tx_keys.end()) {
pub = it->second.first; pub = it->second.first;
@ -274,18 +278,16 @@ public:
generate_keys_deterministic(pub, sec, entropy, sizeof(entropy)); generate_keys_deterministic(pub, sec, entropy, sizeof(entropy));
{ {
MutexLock lock(m); WriteLock lock(tx_keys_lock);
tx_keys.emplace(index, std::pair<hash, hash>(pub, sec)); tx_keys.emplace(index, std::pair<hash, hash>(pub, sec));
} }
} }
void clear() void clear()
{ {
MutexLock lock(m); { MutexLock lock(derivations_lock); derivations.clear(); }
{ WriteLock lock(public_keys_lock); public_keys.clear(); }
derivations.clear(); { WriteLock lock(tx_keys_lock); tx_keys.clear(); }
public_keys.clear();
tx_keys.clear();
} }
private: private:
@ -309,9 +311,13 @@ private:
} }
}; };
uv_mutex_t m; uv_mutex_t derivations_lock;
unordered_map<std::array<uint8_t, HASH_SIZE * 2>, DerivationEntry> derivations; unordered_map<std::array<uint8_t, HASH_SIZE * 2>, DerivationEntry> derivations;
uv_rwlock_t public_keys_lock;
unordered_map<std::array<uint8_t, HASH_SIZE * 2 + sizeof(size_t)>, hash> public_keys; unordered_map<std::array<uint8_t, HASH_SIZE * 2 + sizeof(size_t)>, hash> public_keys;
uv_rwlock_t tx_keys_lock;
unordered_map<std::array<uint8_t, HASH_SIZE * 2>, std::pair<hash, hash>> tx_keys; unordered_map<std::array<uint8_t, HASH_SIZE * 2>, std::pair<hash, hash>> tx_keys;
}; };

View file

@ -32,7 +32,7 @@ namespace p2pool {
static bool track_memory = false; static bool track_memory = false;
constexpr size_t N = 1048576; constexpr size_t N = 2097152;
constexpr size_t MAX_FRAMES = 30; constexpr size_t MAX_FRAMES = 30;
struct TrackedAllocation struct TrackedAllocation

View file

@ -762,8 +762,11 @@ bool SideChain::get_outputs_blob(PoolBlock* block, uint64_t total_reward, std::v
} }
++work->num_helper_jobs_finished; ++work->num_helper_jobs_finished;
delete work; },
}, nullptr); [](uv_work_t* req, int /*status*/)
{
delete reinterpret_cast<Work*>(req->data);
});
if (err) { if (err) {
LOGERR(1, "get_outputs_blob: uv_queue_work failed, error " << uv_err_name(err)); LOGERR(1, "get_outputs_blob: uv_queue_work failed, error " << uv_err_name(err));