diff --git a/src/sim/mem_pool.cc b/src/sim/mem_pool.cc index bde3e67b91..a7dc7c4631 100644 --- a/src/sim/mem_pool.cc +++ b/src/sim/mem_pool.cc @@ -124,4 +124,22 @@ MemPool::allocate(Addr npages) return return_addr; } +void +MemPool::serialize(CheckpointOut &cp) const +{ + paramOut(cp, "page_shift", pageShift); + paramOut(cp, "start_page", startPageNum); + paramOut(cp, "free_page_num", freePageNum); + paramOut(cp, "total_pages", _totalPages); +} + +void +MemPool::unserialize(CheckpointIn &cp) +{ + paramIn(cp, "page_shift", pageShift); + paramIn(cp, "start_page", startPageNum); + paramIn(cp, "free_page_num", freePageNum); + paramIn(cp, "total_pages", _totalPages); +} + } // namespace gem5 diff --git a/src/sim/mem_pool.hh b/src/sim/mem_pool.hh index 3cba3b6987..0b681cd051 100644 --- a/src/sim/mem_pool.hh +++ b/src/sim/mem_pool.hh @@ -35,6 +35,7 @@ #define __MEM_POOL_HH__ #include "base/types.hh" +#include "sim/serialize.hh" namespace gem5 { @@ -42,21 +43,23 @@ namespace gem5 class System; /** Class for handling allocation of physical pages in SE mode. */ -class MemPool +class MemPool : public Serializable { private: - Addr pageShift; + Addr pageShift = 0; /** Start page of pool. */ - Counter startPageNum; + Counter startPageNum = 0; /** Page number of free memory. */ - Counter freePageNum; + Counter freePageNum = 0; /** The size of the pool, in number of pages. */ - Counter _totalPages; + Counter _totalPages = 0; public: + MemPool() {} + MemPool(Addr page_shift, Addr ptr, Addr limit); Counter startPage() const; @@ -74,6 +77,9 @@ class MemPool Addr totalBytes() const; Addr allocate(Addr npages); + + void serialize(CheckpointOut &cp) const override; + void unserialize(CheckpointIn &cp) override; }; } // namespace gem5 diff --git a/src/sim/system.cc b/src/sim/system.cc index 225262a4ab..5196c7183a 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -44,6 +44,7 @@ #include #include "base/compiler.hh" +#include "base/cprintf.hh" #include "base/loader/object_file.hh" #include "base/loader/symtab.hh" #include "base/str.hh" @@ -68,6 +69,7 @@ #include "sim/debug.hh" #include "sim/full_system.hh" #include "sim/redirect_path.hh" +#include "sim/serialize_handlers.hh" namespace gem5 { @@ -430,16 +432,11 @@ System::serialize(CheckpointOut &cp) const paramOut(cp, csprintf("quiesceEndTick_%d", id), when); } - std::vector ptrs; - std::vector limits; + int num_mem_pools = memPools.size(); + SERIALIZE_SCALAR(num_mem_pools); - for (const auto& memPool : memPools) { - ptrs.push_back(memPool.freePageAddr()); - limits.push_back(memPool.totalBytes() + memPool.startAddr()); - } - - SERIALIZE_CONTAINER(ptrs); - SERIALIZE_CONTAINER(limits); + for (int i = 0; i < num_mem_pools; i++) + memPools[i].serializeSection(cp, csprintf("memPool%d", i)); // also serialize the memories in the system physmem.serializeSection(cp, "physmem"); @@ -461,15 +458,14 @@ System::unserialize(CheckpointIn &cp) # endif } - std::vector ptrs; - std::vector limits; + int num_mem_pools = 0; + UNSERIALIZE_SCALAR(num_mem_pools); - UNSERIALIZE_CONTAINER(ptrs); - UNSERIALIZE_CONTAINER(limits); - - assert(ptrs.size() == limits.size()); - for (size_t i = 0; i < ptrs.size(); i++) - memPools.emplace_back(getPageShift(), ptrs[i], limits[i]); + for (int i = 0; i < num_mem_pools; i++) { + MemPool pool; + pool.unserializeSection(cp, csprintf("memPool%d", i)); + memPools.push_back(pool); + } // also unserialize the memories in the system physmem.unserializeSection(cp, "physmem"); diff --git a/util/cpt_upgraders/mempool-sections.py b/util/cpt_upgraders/mempool-sections.py new file mode 100644 index 0000000000..8b0fd2a56b --- /dev/null +++ b/util/cpt_upgraders/mempool-sections.py @@ -0,0 +1,39 @@ +# This upgrader moves memory pool attributes from a vector of pointers to the +# next free page and a vector of the limit of each pool to sections which each +# represent one pool and which hold the page shift amount, the next free page, +# and the total pages in the pool. +def upgrader(cpt): + systems = {} + for sec in cpt.sections(): + ptrs = cpt.get(sec, 'ptrs', fallback=None) + limits = cpt.get(sec, 'limits', fallback=None) + + if ptrs and limits: + systems[sec] = ptrs, limits + + for sec, (ptrs, limits) in systems.items(): + + ptrs = list(map(int, ptrs.split())) + limits = list(map(int, limits.split())) + + if len(ptrs) != len(limits): + print( + f"'{sec}ptrs' and '{limits}limits' were not the same length!") + + cpt.set(sec, 'num_mem_pools', str(len(ptrs))) + + cpt.remove_option(sec, 'ptrs') + cpt.remove_option(sec, 'limits') + + # Assume the page shift is 12, for a 4KiB page. + page_shift = 12 + + for idx, (ptr, limit) in enumerate(zip(ptrs, limits)): + new_sec = f'{sec}.memPool{idx}' + cpt.add_section(new_sec) + cpt.set(new_sec, 'page_shift', str(page_shift)) + # Since there's no way to tell where the pool actually started, + # just assume it started wherever it is right now. + cpt.set(new_sec, 'start_page', str(ptr >> page_shift)) + cpt.set(new_sec, 'free_page_num', str(ptr >> page_shift)) + cpt.set(new_sec, 'total_pages', str((limit - ptr) >> page_shift))