From e261805013731364a9d6832f43e9b1533d0d95e1 Mon Sep 17 00:00:00 2001 From: SChernykh <15806605+SChernykh@users.noreply.github.com> Date: Thu, 31 Oct 2024 15:00:15 +0100 Subject: [PATCH] Stratum: removed submitted shares memory pool It's faster to have stack allocation when possible --- src/stratum_server.cpp | 103 ++++++++++++++++++----------------------- src/stratum_server.h | 4 +- 2 files changed, 47 insertions(+), 60 deletions(-) diff --git a/src/stratum_server.cpp b/src/stratum_server.cpp index 72dbfe62..25b2e890 100644 --- a/src/stratum_server.cpp +++ b/src/stratum_server.cpp @@ -72,13 +72,6 @@ StratumServer::StratumServer(p2pool* pool) m_extraNonce = get_random32(); - m_submittedSharesPool.resize(10); - for (size_t i = 0; i < m_submittedSharesPool.size(); ++i) { - SubmittedShare* share = new SubmittedShare{}; - ASAN_POISON_MEMORY_REGION(share, sizeof(SubmittedShare)); - m_submittedSharesPool[i] = share; - } - m_pendingShareChecks.reserve(10); uv_async_init_checked(&m_loop, &m_blobsAsync, on_blobs_ready); @@ -108,11 +101,6 @@ StratumServer::~StratumServer() uv_mutex_destroy(&m_showWorkersLock); uv_mutex_destroy(&m_rngLock); uv_rwlock_destroy(&m_hashrateDataLock); - - for (SubmittedShare* share : m_submittedSharesPool) { - ASAN_UNPOISON_MEMORY_REGION(share, sizeof(SubmittedShare)); - delete share; - } } void StratumServer::on_block(const BlockTemplate& block) @@ -442,83 +430,81 @@ bool StratumServer::on_submit(StratumClient* client, uint32_t id, const char* jo } } - SubmittedShare* share; - - if (!m_submittedSharesPool.empty()) { - share = m_submittedSharesPool.back(); - m_submittedSharesPool.pop_back(); - ASAN_UNPOISON_MEMORY_REGION(share, sizeof(SubmittedShare)); - } - else { - share = new SubmittedShare{}; - } - if (target >= TARGET_4_BYTES_LIMIT) { // "Low diff share" fix: adjust target to the same value as XMRig would use target = std::numeric_limits::max() / (std::numeric_limits::max() / (target >> 32)); } - share->m_req.data = share; - share->m_server = this; - share->m_client = client; - share->m_clientIPv6 = client->m_isV6; - share->m_clientAddr = client->m_addr; - memcpy(share->m_clientAddrString, client->m_addrString, sizeof(share->m_clientAddrString)); - memcpy(share->m_clientCustomUser, client->m_customUser, sizeof(share->m_clientCustomUser)); - share->m_clientResetCounter = client->m_resetCounter.load(); - share->m_rpcId = client->m_rpcId; - share->m_id = id; - share->m_templateId = template_id; - share->m_nonce = nonce; - share->m_extraNonce = extra_nonce; - share->m_target = target; - share->m_resultHash = resultHash; - share->m_sidechainDifficulty = sidechain_diff; - share->m_mainchainHeight = height; - share->m_sidechainHeight = sidechain_height; - share->m_effort = -1.0; - share->m_timestamp = seconds_since_epoch(); + SubmittedShare share{}; + + share.m_req.data = &share; + share.m_allocated = false; + + share.m_server = this; + share.m_client = client; + share.m_clientIPv6 = client->m_isV6; + share.m_clientAddr = client->m_addr; + memcpy(share.m_clientAddrString, client->m_addrString, sizeof(share.m_clientAddrString)); + memcpy(share.m_clientCustomUser, client->m_customUser, sizeof(share.m_clientCustomUser)); + share.m_clientResetCounter = client->m_resetCounter.load(); + share.m_rpcId = client->m_rpcId; + share.m_id = id; + share.m_templateId = template_id; + share.m_nonce = nonce; + share.m_extraNonce = extra_nonce; + share.m_target = target; + share.m_resultHash = resultHash; + share.m_sidechainDifficulty = sidechain_diff; + share.m_mainchainHeight = height; + share.m_sidechainHeight = sidechain_height; + share.m_effort = -1.0; + share.m_timestamp = seconds_since_epoch(); uint64_t rem; - share->m_hashes = (target > 1) ? udiv128(1, 0, target, &rem) : 1; - share->m_highEnoughDifficulty = sidechain_diff.check_pow(resultHash); - share->m_score = 0; + share.m_hashes = (target > 1) ? udiv128(1, 0, target, &rem) : 1; + share.m_highEnoughDifficulty = sidechain_diff.check_pow(resultHash); + share.m_score = 0; // Don't count shares that were found during sync const SideChain& side_chain = m_pool->side_chain(); const PoolBlock* tip = side_chain.chainTip(); if (tip && (sidechain_height + side_chain.chain_window_size() < tip->m_sidechainHeight)) { - share->m_highEnoughDifficulty = false; + share.m_highEnoughDifficulty = false; } - update_auto_diff(client, share->m_timestamp, share->m_hashes); + update_auto_diff(client, share.m_timestamp, share.m_hashes); // If this share is below sidechain difficulty, process it in this thread because it'll be quick - if (!share->m_highEnoughDifficulty) { - on_share_found(&share->m_req); - on_after_share_found(&share->m_req, 0); + if (!share.m_highEnoughDifficulty) { + on_share_found(&share.m_req); + on_after_share_found(&share.m_req, 0); return true; } // Else switch to a worker thread to check PoW which can take a long time + SubmittedShare* share2 = new SubmittedShare(share); + + share2->m_req.data = share2; + share2->m_allocated = true; + if (m_pendingShareChecks.empty()) { - const int err = uv_queue_work(&m_loop, &share->m_req, on_share_found, on_after_share_found); + const int err = uv_queue_work(&m_loop, &share2->m_req, on_share_found, on_after_share_found); if (err) { LOGERR(1, "uv_queue_work failed, error " << uv_err_name(err)); // If uv_queue_work failed, process this share here anyway - on_share_found(&share->m_req); - on_after_share_found(&share->m_req, 0); + on_share_found(&share2->m_req); + on_after_share_found(&share2->m_req, 0); } else { - m_pendingShareChecks.push_back(share); + m_pendingShareChecks.push_back(share2); LOGINFO(5, "Pending share checks count = " << m_pendingShareChecks.size()); } } else { // If there is a check running already, it will pick up this share in on_after_share_found // This ensures that only one share at a time is checked - m_pendingShareChecks.push_back(share); + m_pendingShareChecks.push_back(share2); LOGINFO(5, "Pending share checks count = " << m_pendingShareChecks.size()); } @@ -1046,8 +1032,9 @@ void StratumServer::on_after_share_found(uv_work_t* req, int /*status*/) } LOGINFO(5, "Pending share checks count = " << server->m_pendingShareChecks.size()); - ASAN_POISON_MEMORY_REGION(share, sizeof(SubmittedShare)); - server->m_submittedSharesPool.push_back(share); + if (share->m_allocated) { + delete share; + } if (!server->m_pendingShareChecks.empty()) { SubmittedShare* share2 = server->m_pendingShareChecks.front(); diff --git a/src/stratum_server.h b/src/stratum_server.h index 73172cd4..0c478d7a 100644 --- a/src/stratum_server.h +++ b/src/stratum_server.h @@ -147,6 +147,8 @@ class StratumServer : public TCPServer struct SubmittedShare { uv_work_t m_req; + bool m_allocated; + StratumServer* m_server; StratumClient* m_client; bool m_clientIPv6; @@ -180,8 +182,6 @@ class StratumServer : public TCPServer } m_result; }; - std::vector m_submittedSharesPool; - struct HashrateData { uint64_t m_timestamp;