mirror of
https://github.com/TomHarte/CLK.git
synced 2024-07-10 12:29:01 +00:00
Uses Disk::flush_tracks to elide replacement of dirty tracks.
This commit is contained in:
parent
97a2be71e3
commit
53b99ea248
@ -23,7 +23,9 @@ namespace Disk {
|
|||||||
|
|
||||||
class Disk {
|
class Disk {
|
||||||
public:
|
public:
|
||||||
virtual ~Disk() {}
|
virtual ~Disk() {
|
||||||
|
flush_tracks();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@returns the number of discrete positions that this disk uses to model its complete surface area.
|
@returns the number of discrete positions that this disk uses to model its complete surface area.
|
||||||
|
@ -66,6 +66,7 @@ class DiskImage {
|
|||||||
|
|
||||||
class DiskImageHolderBase: public Disk {
|
class DiskImageHolderBase: public Disk {
|
||||||
protected:
|
protected:
|
||||||
|
std::set<Track::Address> unwritten_tracks_;
|
||||||
std::map<Track::Address, std::shared_ptr<Track>> cached_tracks_;
|
std::map<Track::Address, std::shared_ptr<Track>> cached_tracks_;
|
||||||
std::unique_ptr<Concurrency::AsyncTaskQueue> update_queue_;
|
std::unique_ptr<Concurrency::AsyncTaskQueue> update_queue_;
|
||||||
};
|
};
|
||||||
|
@ -19,18 +19,30 @@ template <typename T> bool DiskImageHolder<T>::get_is_read_only() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void DiskImageHolder<T>::flush_tracks() {
|
template <typename T> void DiskImageHolder<T>::flush_tracks() {
|
||||||
|
if(!unwritten_tracks_.empty()) {
|
||||||
|
if(!update_queue_) update_queue_.reset(new Concurrency::AsyncTaskQueue);
|
||||||
|
|
||||||
|
using TrackMap = std::map<Track::Address, std::shared_ptr<Track>>;
|
||||||
|
std::shared_ptr<TrackMap> track_copies(new TrackMap);
|
||||||
|
for(auto &address : unwritten_tracks_) {
|
||||||
|
track_copies->insert(std::make_pair(address, cached_tracks_[address]->clone()));
|
||||||
|
}
|
||||||
|
unwritten_tracks_.clear();
|
||||||
|
|
||||||
|
update_queue_->enqueue([this, track_copies]() {
|
||||||
|
// TODO: communicate these as a batch, not one by one.
|
||||||
|
for(auto &pair : *track_copies) {
|
||||||
|
disk_image_.set_track_at_position(pair.first, pair.second);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void DiskImageHolder<T>::set_track_at_position(Track::Address address, const std::shared_ptr<Track> &track) {
|
template <typename T> void DiskImageHolder<T>::set_track_at_position(Track::Address address, const std::shared_ptr<Track> &track) {
|
||||||
if(disk_image_.get_is_read_only()) return;
|
if(disk_image_.get_is_read_only()) return;
|
||||||
|
|
||||||
|
unwritten_tracks_.insert(address);
|
||||||
cached_tracks_[address] = track;
|
cached_tracks_[address] = track;
|
||||||
|
|
||||||
if(!update_queue_) update_queue_.reset(new Concurrency::AsyncTaskQueue);
|
|
||||||
std::shared_ptr<Track> track_copy(track->clone());
|
|
||||||
update_queue_->enqueue([this, address, track_copy] {
|
|
||||||
disk_image_.set_track_at_position(address, track_copy);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> std::shared_ptr<Track> DiskImageHolder<T>::get_track_at_position(Track::Address address) {
|
template <typename T> std::shared_ptr<Track> DiskImageHolder<T>::get_track_at_position(Track::Address address) {
|
||||||
|
Loading…
Reference in New Issue
Block a user