10#include "sparta/functional/ArchData.hpp"
15#include "sparta/serialization/checkpoint/Checkpointer.hpp"
19namespace sparta::serialization::checkpoint
30 std::unique_ptr<char []> data_;
37 Segment(
const Segment&) =
delete;
42 Segment(Segment&& rhp) :
44 data_(std::move(rhp.data_)),
62 Segment& operator=(
const Segment& rhp) =
delete;
68 idx_(idx), bytes_(bytes)
71 "Attempted to create segment of " << bytes <<
" bytes with invalid line index");
72 data_.reset(
new char[bytes]);
73 ::memcpy(data_.get(), data, bytes);
80 uint32_t getSize()
const {
81 return sizeof(
decltype(*this)) + bytes_;
84 void copyTo(
char* buf, uint32_t size)
const {
86 "Attempted to restore checkpoint data for a line where the "
87 "data was " << bytes_ <<
" bytes but the loader requested "
88 << size <<
" bytes. The sizes must match up or something is "
90 memcpy(buf, data_.get(), bytes_);
93 void dump(std::ostream& o)
const {
95 std::cout <<
"\nEnd of ArchData";
99 std::cout <<
"\nLine: " << std::dec << idx_ <<
" (" << bytes_ <<
") bytes";
100 for(uint32_t off = 0; off < bytes_;){
101 char chr = data_[off];
103 o << std::endl << std::setw(7) << std::hex << off;
108 o <<
' ' << std::setfill(
'0') << std::setw(2) << std::hex << (0xff & (uint16_t)chr);
118 std::vector<Segment> data_;
128 uint32_t next_restore_idx_ = 0;
134 decltype(data_)::const_iterator cur_restore_itr_;
143 void dump(std::ostream& o)
const {
144 for(
auto const &seg : data_){
149 uint32_t getSize()
const {
150 uint32_t bytes =
sizeof(
decltype(*this));
151 for(Segment
const & seg : data_){
152 bytes += seg.getSize();
157 void prepareForLoad() {
158 next_restore_idx_ = 0;
159 cur_restore_itr_ = data_.begin();
164 "Cannot begin line with INVALID_LINE_IDX index");
168 void writeLineBytes(
const char* data,
size_t size) {
169 sparta_assert(data_.size() == 0 || data_.back().getLineIdx() != next_idx_,
170 "Cannot store the same line idx twice in a checkpoint. Line "
171 << next_idx_ <<
" detected twice in a row");
173 "Cannot write line bytes with INVALID_LINE_IDX index");
174 data_.emplace_back(next_idx_, data, size);
181 data_.emplace_back();
189 return next_restore_idx_ <= data_.size();
197 if(next_restore_idx_ == data_.size()){
200 }
else if(next_restore_idx_ > data_.size()){
202 <<
"caller tried to keep getting next line even after "
203 "reaching the end of the restore data";
205 if(next_restore_idx_ != 0){
210 const auto next_line_idx = cur_restore_itr_->getLineIdx();
211 return next_line_idx;
219 "Attempted to copy line bytes from an invalid line iterator");
221 "About to return line from checkpoint data segment with INVALID_LINE_IDX index");
222 cur_restore_itr_->copyTo(buf, size);
242 std::stringstream ss_;
246 ss_.exceptions(std::ostream::eofbit | std::ostream::badbit |
247 std::ostream::failbit | std::ostream::goodbit);
250 void dump(std::ostream& o)
const {
252 auto itr = s.begin();
253 for(; itr != s.end(); itr++){
258 strncpy((
char*)&ln_idx, s.substr(itr-s.begin(),
sizeof(ln_idx)).c_str(),
sizeof(ln_idx));
259 std::cout <<
"\nLine: " << ln_idx << std::endl;
262 for(uint16_t i=0; i<64; ++i){
265 o << std::setw(7) << std::hex << off;
270 o <<
' ' << std::setfill(
'0') << std::setw(2) << std::hex << (0xff & (uint16_t)chr);
282 uint32_t getSize()
const {
283 return ss_.str().size() +
sizeof(
decltype(*this));
286 void prepareForLoad() {
297 void writeLineBytes(
const char* data,
size_t size) {
298 ss_.write(data, size);
308 "Ostream error while writing checkpoint data");
327 "Encountered checkpoint data stream error or eof");
330 ss_.read((
char*)&ln_idx,
sizeof(ln_idx));
332 }
else if(ctrl ==
'E'){
336 << ctrl <<
"' control character was found where an 'L' or 'E' was found";
350 class FastCheckpointer;
370 template<
typename StorageT=storage::StringStreamStorage>
420 const std::vector<ArchData*>& dats,
427 is_snapshot_(is_snapshot)
430 if(
nullptr == prev_delta){
431 if(is_snapshot ==
false){
433 <<
id <<
" at tick=" << tick <<
" which has no prev_delta and is not a snapshot";
441 storeSnapshot_(dats);
461 std::cerr <<
"WARNING: DeltaCheckpoint " <<
getID()
462 <<
" being destructed without being allowed to delete" << std::endl;
473 std::stringstream ss;
474 ss <<
"<DeltaCheckpoint id=";
494 virtual void dumpData(std::ostream& o)
const override {
532 +
sizeof(
decltype(*this)) \
533 + (
getNexts().size() *
sizeof(
typename std::remove_reference<
decltype(*this)>::type*));
540 return data_.getSize();
550 void traceValue(std::ostream& o,
const std::vector<ArchData*>& dats,
551 const ArchData* container, uint32_t offset, uint32_t size)
555 std::vector<std::pair<uint8_t,bool>> bytes;
556 bytes.resize(size,
decltype(bytes)::value_type(0,
false));
558 constexpr uint32_t BUF_SIZE = 8192*2;
559 std::unique_ptr<char[]> buf(
new char[BUF_SIZE]);
561 while(!dcps.empty()){
565 d->data_.prepareForLoad();
566 bool found_ad =
false;
567 bool changed =
false;
572 for(
auto &x : bytes){
578 auto ln_idx = d->data_.getNextRestoreLine();
587 auto ln_off = ln_idx * ad->getLineSize();
589 "Cannot trace value on ArchDatas with line sizes > " << BUF_SIZE <<
" (" << ad->getLineSize() <<
")");
590 d->data_.copyLineBytes((
char*)buf.get(), ad->getLineSize());
594 if(offset >= ln_off && offset < ln_off + ad->getLineSize()){
596 "Cannot trace value which spans multiple lines!");
598 "Value being traced changed twice in the same checkpoint");
600 auto off_in_line = offset - ln_off;
601 o <<
"trace: Value changed (line " << std::dec << ln_idx <<
")" << std::endl;
602 for(uint32_t i=0; i<bytes.size(); i++){
603 bytes[i].first = buf.get()[i+off_in_line];
604 bytes[i].second =
true;
611 o <<
"trace: Could not find selected ArchData " << (
const void*)container <<
" in this checkpoint!" << std::endl;
613 o <<
"trace: Value:";
614 for(uint32_t i=0; i<bytes.size(); i++){
616 o <<
' ' << std::setfill(
'0') << std::setw(2) << std::hex << (uint16_t)bytes[i].first;
636 std::stack<DeltaCheckpoint*> dcps;
652 std::stack<DeltaCheckpoint*> dcps;
669 std::stack<const DeltaCheckpoint*> dcps;
687 virtual void load(
const std::vector<ArchData*>& dats)
override {
692 while(!dcps.empty()){
733 "Cannot delete a checkpoint when it is already deleted: " <<
this);
734 deleted_id_ =
getID();
765 std::stringstream ss;
803#pragma clang diagnostic push
804#pragma clang diagnostic ignored "-Wexceptions"
805#elif defined __GNUC__
806#pragma GCC diagnostic push
809#pragma GCC diagnostic ignored "-Wterminate"
814 throw CheckpointError() <<
"In getDistanceToPrevious, somehow reached null "
815 <<
"previous-checkpoint without encountering a snapshot. This should "
816 <<
"never occur and is a critical error";
818#pragma clang diagnostic pop
819#elif defined __GNUC__
820#pragma GCC diagnostic pop
843 data_.prepareForLoad();
845 "Attempted to loadState from a DeltaCheckpoint with a bad data buffer");
849 ad->restoreAll(data_);
871 void storeSnapshot_(
const std::vector<ArchData*>& dats) {
873 "Attempted to storeSnapshot_ from a DeltaCheckpoint with a bad data buffer");
887 void storeDelta_(
const std::vector<ArchData*>& dats) {
889 "Attempted to storeDelta_ from a DeltaCheckpoint with a bad data buffer");
907 bool const is_snapshot_;
File that contains checkpoint exception types.
A simple time-based, event precedence based scheduler.
Set of macros for Sparta assertions. Caught by the framework.
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
Exception class for all of Sparta.
Basic Node framework in sparta device tree composite pattern.
Contains a set of contiguous line of architectural data which can be referred to by any architected o...
static const line_idx_type INVALID_LINE_IDX
Invalid line index.
offset_type line_idx_type
Represents offsets into this ArchData.
Used to construct and throw a standard C++ exception. Inherits from std::exception.
Node in a composite tree representing a sparta Tree item.
Indicates that there was an issue operating on checkpoints within the SPARTA framework.
Single checkpoint object interface with a tick number and an ID unique to the owning Checkpointer ins...
Checkpoint * getPrev() const noexcept
Returns the previous checkpoint. If this checkpoint is a snapshot, it has no previous checkpoint.
const std::vector< Checkpoint * > & getNexts() const noexcept
Returns next checkpoint following *this. May be an empty vector if there are no later checkpoints fol...
chkpt_id_t getID() const noexcept
Returns the ID of this checkpoint.
tick_t getTick() const noexcept
Returns the tick number at which this checkpoint was taken.
sparta::Scheduler::Tick tick_t
tick_t Tick type to which checkpoints will refer
void addNext(Checkpoint *next)
Adds another next checkpoint following *this.
void setID_(chkpt_id_t id)
Sets the checkpoint ID.
uint64_t chkpt_id_t
tick_t Tick type to which checkpoints will refer
static const chkpt_id_t UNIDENTIFIED_CHECKPOINT
Indicates unidentified checkpoint (could mean 'invalid' or 'any') depending on context.
Single delta checkpoint object containing all simulator state which changed since some previous Delta...
chkpt_id_t getDeletedID() const noexcept
Return the ID had by this checkpoint before it was deleted If this checkpoint has not been flagged fo...
virtual void dumpData(std::ostream &o) const override
Writes all checkpoint raw data to an ostream.
DeltaCheckpoint()=delete
Not default constructable.
std::stack< DeltaCheckpoint * > getHistoryChain()
Returns a stack of checkpoints from this checkpoint as far back as possible until no previous link is...
bool isSnapshot() const noexcept
Is this checkpoint a snapshot (contains ALL simulator state)
std::stack< const DeltaCheckpoint * > getRestoreChain() const
Const-qualified version of getRestoreChain.
bool isFlaggedDeleted() const noexcept
Indicates whether this checkpoint has been flagged deleted.
virtual std::string getDeletedRepr() const override
Gets the representation of this deleted checkpoint as part of a checkpoint chain (if that checkpointe...
virtual ~DeltaCheckpoint()
Destructor.
std::stack< DeltaCheckpoint * > getRestoreChain()
Returns a stack of checkpoints that must be restored from top-to-bottom to fully restore the state as...
virtual void load(const std::vector< ArchData * > &dats) override
Attempts to restore this checkpoint including any previous deltas (dependencies).
bool canDelete() const noexcept
Can this checkpoint be deleted Cannot be deleted if:
void traceValue(std::ostream &o, const std::vector< ArchData * > &dats, const ArchData *container, uint32_t offset, uint32_t size)
Implement trace of a value across the restore chain as described in Checkpointer::traceValue.
void flagDeleted()
Allows this checkpoint to be deleted if it is no longer a previous delta of some other delta (i....
const DeltaCheckpoint & operator=(const DeltaCheckpoint &)=delete
Non-assignable.
void loadState(const std::vector< ArchData * > &dats)
Loads delta state of this checkpoint to root. Does not look at any other checkpoints checkpoints.
DeltaCheckpoint(const DeltaCheckpoint &)=delete
Not copy constructable.
virtual uint64_t getContentMemoryUse() const noexcept override
Returns memory usage by the content of this checkpoint.
virtual uint64_t getTotalMemoryUse() const noexcept override
Returns memory usage by this checkpoint.
virtual std::string stringize() const override
Returns a string describing this object.
uint32_t getDistanceToPrevSnapshot() const noexcept
Determines how many checkpoints away the closest, earlier snapshot is.
void dumpRestoreChain(std::ostream &o) const
Dumps the restore chain for this checkpoint.
Implements quick checkpointing through delta-checkpoint trees which store state-deltas in a compact f...
Stringstream storage implementation.
void copyLineBytes(char *buf, uint32_t size)
Read bytes for the current line.
void endArchData()
Signals end of this checkpoint's data.
bool good() const
Is the reading state of this storage good? (i.e. haven't tried to read past the end of the data)
ArchData::line_idx_type getNextRestoreLine()
Restore next line. Return ArchData::INVALID_LINE_IDX on end of data.
Vector of buffers storage implementation.
ArchData::line_idx_type getNextRestoreLine()
Restore next line. Return ArchData::INVALID_LINE_IDX on end of data.
void copyLineBytes(char *buf, uint32_t size)
Read bytes for the current line.
bool good() const
Is the reading state of this storage good? (i.e. haven't tried to read past the end of the data)
void endArchData()
Signals end of this checkpoint's data for one ArchData.