# HG changeset patch # User Paul Boddie # Date 1611512947 -3600 # Node ID ebe5228f5056e1b73f69f6dfc987bdb6ef827425 # Parent a8b8a0d1b148e33bbcf49c835e012fe3118b9afc Introduced usage of an opener to obtain a file pager. diff -r a8b8a0d1b148 -r ebe5228f5056 Makefile --- a/Makefile Sun Jan 24 01:29:41 2021 +0100 +++ b/Makefile Sun Jan 24 19:29:07 2021 +0100 @@ -36,12 +36,13 @@ dstest_client.cc memory_utils.cc PLAIN_SRC_CC_dstest_server = \ - access_map.cc accessor.cc \ + access_map.cc accessing.cc accessor.cc \ dstest_server.cc flexpage.cc file_pager.cc \ ipc.cc memory.cc memory_map.cc memory_utils.cc \ - page_mapper.cc page_queue.cc pager.cc pages.cc \ + opener.cc opener_context.cc \ + page_mapper.cc page_queue.cc pager.cc pages.cc paging.cc \ region.cc resource.cc simple_pager.cc \ - test_file_accessor.cc + test_file_accessor.cc test_file_opener.cc # Normal definitions. diff -r a8b8a0d1b148 -r ebe5228f5056 accessing.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accessing.cc Sun Jan 24 19:29:07 2021 +0100 @@ -0,0 +1,41 @@ +#include "accessing.h" + +/* Reserve this mapping and return whether 'fileid' is associated with an + accessor. */ + +bool Accessing::reserve(fileid_t fileid) +{ + _lock.lock(); + + return _accessors.find(fileid) != _accessors.end(); +} + +/* Return the accessor for 'fileid' and release this mapping. */ + +Accessor *Accessing::get(fileid_t fileid) +{ + FileMapping::iterator entry = _accessors.find(fileid); + Accessor *accessor; + + if (entry == _accessors.end()) + accessor = NULL; + else + accessor = entry->second; + + _lock.unlock(); + return accessor; +} + +/* Associate 'fileid' with the given 'accessor' and release this mapping. */ + +void Accessing::set(fileid_t fileid, Accessor *accessor) +{ + FileMapping::iterator entry = _accessors.find(fileid); + + if (entry == _accessors.end()) + _accessors[fileid] = accessor; + + _lock.unlock(); +} + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r a8b8a0d1b148 -r ebe5228f5056 accessing.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accessing.h Sun Jan 24 19:29:07 2021 +0100 @@ -0,0 +1,33 @@ +#pragma once + +#include +#include + +#include "accessor.h" + + + +/* Mapping type from file identifiers to accessors. */ + +typedef std::map FileMapping; +typedef std::pair FileMappingEntry; + + + +/* A registry of accessors for files. */ + +class Accessing +{ +protected: + FileMapping _accessors; + std::mutex _lock; + +public: + bool reserve(fileid_t fileid); + + Accessor *get(fileid_t fileid); + + void set(fileid_t fileid, Accessor *accessor); +}; + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r a8b8a0d1b148 -r ebe5228f5056 dstest_server.cc --- a/dstest_server.cc Sun Jan 24 01:29:41 2021 +0100 +++ b/dstest_server.cc Sun Jan 24 19:29:07 2021 +0100 @@ -28,42 +28,29 @@ #include +#include "accessing.h" #include "mapped_file_object_server.h" -#include "page_mapper.h" +#include "memory_utils.h" #include "file_pager.h" #include "pages.h" -#include "test_file_accessor.h" +#include "paging.h" +#include "test_file_opener.h" -/* A component exposing the dataspace and mapped file interfaces. */ - -class MappedFileServer : public FilePager, public MappedFileObject -{ -public: - explicit MappedFileServer(fileid_t fileid, PageMapper *mapper) - : FilePager(fileid, mapper) - { - } - - virtual long map(unsigned long offset, l4_addr_t hot_spot, unsigned long flags, l4_snd_fpage_t *region) - { return FilePager::map(offset, hot_spot, flags, region); } - - virtual long mmap(size_t position, size_t length, size_t *start_pos, size_t *end_pos, size_t *data_end) - { return FilePager::mmap(position, length, start_pos, end_pos, data_end); } -}; - - +const unsigned int MEMORY_PAGES = 10; +const unsigned int FILE_PAGES = 20; int main(void) { - /* Some memory. */ + /* Some memory plus infrastructure. */ - Memory mem(10); + Memory mem(MEMORY_PAGES); + Accessing accessing; + Paging paging; Pages pages(&mem); - TestFileAccessor a(123UL); - PageMapper m(&a, &pages); - MappedFileServer obj(123UL, &m); + TestFileOpener opener(&accessing, &paging, &pages, page(FILE_PAGES)); + FilePager *obj = opener.open("123"); /* Server capability. */ @@ -71,7 +58,7 @@ /* Register a server associating it with the given object. */ - long err = ipc_server_bind("server", (l4_umword_t) &obj, &server); + long err = ipc_server_bind("server", (l4_umword_t) obj, &server); if (err) { @@ -81,7 +68,7 @@ /* Wait for messages, dispatching to the handler. */ - ipc_server_loop_for(MappedFileObject, &obj); + ipc_server_loop_for(MappedFileObject, obj); return 0; } diff -r a8b8a0d1b148 -r ebe5228f5056 file_pager.h --- a/file_pager.h Sun Jan 24 01:29:41 2021 +0100 +++ b/file_pager.h Sun Jan 24 19:29:07 2021 +0100 @@ -1,16 +1,20 @@ #pragma once +#include "mapped_file_object_interface.h" #include "pager.h" /* A pager abstraction for a file. */ -class FilePager : public Pager +class FilePager : public Pager, public MappedFileObject { public: fileid_t fileid; explicit FilePager(fileid_t fileid, PageMapper *mapper); + virtual long map(unsigned long offset, l4_addr_t hot_spot, unsigned long flags, l4_snd_fpage_t *region) + { return Pager::map(offset, hot_spot, flags, region); } + virtual long mmap(size_t position, size_t length, size_t *start_pos, size_t *end_pos, size_t *data_end); }; diff -r a8b8a0d1b148 -r ebe5228f5056 opener.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/opener.cc Sun Jan 24 19:29:07 2021 +0100 @@ -0,0 +1,63 @@ +#include "opener.h" + +/* Support for providing access to files. */ + +Opener::Opener(Accessing *accessing, Paging *paging, Pages *pages) +: _accessing(accessing), _paging(paging), _pages(pages) +{ +} + +OpenerContext *Opener::context() +{ + return new OpenerContext(this); +} + +FilePager *Opener::open(const char *path) +{ + fileid_t fileid = get_fileid(path); + + if (fileid == FILEID_INVALID) + return NULL; + + Accessor *accessor = get_accessor(fileid); + PageMapper *mapper = get_mapper(accessor); + return new FilePager(fileid, mapper); +} + +/* Obtain an accessor for the 'fileid' or register a new one in the accessing + object. */ + +Accessor *Opener::get_accessor(fileid_t fileid) +{ + Accessor *accessor; + + if (_accessing->reserve(fileid)) + accessor = _accessing->get(fileid); + else + { + accessor = make_accessor(fileid); + _accessing->set(fileid, accessor); + } + + return accessor; +} + +/* Obtain a page mapper for the 'accessor' or register a new one in the + paging object. */ + +PageMapper *Opener::get_mapper(Accessor *accessor) +{ + PageMapper *mapper; + + if (_paging->reserve(accessor)) + mapper = _paging->get(accessor); + else + { + mapper = new PageMapper(accessor, _pages); + _paging->set(accessor, mapper); + } + + return mapper; +} + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r a8b8a0d1b148 -r ebe5228f5056 opener.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/opener.h Sun Jan 24 19:29:07 2021 +0100 @@ -0,0 +1,39 @@ +#pragma once + +#include "accessing.h" +#include "file_pager.h" +#include "opener_context.h" +#include "pager.h" +#include "paging.h" +#include "pages.h" + +/* Support for providing access to files. */ + +class Opener +{ +protected: + Accessing *_accessing; + Paging *_paging; + Pages *_pages; + + /* Convenience methods. */ + + Accessor *get_accessor(fileid_t fileid); + + PageMapper *get_mapper(Accessor *accessor); + + /* Configurable methods. */ + + virtual fileid_t get_fileid(const char *path) = 0; + + virtual Accessor *make_accessor(fileid_t fileid) = 0; + +public: + explicit Opener(Accessing *accessing, Paging *paging, Pages *pages); + + OpenerContext *context(); + + FilePager *open(const char *path); +}; + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r a8b8a0d1b148 -r ebe5228f5056 opener_context.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/opener_context.cc Sun Jan 24 19:29:07 2021 +0100 @@ -0,0 +1,21 @@ +#include "opener.h" +#include "opener_context.h" + +/* Support for providing access to files. */ + +OpenerContext::OpenerContext(Opener *opener, Memory *memory) +: SimplePager(memory), _opener(opener) +{ +} + +FilePager *OpenerContext::open() +{ + return _opener->open(get_path()); +} + +char *OpenerContext::get_path() +{ + return _region->read(); +} + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r a8b8a0d1b148 -r ebe5228f5056 opener_context.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/opener_context.h Sun Jan 24 19:29:07 2021 +0100 @@ -0,0 +1,29 @@ +#pragma once + +#include "file_pager.h" +#include "simple_pager.h" + + + +/* Forward declaration. */ + +class Opener; + + + +/* Support for indicating files to be opened. */ + +class OpenerContext : public SimplePager +{ +protected: + Opener *_opener; + +public: + explicit OpenerContext(Opener *opener, Memory *memory=NULL); + + FilePager *open(); + + char *get_path(); +}; + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r a8b8a0d1b148 -r ebe5228f5056 paging.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paging.cc Sun Jan 24 19:29:07 2021 +0100 @@ -0,0 +1,34 @@ +#include "paging.h" + +bool Paging::reserve(Accessor *accessor) +{ + _lock.lock(); + + return _mappers.find(accessor) != _mappers.end(); +} + +PageMapper *Paging::get(Accessor *accessor) +{ + AccessorMapping::iterator entry = _mappers.find(accessor); + PageMapper *mapper; + + if (entry == _mappers.end()) + mapper = NULL; + else + mapper = entry->second; + + _lock.unlock(); + return mapper; +} + +void Paging::set(Accessor *accessor, PageMapper *mapper) +{ + AccessorMapping::iterator entry = _mappers.find(accessor); + + if (entry == _mappers.end()) + _mappers[accessor] = mapper; + + _lock.unlock(); +} + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r a8b8a0d1b148 -r ebe5228f5056 paging.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paging.h Sun Jan 24 19:29:07 2021 +0100 @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +#include "accessor.h" +#include "page_mapper.h" + + + +/* Mapping type from accessors to page mappers. */ + +typedef std::map AccessorMapping; +typedef std::pair AccessorMappingEntry; + + + +/* A registry of mappers for accessors. */ + +class Paging +{ +protected: + AccessorMapping _mappers; + std::mutex _lock; + +public: + bool reserve(Accessor *accessor); + + PageMapper *get(Accessor *accessor); + + void set(Accessor *accessor, PageMapper *mapper); +}; + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r a8b8a0d1b148 -r ebe5228f5056 test_file_opener.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test_file_opener.cc Sun Jan 24 19:29:07 2021 +0100 @@ -0,0 +1,30 @@ +#include "test_file_accessor.h" +#include "test_file_opener.h" + +#include + +/* Support for providing access to files. */ + +TestFileOpener::TestFileOpener(Accessing *accessing, Paging *paging, Pages *pages, + offset_t file_size) +: Opener(accessing, paging, pages), _file_size(file_size) +{ +} + +/* Return a file identifier for the given 'path'. */ + +fileid_t TestFileOpener::get_fileid(const char *path) +{ + /* NOTE: Just convert the path to a number. */ + + return atol(path); +} + +/* Return a new accessor for 'fileid'. */ + +Accessor *TestFileOpener::make_accessor(fileid_t fileid) +{ + return new TestFileAccessor(fileid, _file_size); +} + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r a8b8a0d1b148 -r ebe5228f5056 test_file_opener.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test_file_opener.h Sun Jan 24 19:29:07 2021 +0100 @@ -0,0 +1,23 @@ +#pragma once + +#include "opener.h" + +/* Support for providing access to files. */ + +class TestFileOpener : public Opener +{ +protected: + offset_t _file_size; + + /* Configurable methods. */ + + virtual fileid_t get_fileid(const char *path); + + virtual Accessor *make_accessor(fileid_t fileid); + +public: + explicit TestFileOpener(Accessing *accessing, Paging *paging, Pages *pages, + offset_t file_size=0); +}; + +// vim: tabstop=4 expandtab shiftwidth=4