1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-07 08:28:57 +00:00

Attempted to switch to an asynchronous means for continuous file updates. Testing with SSD, as usual.

This commit is contained in:
Thomas Harte 2016-12-29 22:15:58 -05:00
parent bbd94749f4
commit 6fc692cd34
5 changed files with 69 additions and 61 deletions

View File

@ -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();
}

View File

@ -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_;
};
}

View File

@ -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()

View File

@ -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_);
}

View 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_;
};