From 7d362ac6914f6563c1a1531eaa34ae0428ae821a Mon Sep 17 00:00:00 2001 From: Wei Song Date: Thu, 27 Jun 2024 13:50:03 +0800 Subject: [PATCH] make the pending finish transaction db work with MT --- cache/coherence.hpp | 15 ++++------- util/multithread.hpp | 61 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/cache/coherence.hpp b/cache/coherence.hpp index a5fa171..071e6f7 100644 --- a/cache/coherence.hpp +++ b/cache/coherence.hpp @@ -302,16 +302,13 @@ template requires C_DERIVE pending_xact; // record the pending finish message from inner caches protected: using InnerCohPortBase::coh; using InnerCohPortBase::outer; using InnerCohPortBase::policy; public: - InnerCohPortT(policy_ptr policy) : IPUC(policy), addr_pending_finish(0) {} + InnerCohPortT(policy_ptr policy) : IPUC(policy) {} virtual ~InnerCohPortT() {} virtual std::pair probe_req(uint64_t addr, CMMetadataBase *meta, CMDataBase *data, coh_cmd_t cmd, uint64_t *delay) { @@ -329,16 +326,14 @@ class InnerCohPortT : public IPUC // record pending finish virtual void finish_record(uint64_t addr, coh_cmd_t outer_cmd) { - addr_pending_finish = addr; - id_pending_finish = outer_cmd.id; + pending_xact.insert(addr, outer_cmd.id); } // only forward the finish message recorded by previous acquire virtual void finish_resp(uint64_t addr, coh_cmd_t outer_cmd) { - assert(addr_pending_finish == 0 || (addr_pending_finish == addr && id_pending_finish == outer_cmd.id)); - if(addr_pending_finish == addr && id_pending_finish == outer_cmd.id) { + if(pending_xact.count(addr, outer_cmd.id)) { outer->finish_req(addr); - addr_pending_finish = 0; + pending_xact.remove(addr, outer_cmd.id); } } }; diff --git a/util/multithread.hpp b/util/multithread.hpp index 3491a23..1df8f81 100644 --- a/util/multithread.hpp +++ b/util/multithread.hpp @@ -1,6 +1,9 @@ #ifndef CM_UTIL_MULTITHREAD_HPP #define CM_UTIL_MULTITHREAD_HPP +#include +#include +#include #include #include #include @@ -48,4 +51,62 @@ class AtomicVar { } }; +// a database for recoridng the pending transactions +template +class PendingXact { + std::unordered_map db; + std::mutex mtx; +public: + PendingXact() {} + virtual ~PendingXact() {} + + void insert(uint64_t addr, uint32_t id) { + std::lock_guard lk(mtx); + if(!db.count(addr)) db[addr] = 0; + assert(0ull == (db[addr] & (1ull << id)) || 0 == + "The to be inserted pair has already been inserted in the database!"); + db[addr] |= (1ull << id); + } + + void remove(uint64_t addr, uint32_t id) { + std::lock_guard lk(mtx); + if(db.count(addr)) { + db[addr] &= ~(1ull << id); + if(db[addr] == 0) db.erase(addr); + } + } + + bool count(uint64_t addr, uint32_t id) { + std::lock_guard lk(mtx); + return db.count(addr) && (db[addr] & (1ull << id)); + } +}; + +// specialization for non-multithread env +template<> +class PendingXact { + + uint64_t addr; + int32_t id; + +public: + PendingXact(): addr(0), id(0) {} + virtual ~PendingXact() {} + + void insert(uint64_t addr, uint32_t id) { + this->addr = addr; + this->id = id; + } + + void remove(uint64_t addr, uint32_t id) { + if(count(addr, id)) this->addr = 0; + } + + bool count(uint64_t addr, uint32_t id) { + return this->addr == addr && this->id == id; + } +}; + + + #endif