mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-26 15:32:04 +00:00
Attempted to switch to an asynchronous means for continuous file updates. Testing with SSD, as usual.
This commit is contained in:
parent
bbd94749f4
commit
6fc692cd34
@ -21,7 +21,11 @@ void Disk::set_track_at_position(unsigned int head, unsigned int position, const
|
||||
|
||||
int address = get_id_for_track_at_position(head, position);
|
||||
cached_tracks_[address] = track;
|
||||
modified_tracks_.insert(address);
|
||||
|
||||
if(!update_queue_) update_queue_.reset(new Concurrency::AsyncTaskQueue);
|
||||
update_queue_->enqueue([this, head, position, track] {
|
||||
store_updated_track_at_position(head, position, track, file_access_mutex_);
|
||||
});
|
||||
}
|
||||
|
||||
std::shared_ptr<Track> Disk::get_track_at_position(unsigned int head, unsigned int position)
|
||||
@ -30,21 +34,15 @@ std::shared_ptr<Track> Disk::get_track_at_position(unsigned int head, unsigned i
|
||||
std::map<int, std::shared_ptr<Track>>::iterator cached_track = cached_tracks_.find(address);
|
||||
if(cached_track != cached_tracks_.end()) return cached_track->second;
|
||||
|
||||
std::lock_guard<std::mutex> lock_guard(file_access_mutex_);
|
||||
std::shared_ptr<Track> track = get_uncached_track_at_position(head, position);
|
||||
cached_tracks_[address] = track;
|
||||
return track;
|
||||
}
|
||||
|
||||
std::shared_ptr<Track> Disk::get_modified_track_at_position(unsigned int head, unsigned int position)
|
||||
{
|
||||
int address = get_id_for_track_at_position(head, position);
|
||||
if(modified_tracks_.find(address) == modified_tracks_.end()) return nullptr;
|
||||
std::map<int, std::shared_ptr<Track>>::iterator cached_track = cached_tracks_.find(address);
|
||||
if(cached_track == cached_tracks_.end()) return nullptr;
|
||||
return cached_track->second;
|
||||
}
|
||||
void Disk::store_updated_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track, std::mutex &file_access_mutex) {}
|
||||
|
||||
bool Disk::get_is_modified()
|
||||
void Disk::flush_updates()
|
||||
{
|
||||
return !modified_tracks_.empty();
|
||||
if(update_queue_) update_queue_->flush();
|
||||
}
|
||||
|
@ -9,10 +9,13 @@
|
||||
#ifndef Disk_hpp
|
||||
#define Disk_hpp
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
|
||||
#include "../Storage.hpp"
|
||||
#include "../../Concurrency/AsyncTaskQueue.hpp"
|
||||
|
||||
namespace Storage {
|
||||
namespace Disk {
|
||||
@ -107,20 +110,15 @@ class Disk {
|
||||
*/
|
||||
virtual std::shared_ptr<Track> get_uncached_track_at_position(unsigned int head, unsigned int position) = 0;
|
||||
|
||||
/*!
|
||||
@returns @c true if any calls to set_track_at_position occurred; @c false otherwise.
|
||||
*/
|
||||
bool get_is_modified();
|
||||
|
||||
/*!
|
||||
@returns the @c Track at @c position underneath @c head if a modification was written there.
|
||||
*/
|
||||
std::shared_ptr<Track> get_modified_track_at_position(unsigned int head, unsigned int position);
|
||||
virtual void store_updated_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track, std::mutex &file_access_mutex);
|
||||
void flush_updates();
|
||||
|
||||
private:
|
||||
std::map<int, std::shared_ptr<Track>> cached_tracks_;
|
||||
std::set<int> modified_tracks_;
|
||||
int get_id_for_track_at_position(unsigned int head, unsigned int position);
|
||||
std::mutex file_access_mutex_;
|
||||
std::unique_ptr<Concurrency::AsyncTaskQueue> update_queue_;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -39,25 +39,26 @@ AcornADF::AcornADF(const char *file_name) :
|
||||
|
||||
AcornADF::~AcornADF()
|
||||
{
|
||||
if(get_is_modified())
|
||||
{
|
||||
for(unsigned int head = 0; head < get_head_count(); head++)
|
||||
{
|
||||
for(unsigned int track = 0; track < get_head_position_count(); track++)
|
||||
{
|
||||
std::shared_ptr<Storage::Disk::Track> modified_track = get_modified_track_at_position(head, track);
|
||||
if(modified_track)
|
||||
{
|
||||
Storage::Encodings::MFM::Parser parser(true, modified_track);
|
||||
for(unsigned int c = 0; c < sectors_per_track; c++)
|
||||
{
|
||||
std::shared_ptr<Storage::Encodings::MFM::Sector> sector = parser.get_sector((uint8_t)track, (uint8_t)c);
|
||||
printf("Sector %d: %p\n", c, sector.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
flush_updates();
|
||||
// if(get_is_modified())
|
||||
// {
|
||||
// for(unsigned int head = 0; head < get_head_count(); head++)
|
||||
// {
|
||||
// for(unsigned int track = 0; track < get_head_position_count(); track++)
|
||||
// {
|
||||
// std::shared_ptr<Storage::Disk::Track> modified_track = get_modified_track_at_position(head, track);
|
||||
// if(modified_track)
|
||||
// {
|
||||
// Storage::Encodings::MFM::Parser parser(true, modified_track);
|
||||
// for(unsigned int c = 0; c < sectors_per_track; c++)
|
||||
// {
|
||||
// std::shared_ptr<Storage::Encodings::MFM::Sector> sector = parser.get_sector((uint8_t)track, (uint8_t)c);
|
||||
// printf("Sector %d: %p\n", c, sector.get());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
unsigned int AcornADF::get_head_position_count()
|
||||
|
@ -32,27 +32,10 @@ SSD::SSD(const char *file_name) :
|
||||
|
||||
SSD::~SSD()
|
||||
{
|
||||
if(get_is_modified())
|
||||
{
|
||||
for(unsigned int head = 0; head < head_count_; head++)
|
||||
{
|
||||
for(unsigned int track = 0; track < track_count_; track++)
|
||||
{
|
||||
std::shared_ptr<Storage::Disk::Track> modified_track = get_modified_track_at_position(head, track);
|
||||
if(modified_track)
|
||||
{
|
||||
Storage::Encodings::MFM::Parser parser(false, modified_track);
|
||||
for(unsigned int c = 0; c < 10; c++)
|
||||
{
|
||||
std::shared_ptr<Storage::Encodings::MFM::Sector> sector = parser.get_sector((uint8_t)track, (uint8_t)c);
|
||||
printf("Sector %d: %p\n", c, sector.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
flush_updates();
|
||||
}
|
||||
|
||||
|
||||
unsigned int SSD::get_head_position_count()
|
||||
{
|
||||
return track_count_;
|
||||
@ -68,13 +51,17 @@ bool SSD::get_is_read_only()
|
||||
return is_read_only_;
|
||||
}
|
||||
|
||||
long SSD::get_file_offset_for_position(unsigned int head, unsigned int position)
|
||||
{
|
||||
return (position * head_count_ + head) * 256 * 10;
|
||||
}
|
||||
|
||||
std::shared_ptr<Track> SSD::get_uncached_track_at_position(unsigned int head, unsigned int position)
|
||||
{
|
||||
std::shared_ptr<Track> track;
|
||||
|
||||
if(head >= head_count_) return track;
|
||||
long file_offset = (position * head_count_ + head) * 256 * 10;
|
||||
fseek(file_, file_offset, SEEK_SET);
|
||||
fseek(file_, get_file_offset_for_position(head, position), SEEK_SET);
|
||||
|
||||
std::vector<Storage::Encodings::MFM::Sector> sectors;
|
||||
for(int sector = 0; sector < 10; sector++)
|
||||
@ -99,3 +86,25 @@ std::shared_ptr<Track> SSD::get_uncached_track_at_position(unsigned int head, un
|
||||
|
||||
return track;
|
||||
}
|
||||
|
||||
void SSD::store_updated_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track, std::mutex &file_access_mutex)
|
||||
{
|
||||
std::vector<uint8_t> parsed_track;
|
||||
Storage::Encodings::MFM::Parser parser(false, track);
|
||||
for(unsigned int c = 0; c < 10; c++)
|
||||
{
|
||||
std::shared_ptr<Storage::Encodings::MFM::Sector> sector = parser.get_sector((uint8_t)position, (uint8_t)c);
|
||||
if(sector)
|
||||
{
|
||||
parsed_track.insert(parsed_track.end(), sector->data.begin(), sector->data.end());
|
||||
}
|
||||
else
|
||||
{
|
||||
parsed_track.resize(parsed_track.size() + 256);
|
||||
}
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock_guard(file_access_mutex);
|
||||
fseek(file_, get_file_offset_for_position(head, position), SEEK_SET);
|
||||
fwrite(parsed_track.data(), 1, parsed_track.size(), file_);
|
||||
}
|
||||
|
@ -39,7 +39,9 @@ class SSD: public Disk, public Storage::FileHolder {
|
||||
bool get_is_read_only();
|
||||
|
||||
private:
|
||||
void store_updated_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track, std::mutex &file_access_mutex);
|
||||
std::shared_ptr<Track> get_uncached_track_at_position(unsigned int head, unsigned int position);
|
||||
long get_file_offset_for_position(unsigned int head, unsigned int position);
|
||||
unsigned int head_count_;
|
||||
unsigned int track_count_;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user