1.1 --- a/Makefile Sat Mar 27 00:55:05 2021 +0100
1.2 +++ b/Makefile Sat Mar 27 01:42:25 2021 +0100
1.3 @@ -53,7 +53,7 @@
1.4
1.5 PLAIN_SRC_CC_common_server = \
1.6 access_map.cc accessing.cc accessor.cc \
1.7 - flexpage.cc file_pager.cc ipc.cc memory.cc \
1.8 + flexpage.cc files/file_pager.cc ipc.cc memory.cc \
1.9 opener_resource.cc opener_context_resource.cc \
1.10 page_mapper.cc page_queue_partitioned.cc page_queue_shared.cc \
1.11 pager.cc paging.cc \
1.12 @@ -74,8 +74,8 @@
1.13 PLAIN_SRC_CC_dstest_pipe_server = \
1.14 $(PLAIN_SRC_CC_common_server) \
1.15 dstest_pipe_server.cc \
1.16 - pipe_opener_resource.cc pipe_pager.cc \
1.17 - files/pipe_accessor.cc files/pipe_paging.cc
1.18 + pipes/pipe_opener_resource.cc pipes/pipe_pager.cc \
1.19 + pipes/pipe_accessor.cc pipes/pipe_paging.cc
1.20
1.21 PLAIN_SRC_CC_dstest_test_server = \
1.22 $(PLAIN_SRC_CC_common_server) \
1.23 @@ -126,7 +126,8 @@
1.24
1.25 REQUIRES_LIBS = l4re_c-util libipc libstdc++ libsystypes
1.26
1.27 -PRIVATE_INCDIR = $(PKGDIR) $(PKGDIR)/files $(IDL_BUILD_DIR) $(IDL_EXPORT_DIR)
1.28 +PRIVATE_INCDIR = $(PKGDIR) $(PKGDIR)/files $(PKGDIR)/pipes \
1.29 + $(IDL_BUILD_DIR) $(IDL_EXPORT_DIR)
1.30
1.31 include $(L4DIR)/mk/prog.mk
1.32 include $(IDL_MK_DIR)/interface_rules.mk
2.1 --- a/file_pager.cc Sat Mar 27 00:55:05 2021 +0100
2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2.3 @@ -1,53 +0,0 @@
2.4 -#include "file_pager.h"
2.5 -#include "mapped_file_object_server.h"
2.6 -
2.7 -/* Initialise a pager for a file with a unique file identifier and shared page
2.8 - mapper for moderating access to loaded pages. */
2.9 -
2.10 -FilePager::FilePager(fileid_t fileid, PageMapper *mapper, flags_t flags)
2.11 -: Pager(mapper, flags), fileid(fileid)
2.12 -{
2.13 -}
2.14 -
2.15 -int FilePager::expected_items()
2.16 -{
2.17 - return MappedFileObject_expected_items;
2.18 -}
2.19 -
2.20 -ipc_server_handler_type FilePager::handler()
2.21 -{
2.22 - return (ipc_server_handler_type) handle_MappedFileObject;
2.23 -}
2.24 -
2.25 -long FilePager::flush(offset_t populated_size, offset_t *size)
2.26 -{
2.27 - return Pager::flush(populated_size, size);
2.28 -}
2.29 -
2.30 -long FilePager::resize(offset_t *size)
2.31 -{
2.32 - return Pager::resize(size);
2.33 -}
2.34 -
2.35 -long FilePager::mmap(offset_t position, offset_t length, offset_t *start_pos, offset_t *end_pos, offset_t *data_end)
2.36 -{
2.37 - /* Set the limits of the paged region. */
2.38 -
2.39 - Pager::mmap(position, length, start_pos, end_pos, data_end);
2.40 -
2.41 - /* Obtain the amount of the region that is populated with file data. */
2.42 -
2.43 - *data_end = get_data_size() - _start;
2.44 -
2.45 - if (*data_end > _size)
2.46 - *data_end = _size;
2.47 -
2.48 - return L4_EOK;
2.49 -}
2.50 -
2.51 -long FilePager::map(unsigned long offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region)
2.52 -{
2.53 - return Pager::map(offset, hot_spot, flags, region);
2.54 -}
2.55 -
2.56 -// vim: tabstop=4 expandtab shiftwidth=4
3.1 --- a/file_pager.h Sat Mar 27 00:55:05 2021 +0100
3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
3.3 @@ -1,37 +0,0 @@
3.4 -#pragma once
3.5 -
3.6 -#include "mapped_file_object_interface.h"
3.7 -#include "pager.h"
3.8 -
3.9 -/* A pager abstraction for a file. */
3.10 -
3.11 -class FilePager : public Pager, public MappedFileObject
3.12 -{
3.13 -public:
3.14 - fileid_t fileid;
3.15 -
3.16 - explicit FilePager(fileid_t fileid, PageMapper *mapper, flags_t flags);
3.17 -
3.18 - /* Server details. */
3.19 -
3.20 - int expected_items();
3.21 -
3.22 - ipc_server_handler_type handler();
3.23 -
3.24 - void *interface()
3.25 - { return static_cast<MappedFileObject *>(this); }
3.26 -
3.27 - /* File methods. */
3.28 -
3.29 - virtual long flush(offset_t populated_size, offset_t *size);
3.30 -
3.31 - virtual long resize(offset_t *size);
3.32 -
3.33 - /* Pager and mapped file methods. */
3.34 -
3.35 - virtual long map(unsigned long offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region);
3.36 -
3.37 - virtual long mmap(offset_t position, offset_t length, offset_t *start_pos, offset_t *end_pos, offset_t *data_end);
3.38 -};
3.39 -
3.40 -// vim: tabstop=4 expandtab shiftwidth=4
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/files/file_pager.cc Sat Mar 27 01:42:25 2021 +0100
4.3 @@ -0,0 +1,53 @@
4.4 +#include "file_pager.h"
4.5 +#include "mapped_file_object_server.h"
4.6 +
4.7 +/* Initialise a pager for a file with a unique file identifier and shared page
4.8 + mapper for moderating access to loaded pages. */
4.9 +
4.10 +FilePager::FilePager(fileid_t fileid, PageMapper *mapper, flags_t flags)
4.11 +: Pager(mapper, flags), fileid(fileid)
4.12 +{
4.13 +}
4.14 +
4.15 +int FilePager::expected_items()
4.16 +{
4.17 + return MappedFileObject_expected_items;
4.18 +}
4.19 +
4.20 +ipc_server_handler_type FilePager::handler()
4.21 +{
4.22 + return (ipc_server_handler_type) handle_MappedFileObject;
4.23 +}
4.24 +
4.25 +long FilePager::flush(offset_t populated_size, offset_t *size)
4.26 +{
4.27 + return Pager::flush(populated_size, size);
4.28 +}
4.29 +
4.30 +long FilePager::resize(offset_t *size)
4.31 +{
4.32 + return Pager::resize(size);
4.33 +}
4.34 +
4.35 +long FilePager::mmap(offset_t position, offset_t length, offset_t *start_pos, offset_t *end_pos, offset_t *data_end)
4.36 +{
4.37 + /* Set the limits of the paged region. */
4.38 +
4.39 + Pager::mmap(position, length, start_pos, end_pos, data_end);
4.40 +
4.41 + /* Obtain the amount of the region that is populated with file data. */
4.42 +
4.43 + *data_end = get_data_size() - _start;
4.44 +
4.45 + if (*data_end > _size)
4.46 + *data_end = _size;
4.47 +
4.48 + return L4_EOK;
4.49 +}
4.50 +
4.51 +long FilePager::map(unsigned long offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region)
4.52 +{
4.53 + return Pager::map(offset, hot_spot, flags, region);
4.54 +}
4.55 +
4.56 +// vim: tabstop=4 expandtab shiftwidth=4
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/files/file_pager.h Sat Mar 27 01:42:25 2021 +0100
5.3 @@ -0,0 +1,37 @@
5.4 +#pragma once
5.5 +
5.6 +#include "mapped_file_object_interface.h"
5.7 +#include "pager.h"
5.8 +
5.9 +/* A pager abstraction for a file. */
5.10 +
5.11 +class FilePager : public Pager, public MappedFileObject
5.12 +{
5.13 +public:
5.14 + fileid_t fileid;
5.15 +
5.16 + explicit FilePager(fileid_t fileid, PageMapper *mapper, flags_t flags);
5.17 +
5.18 + /* Server details. */
5.19 +
5.20 + int expected_items();
5.21 +
5.22 + ipc_server_handler_type handler();
5.23 +
5.24 + void *interface()
5.25 + { return static_cast<MappedFileObject *>(this); }
5.26 +
5.27 + /* File methods. */
5.28 +
5.29 + virtual long flush(offset_t populated_size, offset_t *size);
5.30 +
5.31 + virtual long resize(offset_t *size);
5.32 +
5.33 + /* Pager and mapped file methods. */
5.34 +
5.35 + virtual long map(unsigned long offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region);
5.36 +
5.37 + virtual long mmap(offset_t position, offset_t length, offset_t *start_pos, offset_t *end_pos, offset_t *data_end);
5.38 +};
5.39 +
5.40 +// vim: tabstop=4 expandtab shiftwidth=4
6.1 --- a/files/pipe_accessor.cc Sat Mar 27 00:55:05 2021 +0100
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,43 +0,0 @@
6.4 -#include "pipe_accessor.h"
6.5 -
6.6 -#include <string.h>
6.7 -
6.8 -PipeAccessor::PipeAccessor()
6.9 -: Accessor(0)
6.10 -{
6.11 -}
6.12 -
6.13 -/* Perform any closing operation on the file. */
6.14 -
6.15 -void PipeAccessor::close()
6.16 -{
6.17 -}
6.18 -
6.19 -/* Perform any opening operation on the file. */
6.20 -
6.21 -void PipeAccessor::open()
6.22 -{
6.23 -}
6.24 -
6.25 -/* Data transfer helper methods. */
6.26 -
6.27 -void PipeAccessor::fill_populated(Flexpage *flexpage)
6.28 -{
6.29 - offset_t filepos = flexpage->base_offset;
6.30 - offset_t addr = flexpage->base_addr;
6.31 -
6.32 - /* Tag the region with file state. */
6.33 -
6.34 - flexpage->region->fill(fileid, filepos);
6.35 -
6.36 - /* File the flexpage with zero. */
6.37 -
6.38 - memset((void *) addr, 0, flexpage->size);
6.39 -}
6.40 -
6.41 -void PipeAccessor::flush_populated(Flexpage *flexpage)
6.42 -{
6.43 - flexpage->region->flush();
6.44 -}
6.45 -
6.46 -// vim: tabstop=4 expandtab shiftwidth=4
7.1 --- a/files/pipe_accessor.h Sat Mar 27 00:55:05 2021 +0100
7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
7.3 @@ -1,25 +0,0 @@
7.4 -#pragma once
7.5 -
7.6 -#include "accessor.h"
7.7 -
7.8 -/* A pipe accessor, providing flexpages for pipe sections. */
7.9 -
7.10 -class PipeAccessor : public Accessor
7.11 -{
7.12 -protected:
7.13 -
7.14 - /* Data transfer helper methods. */
7.15 -
7.16 - virtual void fill_populated(Flexpage *flexpage);
7.17 -
7.18 - virtual void flush_populated(Flexpage *flexpage);
7.19 -
7.20 -public:
7.21 - explicit PipeAccessor();
7.22 -
7.23 - virtual void close();
7.24 -
7.25 - virtual void open();
7.26 -};
7.27 -
7.28 -// vim: tabstop=4 expandtab shiftwidth=4
8.1 --- a/files/pipe_paging.cc Sat Mar 27 00:55:05 2021 +0100
8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
8.3 @@ -1,101 +0,0 @@
8.4 -#include "pipe_paging.h"
8.5 -
8.6 -PipePaging::PipePaging(Memory *memory, offset_t size)
8.7 -: _memory(NULL), _size(size)
8.8 -{
8.9 - _pages = new PagesConserving(memory);
8.10 -}
8.11 -
8.12 -PipePaging::PipePaging(offset_t size)
8.13 -: _size(size)
8.14 -{
8.15 - _memory = new Memory();
8.16 - _pages = new PagesConserving(_memory);
8.17 -}
8.18 -
8.19 -/* Detach one endpoint. */
8.20 -
8.21 -void PipePaging::detach()
8.22 -{
8.23 - if (!_endpoints)
8.24 - return;
8.25 - else
8.26 - _endpoints--;
8.27 -
8.28 - /* Return if the other endpoint is attached. */
8.29 -
8.30 - if (_endpoints)
8.31 - return;
8.32 -
8.33 - /* Discard all regions from the pipe. */
8.34 -
8.35 - while (!_regions.empty())
8.36 - {
8.37 - PageMapper *mapper = _regions.front();
8.38 -
8.39 - _regions.pop_front();
8.40 - mapper->detach();
8.41 - delete mapper;
8.42 - }
8.43 -
8.44 - /* Delete the page collection and memory object. */
8.45 -
8.46 - delete _pages;
8.47 -
8.48 - if (_memory != NULL)
8.49 - delete _memory;
8.50 -}
8.51 -
8.52 -/* Add a region to the sequence. */
8.53 -
8.54 -void PipePaging::add_region(PageMapper *mapper)
8.55 -{
8.56 - _regions.push_back(mapper);
8.57 -}
8.58 -
8.59 -/* Return the first region in the sequence. */
8.60 -
8.61 -PageMapper *PipePaging::first_region()
8.62 -{
8.63 - return _regions.front();
8.64 -}
8.65 -
8.66 -/* Return the next region for the reader. If only a single region remains, with
8.67 - the reader wishing to move to the next, return NULL. */
8.68 -
8.69 -PageMapper *PipePaging::next_region()
8.70 -{
8.71 - if (_regions.size() > 1)
8.72 - {
8.73 - /* Discard the accessor from the current region. */
8.74 -
8.75 - if (_accessors.size() > _regions.size())
8.76 - _accessors.pop_front();
8.77 -
8.78 - /* Detach and discard the current page mapper. */
8.79 -
8.80 - PageMapper *mapper = _regions.front();
8.81 -
8.82 - _regions.pop_front();
8.83 - mapper->detach();
8.84 - delete mapper;
8.85 -
8.86 - /* Return the next region. */
8.87 -
8.88 - return _regions.front();
8.89 - }
8.90 - else
8.91 - return NULL;
8.92 -}
8.93 -
8.94 -/* Initialise an accessor for a region. */
8.95 -
8.96 -PipeAccessor *PipePaging::accessor()
8.97 -{
8.98 - PipeAccessor accessor;
8.99 -
8.100 - _accessors.push_back(accessor);
8.101 - return &_accessors.back();
8.102 -}
8.103 -
8.104 -// vim: tabstop=4 expandtab shiftwidth=4
9.1 --- a/files/pipe_paging.h Sat Mar 27 00:55:05 2021 +0100
9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
9.3 @@ -1,55 +0,0 @@
9.4 -#pragma once
9.5 -
9.6 -#include <list>
9.7 -
9.8 -#include "page_mapper.h"
9.9 -#include "pages_conserving.h"
9.10 -#include "pipe_accessor.h"
9.11 -
9.12 -/* Pipe paging support, maintaining the sequence of active regions or sections
9.13 - in a pipe. */
9.14 -
9.15 -class PipePaging
9.16 -{
9.17 -protected:
9.18 - Memory *_memory;
9.19 - PagesConserving *_pages;
9.20 -
9.21 - /* Regions acting as files with their own accessors. */
9.22 -
9.23 - std::list<PageMapper *> _regions;
9.24 - std::list<PipeAccessor> _accessors;
9.25 -
9.26 - /* Pipe section/region size. */
9.27 -
9.28 - offset_t _size;
9.29 -
9.30 - /* Endpoint status. */
9.31 -
9.32 - unsigned int _endpoints = 2;
9.33 -
9.34 -public:
9.35 - explicit PipePaging(Memory *memory, offset_t size);
9.36 -
9.37 - explicit PipePaging(offset_t size);
9.38 -
9.39 - virtual void detach();
9.40 -
9.41 - virtual PagesConserving *pages()
9.42 - { return _pages; }
9.43 -
9.44 - virtual offset_t region_size()
9.45 - { return _size; }
9.46 -
9.47 - /* Region management. */
9.48 -
9.49 - virtual void add_region(PageMapper *mapper);
9.50 -
9.51 - virtual PageMapper *first_region();
9.52 -
9.53 - virtual PageMapper *next_region();
9.54 -
9.55 - virtual PipeAccessor *accessor();
9.56 -};
9.57 -
9.58 -// vim: tabstop=4 expandtab shiftwidth=4
10.1 --- a/pipe_opener_resource.cc Sat Mar 27 00:55:05 2021 +0100
10.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
10.3 @@ -1,67 +0,0 @@
10.4 -#include "pipe_opener_resource.h"
10.5 -#include "pipe_opener_server.h"
10.6 -#include "pipe_pager.h"
10.7 -#include "resource_server.h"
10.8 -
10.9 -
10.10 -
10.11 -/* Support for providing access to pipes. */
10.12 -
10.13 -PipeOpenerResource::PipeOpenerResource(Memory *memory)
10.14 -: _memory(memory)
10.15 -{
10.16 -}
10.17 -
10.18 -PipeOpenerResource::PipeOpenerResource()
10.19 -{
10.20 - _memory = new Memory();
10.21 -}
10.22 -
10.23 -int PipeOpenerResource::expected_items()
10.24 -{
10.25 - return PipeOpener_expected_items;
10.26 -}
10.27 -
10.28 -ipc_server_handler_type PipeOpenerResource::handler()
10.29 -{
10.30 - return (ipc_server_handler_type) handle_PipeOpener;
10.31 -}
10.32 -
10.33 -
10.34 -
10.35 -/* Pipe opener interface methods. */
10.36 -
10.37 -long PipeOpenerResource::pipe(offset_t size, l4_cap_idx_t *reader, l4_cap_idx_t *writer)
10.38 -{
10.39 - /* Both endpoints will employ a common paging coordinator. */
10.40 -
10.41 - PipePaging *paging = new PipePaging(_memory, size);
10.42 -
10.43 - /* Each endpoint will have its own pager. */
10.44 -
10.45 - /* NOTE: Failure to open an endpoint should invalidate both, plus the
10.46 - paging object. Also, any active server thread would need to be
10.47 - cancelled. */
10.48 -
10.49 - return open_endpoint(paging, false, reader) || open_endpoint(paging, true, writer);
10.50 -}
10.51 -
10.52 -long PipeOpenerResource::open_endpoint(PipePaging *paging, bool writing, l4_cap_idx_t *endpoint)
10.53 -{
10.54 - PipePager *pager = new PipePager(paging, writing);
10.55 -
10.56 - /* Start the endpoint server in a new thread.
10.57 - If the thread does not start, the resource should be finalised. */
10.58 -
10.59 - ResourceServer server(pager);
10.60 - long err = server.start_thread();
10.61 -
10.62 - /* Return the server capability to the caller. */
10.63 -
10.64 - if (!err)
10.65 - *endpoint = server.config()->server;
10.66 -
10.67 - return err;
10.68 -}
10.69 -
10.70 -// vim: tabstop=4 expandtab shiftwidth=4
11.1 --- a/pipe_opener_resource.h Sat Mar 27 00:55:05 2021 +0100
11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
11.3 @@ -1,36 +0,0 @@
11.4 -#pragma once
11.5 -
11.6 -#include "memory.h"
11.7 -#include "pipe_opener_interface.h"
11.8 -#include "pipe_paging.h"
11.9 -#include "resource.h"
11.10 -
11.11 -/* Support for providing access to pipes. */
11.12 -
11.13 -class PipeOpenerResource : public Resource, public PipeOpener
11.14 -{
11.15 -protected:
11.16 - Memory *_memory;
11.17 -
11.18 - long open_endpoint(PipePaging *paging, bool writing, l4_cap_idx_t *endpoint);
11.19 -
11.20 -public:
11.21 - explicit PipeOpenerResource(Memory *memory);
11.22 -
11.23 - explicit PipeOpenerResource();
11.24 -
11.25 - /* Server details. */
11.26 -
11.27 - int expected_items();
11.28 -
11.29 - ipc_server_handler_type handler();
11.30 -
11.31 - void *interface()
11.32 - { return static_cast<PipeOpener *>(this); }
11.33 -
11.34 - /* PipeOpener interface methods. */
11.35 -
11.36 - long pipe(offset_t size, l4_cap_idx_t *reader, l4_cap_idx_t *writer);
11.37 -};
11.38 -
11.39 -// vim: tabstop=4 expandtab shiftwidth=4
12.1 --- a/pipe_pager.cc Sat Mar 27 00:55:05 2021 +0100
12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
12.3 @@ -1,129 +0,0 @@
12.4 -#include "pipe_pager.h"
12.5 -#include "pipe_object_server.h"
12.6 -
12.7 -/* Initialise a pager for a pipe with a shared page mapper for moderating
12.8 - access to loaded pages. At first, no mapper will be configured: this must be
12.9 - done by requesting a region. */
12.10 -
12.11 -PipePager::PipePager(PipePaging *paging, bool writing)
12.12 -: Pager(NULL, writing ? L4_FPAGE_RW : L4_FPAGE_RO),
12.13 - _paging(paging), _writing(writing)
12.14 -{
12.15 - /* Initialise the size of the paged region. */
12.16 -
12.17 - _size = _paging->region_size();
12.18 -}
12.19 -
12.20 -int PipePager::expected_items()
12.21 -{
12.22 - return PipeObject_expected_items;
12.23 -}
12.24 -
12.25 -ipc_server_handler_type PipePager::handler()
12.26 -{
12.27 - return (ipc_server_handler_type) handle_PipeObject;
12.28 -}
12.29 -
12.30 -
12.31 -
12.32 -/* Close the pager, releasing the paging coordinator for the pipe. This will
12.33 - release all active page mappers. */
12.34 -
12.35 -void PipePager::close()
12.36 -{
12.37 - _paging->detach();
12.38 -}
12.39 -
12.40 -/* Support paging. */
12.41 -
12.42 -long PipePager::map(unsigned long offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region)
12.43 -{
12.44 - return Pager::map(offset, hot_spot, flags, region);
12.45 -}
12.46 -
12.47 -
12.48 -
12.49 -/* Return details of the current region. */
12.50 -
12.51 -long PipePager::current_region(offset_t *populated_size, offset_t *size)
12.52 -{
12.53 - if (_mapper != NULL)
12.54 - {
12.55 - *populated_size = _mapper->get_data_size();
12.56 - *size = _size;
12.57 - return L4_EOK;
12.58 - }
12.59 - else
12.60 - return -L4_EIO;
12.61 -}
12.62 -
12.63 -/* Obtain the next region and its details. */
12.64 -
12.65 -long PipePager::next_region(offset_t *populated_size, offset_t *size)
12.66 -{
12.67 - /* Obtain a new region if writing. */
12.68 -
12.69 - if (_writing)
12.70 - return next_region_for_writer(populated_size, size);
12.71 - else
12.72 - return next_region_for_reader(populated_size, size);
12.73 -}
12.74 -
12.75 -long PipePager::next_region_for_reader(offset_t *populated_size, offset_t *size)
12.76 -{
12.77 - /* Obtain the next region if a current region is defined. */
12.78 -
12.79 - if (_mapper != NULL)
12.80 - {
12.81 - PageMapper *mapper = _paging->next_region();
12.82 -
12.83 - /* Return an error if no next region currently exists. */
12.84 -
12.85 - if (mapper == NULL)
12.86 - return -L4_EIO;
12.87 -
12.88 - _mapper = mapper;
12.89 - }
12.90 -
12.91 - /* Obtain the first region if no mapper is defined. */
12.92 -
12.93 - else
12.94 - _mapper = _paging->first_region();
12.95 -
12.96 - /* Return the details of the now-current region. */
12.97 -
12.98 - return current_region(populated_size, size);
12.99 -}
12.100 -
12.101 -long PipePager::next_region_for_writer(offset_t *populated_size, offset_t *size)
12.102 -{
12.103 - /* Set the populated size before moving on. */
12.104 -
12.105 - if (_mapper != NULL)
12.106 - _mapper->set_data_size(*populated_size);
12.107 -
12.108 - /* A guaranteed amount of memory is reserved for the pipe. */
12.109 -
12.110 - PagesConserving *pages = _paging->pages();
12.111 -
12.112 - if (!pages->increase(_size))
12.113 - return -L4_ENOMEM;
12.114 -
12.115 - /* Set the page mapper for the region. */
12.116 -
12.117 - _mapper = new PageMapper(_paging->accessor(), pages);
12.118 - _mapper->attach();
12.119 -
12.120 - /* Record the mapper as the latest region in the accessor. */
12.121 -
12.122 - _paging->add_region(_mapper);
12.123 -
12.124 - /* Set the region size to the allocated amount. */
12.125 -
12.126 - *size = _size;
12.127 - *populated_size = 0;
12.128 -
12.129 - return L4_EOK;
12.130 -}
12.131 -
12.132 -// vim: tabstop=4 expandtab shiftwidth=4
13.1 --- a/pipe_pager.h Sat Mar 27 00:55:05 2021 +0100
13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
13.3 @@ -1,47 +0,0 @@
13.4 -#pragma once
13.5 -
13.6 -#include "pipe_accessor.h"
13.7 -#include "pipe_object_interface.h"
13.8 -#include "pipe_paging.h"
13.9 -#include "pager.h"
13.10 -
13.11 -/* A pager abstraction for a pipe. */
13.12 -
13.13 -class PipePager : public Pager, public PipeObject
13.14 -{
13.15 -protected:
13.16 - PipePaging *_paging;
13.17 - bool _writing;
13.18 -
13.19 - /* Helper methods. */
13.20 -
13.21 - virtual long next_region_for_reader(offset_t *populated_size, offset_t *size);
13.22 -
13.23 - virtual long next_region_for_writer(offset_t *populated_size, offset_t *size);
13.24 -
13.25 -public:
13.26 - explicit PipePager(PipePaging *paging, bool writer);
13.27 -
13.28 - virtual void close();
13.29 -
13.30 - /* Server details. */
13.31 -
13.32 - int expected_items();
13.33 -
13.34 - ipc_server_handler_type handler();
13.35 -
13.36 - void *interface()
13.37 - { return static_cast<PipeObject *>(this); }
13.38 -
13.39 - /* Pager methods. */
13.40 -
13.41 - virtual long map(unsigned long offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region);
13.42 -
13.43 - /* Pipe methods. */
13.44 -
13.45 - virtual long current_region(offset_t *populated_size, offset_t *size);
13.46 -
13.47 - virtual long next_region(offset_t *populated_size, offset_t *size);
13.48 -};
13.49 -
13.50 -// vim: tabstop=4 expandtab shiftwidth=4
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/pipes/pipe_accessor.cc Sat Mar 27 01:42:25 2021 +0100
14.3 @@ -0,0 +1,43 @@
14.4 +#include "pipe_accessor.h"
14.5 +
14.6 +#include <string.h>
14.7 +
14.8 +PipeAccessor::PipeAccessor()
14.9 +: Accessor(0)
14.10 +{
14.11 +}
14.12 +
14.13 +/* Perform any closing operation on the file. */
14.14 +
14.15 +void PipeAccessor::close()
14.16 +{
14.17 +}
14.18 +
14.19 +/* Perform any opening operation on the file. */
14.20 +
14.21 +void PipeAccessor::open()
14.22 +{
14.23 +}
14.24 +
14.25 +/* Data transfer helper methods. */
14.26 +
14.27 +void PipeAccessor::fill_populated(Flexpage *flexpage)
14.28 +{
14.29 + offset_t filepos = flexpage->base_offset;
14.30 + offset_t addr = flexpage->base_addr;
14.31 +
14.32 + /* Tag the region with file state. */
14.33 +
14.34 + flexpage->region->fill(fileid, filepos);
14.35 +
14.36 + /* File the flexpage with zero. */
14.37 +
14.38 + memset((void *) addr, 0, flexpage->size);
14.39 +}
14.40 +
14.41 +void PipeAccessor::flush_populated(Flexpage *flexpage)
14.42 +{
14.43 + flexpage->region->flush();
14.44 +}
14.45 +
14.46 +// vim: tabstop=4 expandtab shiftwidth=4
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/pipes/pipe_accessor.h Sat Mar 27 01:42:25 2021 +0100
15.3 @@ -0,0 +1,25 @@
15.4 +#pragma once
15.5 +
15.6 +#include "accessor.h"
15.7 +
15.8 +/* A pipe accessor, providing flexpages for pipe sections. */
15.9 +
15.10 +class PipeAccessor : public Accessor
15.11 +{
15.12 +protected:
15.13 +
15.14 + /* Data transfer helper methods. */
15.15 +
15.16 + virtual void fill_populated(Flexpage *flexpage);
15.17 +
15.18 + virtual void flush_populated(Flexpage *flexpage);
15.19 +
15.20 +public:
15.21 + explicit PipeAccessor();
15.22 +
15.23 + virtual void close();
15.24 +
15.25 + virtual void open();
15.26 +};
15.27 +
15.28 +// vim: tabstop=4 expandtab shiftwidth=4
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/pipes/pipe_opener_resource.cc Sat Mar 27 01:42:25 2021 +0100
16.3 @@ -0,0 +1,67 @@
16.4 +#include "pipe_opener_resource.h"
16.5 +#include "pipe_opener_server.h"
16.6 +#include "pipe_pager.h"
16.7 +#include "resource_server.h"
16.8 +
16.9 +
16.10 +
16.11 +/* Support for providing access to pipes. */
16.12 +
16.13 +PipeOpenerResource::PipeOpenerResource(Memory *memory)
16.14 +: _memory(memory)
16.15 +{
16.16 +}
16.17 +
16.18 +PipeOpenerResource::PipeOpenerResource()
16.19 +{
16.20 + _memory = new Memory();
16.21 +}
16.22 +
16.23 +int PipeOpenerResource::expected_items()
16.24 +{
16.25 + return PipeOpener_expected_items;
16.26 +}
16.27 +
16.28 +ipc_server_handler_type PipeOpenerResource::handler()
16.29 +{
16.30 + return (ipc_server_handler_type) handle_PipeOpener;
16.31 +}
16.32 +
16.33 +
16.34 +
16.35 +/* Pipe opener interface methods. */
16.36 +
16.37 +long PipeOpenerResource::pipe(offset_t size, l4_cap_idx_t *reader, l4_cap_idx_t *writer)
16.38 +{
16.39 + /* Both endpoints will employ a common paging coordinator. */
16.40 +
16.41 + PipePaging *paging = new PipePaging(_memory, size);
16.42 +
16.43 + /* Each endpoint will have its own pager. */
16.44 +
16.45 + /* NOTE: Failure to open an endpoint should invalidate both, plus the
16.46 + paging object. Also, any active server thread would need to be
16.47 + cancelled. */
16.48 +
16.49 + return open_endpoint(paging, false, reader) || open_endpoint(paging, true, writer);
16.50 +}
16.51 +
16.52 +long PipeOpenerResource::open_endpoint(PipePaging *paging, bool writing, l4_cap_idx_t *endpoint)
16.53 +{
16.54 + PipePager *pager = new PipePager(paging, writing);
16.55 +
16.56 + /* Start the endpoint server in a new thread.
16.57 + If the thread does not start, the resource should be finalised. */
16.58 +
16.59 + ResourceServer server(pager);
16.60 + long err = server.start_thread();
16.61 +
16.62 + /* Return the server capability to the caller. */
16.63 +
16.64 + if (!err)
16.65 + *endpoint = server.config()->server;
16.66 +
16.67 + return err;
16.68 +}
16.69 +
16.70 +// vim: tabstop=4 expandtab shiftwidth=4
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/pipes/pipe_opener_resource.h Sat Mar 27 01:42:25 2021 +0100
17.3 @@ -0,0 +1,36 @@
17.4 +#pragma once
17.5 +
17.6 +#include "memory.h"
17.7 +#include "pipe_opener_interface.h"
17.8 +#include "pipe_paging.h"
17.9 +#include "resource.h"
17.10 +
17.11 +/* Support for providing access to pipes. */
17.12 +
17.13 +class PipeOpenerResource : public Resource, public PipeOpener
17.14 +{
17.15 +protected:
17.16 + Memory *_memory;
17.17 +
17.18 + long open_endpoint(PipePaging *paging, bool writing, l4_cap_idx_t *endpoint);
17.19 +
17.20 +public:
17.21 + explicit PipeOpenerResource(Memory *memory);
17.22 +
17.23 + explicit PipeOpenerResource();
17.24 +
17.25 + /* Server details. */
17.26 +
17.27 + int expected_items();
17.28 +
17.29 + ipc_server_handler_type handler();
17.30 +
17.31 + void *interface()
17.32 + { return static_cast<PipeOpener *>(this); }
17.33 +
17.34 + /* PipeOpener interface methods. */
17.35 +
17.36 + long pipe(offset_t size, l4_cap_idx_t *reader, l4_cap_idx_t *writer);
17.37 +};
17.38 +
17.39 +// vim: tabstop=4 expandtab shiftwidth=4
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/pipes/pipe_pager.cc Sat Mar 27 01:42:25 2021 +0100
18.3 @@ -0,0 +1,129 @@
18.4 +#include "pipe_pager.h"
18.5 +#include "pipe_object_server.h"
18.6 +
18.7 +/* Initialise a pager for a pipe with a shared page mapper for moderating
18.8 + access to loaded pages. At first, no mapper will be configured: this must be
18.9 + done by requesting a region. */
18.10 +
18.11 +PipePager::PipePager(PipePaging *paging, bool writing)
18.12 +: Pager(NULL, writing ? L4_FPAGE_RW : L4_FPAGE_RO),
18.13 + _paging(paging), _writing(writing)
18.14 +{
18.15 + /* Initialise the size of the paged region. */
18.16 +
18.17 + _size = _paging->region_size();
18.18 +}
18.19 +
18.20 +int PipePager::expected_items()
18.21 +{
18.22 + return PipeObject_expected_items;
18.23 +}
18.24 +
18.25 +ipc_server_handler_type PipePager::handler()
18.26 +{
18.27 + return (ipc_server_handler_type) handle_PipeObject;
18.28 +}
18.29 +
18.30 +
18.31 +
18.32 +/* Close the pager, releasing the paging coordinator for the pipe. This will
18.33 + release all active page mappers. */
18.34 +
18.35 +void PipePager::close()
18.36 +{
18.37 + _paging->detach();
18.38 +}
18.39 +
18.40 +/* Support paging. */
18.41 +
18.42 +long PipePager::map(unsigned long offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region)
18.43 +{
18.44 + return Pager::map(offset, hot_spot, flags, region);
18.45 +}
18.46 +
18.47 +
18.48 +
18.49 +/* Return details of the current region. */
18.50 +
18.51 +long PipePager::current_region(offset_t *populated_size, offset_t *size)
18.52 +{
18.53 + if (_mapper != NULL)
18.54 + {
18.55 + *populated_size = _mapper->get_data_size();
18.56 + *size = _size;
18.57 + return L4_EOK;
18.58 + }
18.59 + else
18.60 + return -L4_EIO;
18.61 +}
18.62 +
18.63 +/* Obtain the next region and its details. */
18.64 +
18.65 +long PipePager::next_region(offset_t *populated_size, offset_t *size)
18.66 +{
18.67 + /* Obtain a new region if writing. */
18.68 +
18.69 + if (_writing)
18.70 + return next_region_for_writer(populated_size, size);
18.71 + else
18.72 + return next_region_for_reader(populated_size, size);
18.73 +}
18.74 +
18.75 +long PipePager::next_region_for_reader(offset_t *populated_size, offset_t *size)
18.76 +{
18.77 + /* Obtain the next region if a current region is defined. */
18.78 +
18.79 + if (_mapper != NULL)
18.80 + {
18.81 + PageMapper *mapper = _paging->next_region();
18.82 +
18.83 + /* Return an error if no next region currently exists. */
18.84 +
18.85 + if (mapper == NULL)
18.86 + return -L4_EIO;
18.87 +
18.88 + _mapper = mapper;
18.89 + }
18.90 +
18.91 + /* Obtain the first region if no mapper is defined. */
18.92 +
18.93 + else
18.94 + _mapper = _paging->first_region();
18.95 +
18.96 + /* Return the details of the now-current region. */
18.97 +
18.98 + return current_region(populated_size, size);
18.99 +}
18.100 +
18.101 +long PipePager::next_region_for_writer(offset_t *populated_size, offset_t *size)
18.102 +{
18.103 + /* Set the populated size before moving on. */
18.104 +
18.105 + if (_mapper != NULL)
18.106 + _mapper->set_data_size(*populated_size);
18.107 +
18.108 + /* A guaranteed amount of memory is reserved for the pipe. */
18.109 +
18.110 + PagesConserving *pages = _paging->pages();
18.111 +
18.112 + if (!pages->increase(_size))
18.113 + return -L4_ENOMEM;
18.114 +
18.115 + /* Set the page mapper for the region. */
18.116 +
18.117 + _mapper = new PageMapper(_paging->accessor(), pages);
18.118 + _mapper->attach();
18.119 +
18.120 + /* Record the mapper as the latest region in the accessor. */
18.121 +
18.122 + _paging->add_region(_mapper);
18.123 +
18.124 + /* Set the region size to the allocated amount. */
18.125 +
18.126 + *size = _size;
18.127 + *populated_size = 0;
18.128 +
18.129 + return L4_EOK;
18.130 +}
18.131 +
18.132 +// vim: tabstop=4 expandtab shiftwidth=4
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/pipes/pipe_pager.h Sat Mar 27 01:42:25 2021 +0100
19.3 @@ -0,0 +1,47 @@
19.4 +#pragma once
19.5 +
19.6 +#include "pipe_accessor.h"
19.7 +#include "pipe_object_interface.h"
19.8 +#include "pipe_paging.h"
19.9 +#include "pager.h"
19.10 +
19.11 +/* A pager abstraction for a pipe. */
19.12 +
19.13 +class PipePager : public Pager, public PipeObject
19.14 +{
19.15 +protected:
19.16 + PipePaging *_paging;
19.17 + bool _writing;
19.18 +
19.19 + /* Helper methods. */
19.20 +
19.21 + virtual long next_region_for_reader(offset_t *populated_size, offset_t *size);
19.22 +
19.23 + virtual long next_region_for_writer(offset_t *populated_size, offset_t *size);
19.24 +
19.25 +public:
19.26 + explicit PipePager(PipePaging *paging, bool writer);
19.27 +
19.28 + virtual void close();
19.29 +
19.30 + /* Server details. */
19.31 +
19.32 + int expected_items();
19.33 +
19.34 + ipc_server_handler_type handler();
19.35 +
19.36 + void *interface()
19.37 + { return static_cast<PipeObject *>(this); }
19.38 +
19.39 + /* Pager methods. */
19.40 +
19.41 + virtual long map(unsigned long offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region);
19.42 +
19.43 + /* Pipe methods. */
19.44 +
19.45 + virtual long current_region(offset_t *populated_size, offset_t *size);
19.46 +
19.47 + virtual long next_region(offset_t *populated_size, offset_t *size);
19.48 +};
19.49 +
19.50 +// vim: tabstop=4 expandtab shiftwidth=4
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/pipes/pipe_paging.cc Sat Mar 27 01:42:25 2021 +0100
20.3 @@ -0,0 +1,101 @@
20.4 +#include "pipe_paging.h"
20.5 +
20.6 +PipePaging::PipePaging(Memory *memory, offset_t size)
20.7 +: _memory(NULL), _size(size)
20.8 +{
20.9 + _pages = new PagesConserving(memory);
20.10 +}
20.11 +
20.12 +PipePaging::PipePaging(offset_t size)
20.13 +: _size(size)
20.14 +{
20.15 + _memory = new Memory();
20.16 + _pages = new PagesConserving(_memory);
20.17 +}
20.18 +
20.19 +/* Detach one endpoint. */
20.20 +
20.21 +void PipePaging::detach()
20.22 +{
20.23 + if (!_endpoints)
20.24 + return;
20.25 + else
20.26 + _endpoints--;
20.27 +
20.28 + /* Return if the other endpoint is attached. */
20.29 +
20.30 + if (_endpoints)
20.31 + return;
20.32 +
20.33 + /* Discard all regions from the pipe. */
20.34 +
20.35 + while (!_regions.empty())
20.36 + {
20.37 + PageMapper *mapper = _regions.front();
20.38 +
20.39 + _regions.pop_front();
20.40 + mapper->detach();
20.41 + delete mapper;
20.42 + }
20.43 +
20.44 + /* Delete the page collection and memory object. */
20.45 +
20.46 + delete _pages;
20.47 +
20.48 + if (_memory != NULL)
20.49 + delete _memory;
20.50 +}
20.51 +
20.52 +/* Add a region to the sequence. */
20.53 +
20.54 +void PipePaging::add_region(PageMapper *mapper)
20.55 +{
20.56 + _regions.push_back(mapper);
20.57 +}
20.58 +
20.59 +/* Return the first region in the sequence. */
20.60 +
20.61 +PageMapper *PipePaging::first_region()
20.62 +{
20.63 + return _regions.front();
20.64 +}
20.65 +
20.66 +/* Return the next region for the reader. If only a single region remains, with
20.67 + the reader wishing to move to the next, return NULL. */
20.68 +
20.69 +PageMapper *PipePaging::next_region()
20.70 +{
20.71 + if (_regions.size() > 1)
20.72 + {
20.73 + /* Discard the accessor from the current region. */
20.74 +
20.75 + if (_accessors.size() > _regions.size())
20.76 + _accessors.pop_front();
20.77 +
20.78 + /* Detach and discard the current page mapper. */
20.79 +
20.80 + PageMapper *mapper = _regions.front();
20.81 +
20.82 + _regions.pop_front();
20.83 + mapper->detach();
20.84 + delete mapper;
20.85 +
20.86 + /* Return the next region. */
20.87 +
20.88 + return _regions.front();
20.89 + }
20.90 + else
20.91 + return NULL;
20.92 +}
20.93 +
20.94 +/* Initialise an accessor for a region. */
20.95 +
20.96 +PipeAccessor *PipePaging::accessor()
20.97 +{
20.98 + PipeAccessor accessor;
20.99 +
20.100 + _accessors.push_back(accessor);
20.101 + return &_accessors.back();
20.102 +}
20.103 +
20.104 +// vim: tabstop=4 expandtab shiftwidth=4
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/pipes/pipe_paging.h Sat Mar 27 01:42:25 2021 +0100
21.3 @@ -0,0 +1,55 @@
21.4 +#pragma once
21.5 +
21.6 +#include <list>
21.7 +
21.8 +#include "page_mapper.h"
21.9 +#include "pages_conserving.h"
21.10 +#include "pipe_accessor.h"
21.11 +
21.12 +/* Pipe paging support, maintaining the sequence of active regions or sections
21.13 + in a pipe. */
21.14 +
21.15 +class PipePaging
21.16 +{
21.17 +protected:
21.18 + Memory *_memory;
21.19 + PagesConserving *_pages;
21.20 +
21.21 + /* Regions acting as files with their own accessors. */
21.22 +
21.23 + std::list<PageMapper *> _regions;
21.24 + std::list<PipeAccessor> _accessors;
21.25 +
21.26 + /* Pipe section/region size. */
21.27 +
21.28 + offset_t _size;
21.29 +
21.30 + /* Endpoint status. */
21.31 +
21.32 + unsigned int _endpoints = 2;
21.33 +
21.34 +public:
21.35 + explicit PipePaging(Memory *memory, offset_t size);
21.36 +
21.37 + explicit PipePaging(offset_t size);
21.38 +
21.39 + virtual void detach();
21.40 +
21.41 + virtual PagesConserving *pages()
21.42 + { return _pages; }
21.43 +
21.44 + virtual offset_t region_size()
21.45 + { return _size; }
21.46 +
21.47 + /* Region management. */
21.48 +
21.49 + virtual void add_region(PageMapper *mapper);
21.50 +
21.51 + virtual PageMapper *first_region();
21.52 +
21.53 + virtual PageMapper *next_region();
21.54 +
21.55 + virtual PipeAccessor *accessor();
21.56 +};
21.57 +
21.58 +// vim: tabstop=4 expandtab shiftwidth=4