# HG changeset patch # User Paul Boddie # Date 1617319670 -7200 # Node ID 5e0048b834f208c539ef48badcfc1020a81fce51 # Parent 405eb83f7eed53aaf9c038f31f8aa8a3d3c2ef5d Moved various files into subdirectories. diff -r 405eb83f7eed -r 5e0048b834f2 Makefile --- a/Makefile Thu Apr 01 00:57:43 2021 +0200 +++ b/Makefile Fri Apr 02 01:27:50 2021 +0200 @@ -43,21 +43,19 @@ COMMON_SRC_CC = memory/memory_utils.cc -PLAIN_SRC_CC_dstest_block_client = tests/dstest_block_client.cc file.cc +PLAIN_SRC_CC_dstest_block_client = tests/dstest_block_client.cc client/file.cc -PLAIN_SRC_CC_dstest_host_client = tests/dstest_host_client.cc file.cc +PLAIN_SRC_CC_dstest_host_client = tests/dstest_host_client.cc client/file.cc -PLAIN_SRC_CC_dstest_pipe_client = tests/dstest_pipe_client.cc file.cc +PLAIN_SRC_CC_dstest_pipe_client = tests/dstest_pipe_client.cc client/file.cc -PLAIN_SRC_CC_dstest_test_client = tests/dstest_test_client.cc file.cc +PLAIN_SRC_CC_dstest_test_client = tests/dstest_test_client.cc client/file.cc PLAIN_SRC_CC_common_server = \ - accessor.cc \ - ipc.cc \ - mapping/access_map.cc mapping/flexpage.cc mapping/page_mapper.cc \ - memory/memory_incremental.cc memory/memory_preallocated.cc \ - memory/region.cc \ - pager.cc \ + generic/accessor.cc generic/pager.cc \ + mapping/access_map.cc mapping/flexpage.cc mapping/ipc.cc \ + memory/memory_incremental.cc mapping/page_mapper.cc \ + memory/memory_preallocated.cc memory/region.cc \ pages/page_queue.cc pages/page_queue_partitioned.cc \ pages/page_queue_shared.cc pages/pages.cc \ resource_server.cc @@ -65,7 +63,7 @@ PLAIN_SRC_CC_common_file_server = \ files/file_pager.cc files/file_paging.cc \ files/opener_resource.cc files/opener_context_resource.cc \ - simple_pager.cc + generic/simple_pager.cc PLAIN_SRC_CC_dstest_block_server = \ $(PLAIN_SRC_CC_common_server) \ @@ -136,7 +134,9 @@ REQUIRES_LIBS = l4re_c-util libipc libstdc++ libsystypes -PRIVATE_INCDIR = $(PKGDIR) $(PKGDIR)/files $(PKGDIR)/mapping $(PKGDIR)/memory \ +PRIVATE_INCDIR = $(PKGDIR) $(PKGDIR)/client \ + $(PKGDIR)/files $(PKGDIR)/generic \ + $(PKGDIR)/mapping $(PKGDIR)/memory \ $(PKGDIR)/pages $(PKGDIR)/pipes \ $(IDL_BUILD_DIR) $(IDL_EXPORT_DIR) diff -r 405eb83f7eed -r 5e0048b834f2 accessor.cc --- a/accessor.cc Thu Apr 01 00:57:43 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -#include "accessor.h" - -#include - - - -Accessor::Accessor(fileid_t fileid, offset_t size) -: _size(size), fileid(fileid) -{ -} - -/* Return the size of the file. */ - -offset_t Accessor::get_size() -{ - return _size; -} - -/* Update the size of the file. */ - -void Accessor::set_size(offset_t size) -{ - _size = size; -} - -/* Perform any closing operation on the file. */ - -void Accessor::close() -{ -} - -/* Perform any opening operation on the file. */ - -void Accessor::open() -{ -} - -/* Data transfer methods. */ - -void Accessor::fill(Flexpage *flexpage) -{ - /* Filling completely beyond the end of file should produce an empty - flexpage. This could potentially be a shared read-only flexpage that - would be replaced by an independent writable flexpage if ever written. */ - - if (flexpage->base_offset < _size) - fill_populated(flexpage); - else - memset((void *) flexpage->base_addr, 0, flexpage->size); -} - -void Accessor::flush(Flexpage *flexpage) -{ - /* Flushing completely beyond the end of file should discard the - flexpage. */ - - if (flexpage->base_offset < _size) - flush_populated(flexpage); -} - -/* Data transfer helper methods. */ - -void Accessor::fill_populated(Flexpage *flexpage) -{ - (void) flexpage; -} - -void Accessor::flush_populated(Flexpage *flexpage) -{ - (void) flexpage; -} - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r 405eb83f7eed -r 5e0048b834f2 accessor.h --- a/accessor.h Thu Apr 01 00:57:43 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -#pragma once - -#include "flexpage.h" - -/* A file accessor, providing flexpages corresponding to file regions. */ - -class Accessor -{ -protected: - offset_t _size; - - /* Data transfer helper methods. */ - - virtual void fill_populated(Flexpage *flexpage); - - virtual void flush_populated(Flexpage *flexpage); - -public: - fileid_t fileid; - - explicit Accessor(fileid_t fileid, offset_t size=0); - - virtual ~Accessor() - { - } - - virtual offset_t get_size(); - - virtual void set_size(offset_t size); - - virtual void close(); - - virtual void open(); - - /* Data transfer methods. */ - - virtual void fill(Flexpage *flexpage); - - virtual void flush(Flexpage *flexpage); -}; - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r 405eb83f7eed -r 5e0048b834f2 client/file.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/file.cc Fri Apr 02 01:27:50 2021 +0200 @@ -0,0 +1,320 @@ +/* + * File access convenience functions. + * + * Copyright (C) 2021 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#include +#include + +#include + +#include "dataspace_client.h" +#include "file_client.h" +#include "opener_client.h" +#include "opener_context_client.h" +#include "pipe_client.h" +#include "pipe_opener_client.h" +#include "mapped_file_client.h" + +#include "file.h" + + + +/* Release resources for the given file. */ + +void file_close(file_t *file) +{ + if (l4_is_valid_cap(file->ref)) + ipc_cap_free_um(file->ref); + + if (file->memory != NULL) + ipc_detach_dataspace(file->memory); + + file_init(file); +} + +/* Initialise a file structure for a context obtained from the given server. */ + +long file_context(file_t *file, l4_cap_idx_t server) +{ + client_Opener opener(server); + unsigned long size, flags; + long err; + + file_init(file); + + err = opener.context(&file->ref); + if (err) + return err; + + client_Dataspace context_ds(file->ref); + + err = context_ds.info(&size, &flags); + if (err) + return err; + + file->start_pos = 0; + file->end_pos = size; + + return ipc_attach_dataspace(file->ref, size, (void **) &file->memory); +} + +/* Open a file using the given structure and context. */ + +long file_context_open(file_t *file, file_t *context) +{ + client_OpenerContext openercontext(context->ref); + file_init(file); + return openercontext.open(L4_FPAGE_RW, &file->size, &file->ref); +} + +/* Initialise the given file structure. */ + +void file_init(file_t *file) +{ + file->memory = NULL; + file->ref = L4_INVALID_CAP; + file->start_pos = 0; + file->end_pos = 0; + file->data_end = 0; +} + +/* Open a file using the given structure, indicating the filename and + filesystem server. This is a convenience function invoking file_context and + file_context_open. */ + +long file_open(file_t *file, const char *filename, l4_cap_idx_t server) +{ + file_t context; + long err; + + err = file_context(&context, server); + if (err) + return err; + + if (!file_string_set(&context, filename, 0, NULL)) + return -L4_ENOMEM; + + err = file_context_open(file, &context); + file_close(&context); + return err; +} + + + +/* Map a region of the given file to a memory region. */ + +long file_mmap(file_t *file, offset_t position, offset_t length) +{ + client_MappedFile mapped_file(file->ref); + long err = mapped_file.mmap(position, length, &file->start_pos, &file->end_pos, &file->data_end); + + if (err) + return err; + + return ipc_attach_dataspace(file->ref, file_span(file), (void **) &file->memory); +} + +/* Resize a file. */ + +long file_resize(file_t *file, offset_t size) +{ + client_File _file(file->ref); + offset_t file_size = size; + long err = _file.resize(&file_size); + + if (!err) + { + /* Determine the extent of the file in this region. */ + + if (file_size > file->end_pos) + file->data_end = file_span(file); + else + file->data_end = file_size - file->start_pos; + + /* Update the file size locally. */ + + file->size = file_size; + } + + return err; +} + + + +/* Return the amount of data in the mapped region for the given file. */ + +offset_t file_populated_span(file_t *file) +{ + offset_t size = file_span(file); + return (file->data_end < size) ? file->data_end : size; +} + +/* Return the size of the mapped region for the given file. */ + +offset_t file_span(file_t *file) +{ + return file->end_pos - file->start_pos; +} + + + +/* Get a pointer to any terminated string at the given offset or NULL if the + data from offset is not terminated. */ + +char *file_string_get(file_t *file, offset_t offset) +{ + offset_t limit = file_span(file) - offset; + + if (strnlen(file->memory + offset, limit) < limit) + return file->memory + offset; + else + return NULL; +} + +/* Copy a string to the mapped region at the given offset, returning 1 (true) + where all characters were copied, 0 (false) otherwise. The precise number of + characters copied, excluding the zero terminator is provided via the written + parameter if it is not specified as NULL. */ + +int file_string_set(file_t *file, const char *data, offset_t offset, + offset_t *written) +{ + offset_t i, pos, limit = file_span(file); + + /* Do not attempt to copy data with an invalid offset. */ + + if (offset >= limit) + { + if (written != NULL) + *written = 0; + return 0; + } + + /* Copy the data to the given offset, stopping at the end of the region. */ + + for (i = 0, pos = offset; pos < limit; i++, pos++) + { + file->memory[pos] = data[i]; + + /* Terminator written, can return immediately. */ + + if (!data[i]) + { + if (written != NULL) + *written = pos - offset; + return 1; + } + } + + /* Terminate the incomplete string at the end of the region. */ + + file->memory[limit - 1] = '\0'; + if (written != NULL) + *written = limit - 1 - offset; + return 0; +} + + + +/* Open two pipe endpoints using the given pipe server. */ + +long pipe_open(offset_t size, file_t *reader, file_t *writer, l4_cap_idx_t server) +{ + client_PipeOpener opener(server); + + file_init(reader); + file_init(writer); + + long err = opener.pipe(size, &reader->ref, &writer->ref); + if (err) + return err; + + err = pipe_next(writer) || pipe_next(reader); + + if (err) + { + file_close(reader); + file_close(writer); + } + + return err; +} + +/* Access the current region for a pipe endpoint. */ + +long pipe_current(file_t *pipe) +{ + client_Pipe _pipe(pipe->ref); + long err = _pipe.current_region(&pipe->data_end, &pipe->size); + char *memory = pipe->memory; + + if (err) + return err; + + pipe->end_pos = pipe->size; + + err = ipc_attach_dataspace(pipe->ref, file_span(pipe), (void **) &pipe->memory); + if (err) + return err; + + if (memory != NULL) + ipc_detach_dataspace(memory); + + return L4_EOK; +} + +/* Access the next region for a pipe endpoint, updating the eventual size of + the current region. */ + +long pipe_next(file_t *pipe) +{ + client_Pipe _pipe(pipe->ref); + long err = _pipe.next_region(&pipe->data_end, &pipe->size); + char *memory = pipe->memory; + + if (err) + return err; + + pipe->end_pos = pipe->size; + + err = ipc_attach_dataspace(pipe->ref, file_span(pipe), (void **) &pipe->memory); + if (err) + return err; + + if (memory != NULL) + ipc_detach_dataspace(memory); + + return L4_EOK; +} + +/* Set the size of the written region. */ + +long pipe_written(file_t *pipe, offset_t size) +{ + if (size <= pipe->size) + { + pipe->data_end = size; + return L4_EOK; + } + else + return -L4_EINVAL; +} + +// vim: tabstop=2 expandtab shiftwidth=2 diff -r 405eb83f7eed -r 5e0048b834f2 client/file.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/file.h Fri Apr 02 01:27:50 2021 +0200 @@ -0,0 +1,95 @@ +/* + * File access convenience functions and types. + * + * Copyright (C) 2021 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#include + +#include + + + +EXTERN_C_BEGIN + +/* File access abstraction. */ + +typedef struct +{ + /* File object reference. */ + + l4_cap_idx_t ref; + + /* Mapped memory accessing a file region. */ + + char *memory; + + /* File region parameters. */ + + offset_t start_pos, end_pos; /* start and end positions of region */ + offset_t data_end; /* amount of data in the region */ + + /* Total size of file. */ + + offset_t size; + +} file_t; + + + +/* File operations. */ + +void file_close(file_t *file); +long file_open(file_t *file, const char *filename, l4_cap_idx_t server); + +/* File lifecycle operations. */ + +long file_context(file_t *file, l4_cap_idx_t server); +long file_context_open(file_t *file, file_t *context); +void file_init(file_t *file); + +/* File and region operations. */ + +long file_mmap(file_t *file, offset_t position, offset_t length); +long file_resize(file_t *file, offset_t size); + +/* File and region properties. */ + +offset_t file_populated_span(file_t *file); +offset_t file_span(file_t *file); + +/* Convenience functions. */ + +char *file_string_get(file_t *file, offset_t offset); +int file_string_set(file_t *file, const char *data, offset_t offset, offset_t *written); + + + +/* Pipe operations. */ + +long pipe_open(offset_t size, file_t *reader, file_t *writer, l4_cap_idx_t server); + +/* Pipe region operations. */ + +long pipe_current(file_t *pipe); +long pipe_next(file_t *pipe); +long pipe_written(file_t *pipe, offset_t size); + +EXTERN_C_END + +// vim: tabstop=2 expandtab shiftwidth=2 diff -r 405eb83f7eed -r 5e0048b834f2 file.cc --- a/file.cc Thu Apr 01 00:57:43 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,320 +0,0 @@ -/* - * File access convenience functions. - * - * Copyright (C) 2021 Paul Boddie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA - */ - -#include -#include - -#include - -#include "dataspace_client.h" -#include "file_client.h" -#include "opener_client.h" -#include "opener_context_client.h" -#include "pipe_client.h" -#include "pipe_opener_client.h" -#include "mapped_file_client.h" - -#include "file.h" - - - -/* Release resources for the given file. */ - -void file_close(file_t *file) -{ - if (l4_is_valid_cap(file->ref)) - ipc_cap_free_um(file->ref); - - if (file->memory != NULL) - ipc_detach_dataspace(file->memory); - - file_init(file); -} - -/* Initialise a file structure for a context obtained from the given server. */ - -long file_context(file_t *file, l4_cap_idx_t server) -{ - client_Opener opener(server); - unsigned long size, flags; - long err; - - file_init(file); - - err = opener.context(&file->ref); - if (err) - return err; - - client_Dataspace context_ds(file->ref); - - err = context_ds.info(&size, &flags); - if (err) - return err; - - file->start_pos = 0; - file->end_pos = size; - - return ipc_attach_dataspace(file->ref, size, (void **) &file->memory); -} - -/* Open a file using the given structure and context. */ - -long file_context_open(file_t *file, file_t *context) -{ - client_OpenerContext openercontext(context->ref); - file_init(file); - return openercontext.open(L4_FPAGE_RW, &file->size, &file->ref); -} - -/* Initialise the given file structure. */ - -void file_init(file_t *file) -{ - file->memory = NULL; - file->ref = L4_INVALID_CAP; - file->start_pos = 0; - file->end_pos = 0; - file->data_end = 0; -} - -/* Open a file using the given structure, indicating the filename and - filesystem server. This is a convenience function invoking file_context and - file_context_open. */ - -long file_open(file_t *file, const char *filename, l4_cap_idx_t server) -{ - file_t context; - long err; - - err = file_context(&context, server); - if (err) - return err; - - if (!file_string_set(&context, filename, 0, NULL)) - return -L4_ENOMEM; - - err = file_context_open(file, &context); - file_close(&context); - return err; -} - - - -/* Map a region of the given file to a memory region. */ - -long file_mmap(file_t *file, offset_t position, offset_t length) -{ - client_MappedFile mapped_file(file->ref); - long err = mapped_file.mmap(position, length, &file->start_pos, &file->end_pos, &file->data_end); - - if (err) - return err; - - return ipc_attach_dataspace(file->ref, file_span(file), (void **) &file->memory); -} - -/* Resize a file. */ - -long file_resize(file_t *file, offset_t size) -{ - client_File _file(file->ref); - offset_t file_size = size; - long err = _file.resize(&file_size); - - if (!err) - { - /* Determine the extent of the file in this region. */ - - if (file_size > file->end_pos) - file->data_end = file_span(file); - else - file->data_end = file_size - file->start_pos; - - /* Update the file size locally. */ - - file->size = file_size; - } - - return err; -} - - - -/* Return the amount of data in the mapped region for the given file. */ - -offset_t file_populated_span(file_t *file) -{ - offset_t size = file_span(file); - return (file->data_end < size) ? file->data_end : size; -} - -/* Return the size of the mapped region for the given file. */ - -offset_t file_span(file_t *file) -{ - return file->end_pos - file->start_pos; -} - - - -/* Get a pointer to any terminated string at the given offset or NULL if the - data from offset is not terminated. */ - -char *file_string_get(file_t *file, offset_t offset) -{ - offset_t limit = file_span(file) - offset; - - if (strnlen(file->memory + offset, limit) < limit) - return file->memory + offset; - else - return NULL; -} - -/* Copy a string to the mapped region at the given offset, returning 1 (true) - where all characters were copied, 0 (false) otherwise. The precise number of - characters copied, excluding the zero terminator is provided via the written - parameter if it is not specified as NULL. */ - -int file_string_set(file_t *file, const char *data, offset_t offset, - offset_t *written) -{ - offset_t i, pos, limit = file_span(file); - - /* Do not attempt to copy data with an invalid offset. */ - - if (offset >= limit) - { - if (written != NULL) - *written = 0; - return 0; - } - - /* Copy the data to the given offset, stopping at the end of the region. */ - - for (i = 0, pos = offset; pos < limit; i++, pos++) - { - file->memory[pos] = data[i]; - - /* Terminator written, can return immediately. */ - - if (!data[i]) - { - if (written != NULL) - *written = pos - offset; - return 1; - } - } - - /* Terminate the incomplete string at the end of the region. */ - - file->memory[limit - 1] = '\0'; - if (written != NULL) - *written = limit - 1 - offset; - return 0; -} - - - -/* Open two pipe endpoints using the given pipe server. */ - -long pipe_open(offset_t size, file_t *reader, file_t *writer, l4_cap_idx_t server) -{ - client_PipeOpener opener(server); - - file_init(reader); - file_init(writer); - - long err = opener.pipe(size, &reader->ref, &writer->ref); - if (err) - return err; - - err = pipe_next(writer) || pipe_next(reader); - - if (err) - { - file_close(reader); - file_close(writer); - } - - return err; -} - -/* Access the current region for a pipe endpoint. */ - -long pipe_current(file_t *pipe) -{ - client_Pipe _pipe(pipe->ref); - long err = _pipe.current_region(&pipe->data_end, &pipe->size); - char *memory = pipe->memory; - - if (err) - return err; - - pipe->end_pos = pipe->size; - - err = ipc_attach_dataspace(pipe->ref, file_span(pipe), (void **) &pipe->memory); - if (err) - return err; - - if (memory != NULL) - ipc_detach_dataspace(memory); - - return L4_EOK; -} - -/* Access the next region for a pipe endpoint, updating the eventual size of - the current region. */ - -long pipe_next(file_t *pipe) -{ - client_Pipe _pipe(pipe->ref); - long err = _pipe.next_region(&pipe->data_end, &pipe->size); - char *memory = pipe->memory; - - if (err) - return err; - - pipe->end_pos = pipe->size; - - err = ipc_attach_dataspace(pipe->ref, file_span(pipe), (void **) &pipe->memory); - if (err) - return err; - - if (memory != NULL) - ipc_detach_dataspace(memory); - - return L4_EOK; -} - -/* Set the size of the written region. */ - -long pipe_written(file_t *pipe, offset_t size) -{ - if (size <= pipe->size) - { - pipe->data_end = size; - return L4_EOK; - } - else - return -L4_EINVAL; -} - -// vim: tabstop=2 expandtab shiftwidth=2 diff -r 405eb83f7eed -r 5e0048b834f2 file.h --- a/file.h Thu Apr 01 00:57:43 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ -/* - * File access convenience functions and types. - * - * Copyright (C) 2021 Paul Boddie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA - */ - -#include - -#include - - - -EXTERN_C_BEGIN - -/* File access abstraction. */ - -typedef struct -{ - /* File object reference. */ - - l4_cap_idx_t ref; - - /* Mapped memory accessing a file region. */ - - char *memory; - - /* File region parameters. */ - - offset_t start_pos, end_pos; /* start and end positions of region */ - offset_t data_end; /* amount of data in the region */ - - /* Total size of file. */ - - offset_t size; - -} file_t; - - - -/* File operations. */ - -void file_close(file_t *file); -long file_open(file_t *file, const char *filename, l4_cap_idx_t server); - -/* File lifecycle operations. */ - -long file_context(file_t *file, l4_cap_idx_t server); -long file_context_open(file_t *file, file_t *context); -void file_init(file_t *file); - -/* File and region operations. */ - -long file_mmap(file_t *file, offset_t position, offset_t length); -long file_resize(file_t *file, offset_t size); - -/* File and region properties. */ - -offset_t file_populated_span(file_t *file); -offset_t file_span(file_t *file); - -/* Convenience functions. */ - -char *file_string_get(file_t *file, offset_t offset); -int file_string_set(file_t *file, const char *data, offset_t offset, offset_t *written); - - - -/* Pipe operations. */ - -long pipe_open(offset_t size, file_t *reader, file_t *writer, l4_cap_idx_t server); - -/* Pipe region operations. */ - -long pipe_current(file_t *pipe); -long pipe_next(file_t *pipe); -long pipe_written(file_t *pipe, offset_t size); - -EXTERN_C_END - -// vim: tabstop=2 expandtab shiftwidth=2 diff -r 405eb83f7eed -r 5e0048b834f2 generic/accessor.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/generic/accessor.cc Fri Apr 02 01:27:50 2021 +0200 @@ -0,0 +1,73 @@ +#include "accessor.h" + +#include + + + +Accessor::Accessor(fileid_t fileid, offset_t size) +: _size(size), fileid(fileid) +{ +} + +/* Return the size of the file. */ + +offset_t Accessor::get_size() +{ + return _size; +} + +/* Update the size of the file. */ + +void Accessor::set_size(offset_t size) +{ + _size = size; +} + +/* Perform any closing operation on the file. */ + +void Accessor::close() +{ +} + +/* Perform any opening operation on the file. */ + +void Accessor::open() +{ +} + +/* Data transfer methods. */ + +void Accessor::fill(Flexpage *flexpage) +{ + /* Filling completely beyond the end of file should produce an empty + flexpage. This could potentially be a shared read-only flexpage that + would be replaced by an independent writable flexpage if ever written. */ + + if (flexpage->base_offset < _size) + fill_populated(flexpage); + else + memset((void *) flexpage->base_addr, 0, flexpage->size); +} + +void Accessor::flush(Flexpage *flexpage) +{ + /* Flushing completely beyond the end of file should discard the + flexpage. */ + + if (flexpage->base_offset < _size) + flush_populated(flexpage); +} + +/* Data transfer helper methods. */ + +void Accessor::fill_populated(Flexpage *flexpage) +{ + (void) flexpage; +} + +void Accessor::flush_populated(Flexpage *flexpage) +{ + (void) flexpage; +} + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r 405eb83f7eed -r 5e0048b834f2 generic/accessor.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/generic/accessor.h Fri Apr 02 01:27:50 2021 +0200 @@ -0,0 +1,42 @@ +#pragma once + +#include "flexpage.h" + +/* A file accessor, providing flexpages corresponding to file regions. */ + +class Accessor +{ +protected: + offset_t _size; + + /* Data transfer helper methods. */ + + virtual void fill_populated(Flexpage *flexpage); + + virtual void flush_populated(Flexpage *flexpage); + +public: + fileid_t fileid; + + explicit Accessor(fileid_t fileid, offset_t size=0); + + virtual ~Accessor() + { + } + + virtual offset_t get_size(); + + virtual void set_size(offset_t size); + + virtual void close(); + + virtual void open(); + + /* Data transfer methods. */ + + virtual void fill(Flexpage *flexpage); + + virtual void flush(Flexpage *flexpage); +}; + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r 405eb83f7eed -r 5e0048b834f2 generic/pager.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/generic/pager.cc Fri Apr 02 01:27:50 2021 +0200 @@ -0,0 +1,91 @@ +#include "dataspace_server.h" +#include "ipc.h" +#include "pager.h" + + + +Pager::Pager(PageMapper *mapper, flags_t flags) +: _start(0), _size(0), _mapper(mapper), _flags(flags) +{ + /* Some pagers may not be initialised with a mapper. */ + + if (_mapper != NULL) + _mapper->attach(); +} + +/* Close the pager. */ + +void Pager::close() +{ + if (_mapper != NULL) + _mapper->detach(); +} + +/* Flush data to the file. */ + +long Pager::flush(offset_t populated_size, offset_t *size) +{ + _mapper->flush_all(_start, populated_size); + + *size = _mapper->get_data_size(); + return L4_EOK; +} + +/* Resize the underlying file. */ + +long Pager::resize(offset_t *size) +{ + _mapper->set_data_size(*size); + + *size = _mapper->get_data_size(); + return L4_EOK; +} + +/* Expose a region of the file. */ + +long Pager::mmap(offset_t position, offset_t length, offset_t *start_pos, offset_t *end_pos, offset_t *data_end) +{ + _start = trunc(position, PAGE_SIZE); + _size = round(position + length, PAGE_SIZE) - _start; + + *start_pos = _start; + *end_pos = _start + _size; + *data_end = 0; + + return L4_EOK; +} + +/* Map a flexpage corresponding to the dataspace 'offset' involving a 'hot_spot' + (flexpage offset). */ + +long Pager::map(offset_t offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region) +{ + offset_t file_offset = _start + offset; + offset_t max_offset = _start + _size; + Flexpage *flexpage = _mapper->get(file_offset, flags); + + /* Issue the flexpage via the IPC system. */ + + long err = ipc_prepare_flexpage(flexpage, file_offset, max_offset, hot_spot, region); + + if (!err) + err = complete_Dataspace_map(*region); + + /* After the flexpage is issued, it is queued for future reuse. */ + + _mapper->queue(flexpage); + + if (err) + return err; + + return IPC_MESSAGE_SENT; +} + +/* Return the total size of the data. */ + +offset_t Pager::get_data_size() +{ + return _mapper->get_data_size(); +} + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r 405eb83f7eed -r 5e0048b834f2 generic/pager.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/generic/pager.h Fri Apr 02 01:27:50 2021 +0200 @@ -0,0 +1,43 @@ +#pragma once + +#include + +#include "page_mapper.h" +#include "resource.h" + + + +/* A pager exposing a dataspace. */ + +class Pager : public Resource +{ +protected: + offset_t _start, _size; + PageMapper *_mapper; + flags_t _flags; + +public: + explicit Pager(PageMapper *mapper, flags_t flags); + + virtual void close(); + + /* Paging methods. */ + + virtual long map(offset_t offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region); + + /* Limit methods. */ + + offset_t get_data_size(); + + /* File methods. */ + + virtual long flush(offset_t populated_size, offset_t *size); + + virtual long resize(offset_t *size); + + /* Mapped file methods. */ + + virtual long mmap(offset_t position, offset_t length, offset_t *start_pos, offset_t *end_pos, offset_t *data_end); +}; + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r 405eb83f7eed -r 5e0048b834f2 generic/resource.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/generic/resource.h Fri Apr 02 01:27:50 2021 +0200 @@ -0,0 +1,56 @@ +/* + * Common resource classes and functions. + * + * Copyright (C) 2018, 2019, 2020 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#pragma once + +#include + + + +/* A generic class for an object potentially needing to be closed after use. */ + +class Resource +{ +public: + virtual ~Resource() + { + } + + /* Server details. */ + + virtual int expected_items() = 0; + + virtual ipc_server_handler_type handler() = 0; + + virtual void *interface() = 0; + + /* Deallocation of resources. */ + + virtual void close() + { + } + + /* Activation. */ + + virtual void activate() + { + } +}; diff -r 405eb83f7eed -r 5e0048b834f2 generic/simple_pager.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/generic/simple_pager.cc Fri Apr 02 01:27:50 2021 +0200 @@ -0,0 +1,62 @@ +#include + +#include "dataspace_server.h" +#include "memory_incremental.h" +#include "ipc.h" +#include "simple_pager.h" + + + +SimplePager::SimplePager(Memory *memory) +{ + if (memory == NULL) + _memory = new MemoryIncremental(); + else + _memory = memory; + + _region = _memory->region(); +} + +void SimplePager::close() +{ + if (_region != NULL) + { + _memory->release(_region); + _region = NULL; + } +} + +/* Map a flexpage corresponding to the dataspace 'offset' involving a 'hot_spot' + (flexpage offset). */ + +long SimplePager::map(offset_t offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region) +{ + Flexpage flexpage(_region); + + flexpage.reset(offset); + flexpage.upgrade(flags); + + /* Send the flexpage explicitly. */ + + long err = ipc_prepare_flexpage(&flexpage, offset, _region->size(), hot_spot, region); + + if (err) + return err; + + err = complete_Dataspace_map(*region); + + if (err) + return err; + + return IPC_MESSAGE_SENT; +} + +long SimplePager::info(offset_t *size, flags_t *flags) +{ + *size = _region->size(); + *flags = L4_FPAGE_RW; + + return L4_EOK; +} + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r 405eb83f7eed -r 5e0048b834f2 generic/simple_pager.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/generic/simple_pager.h Fri Apr 02 01:27:50 2021 +0200 @@ -0,0 +1,30 @@ +#pragma once + +#include "dataspace_interface.h" +#include "flexpage.h" +#include "memory.h" +#include "resource.h" + + + +/* A simple pager exposing a single memory region as a dataspace. */ + +class SimplePager : public Dataspace, public Resource +{ +protected: + Memory *_memory; + Region *_region; + +public: + explicit SimplePager(Memory *memory=NULL); + + void close(); + + /* Paging methods. */ + + long map(offset_t offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region); + + long info(offset_t *size, flags_t *flags); +}; + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r 405eb83f7eed -r 5e0048b834f2 generic/types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/generic/types.h Fri Apr 02 01:27:50 2021 +0200 @@ -0,0 +1,9 @@ +#pragma once + +/* File identification. */ + +typedef unsigned long fileid_t; + +#define FILEID_INVALID (~0UL) + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r 405eb83f7eed -r 5e0048b834f2 ipc.cc --- a/ipc.cc Thu Apr 01 00:57:43 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -#include -#include -#include - -#include "ipc.h" -#include "send_flexpage.h" - - - -/* Make an L4 representation of the given flexpage. */ - -static l4_fpage_t ipc_get_fpage(SendFlexpage *send_flexpage) -{ - return l4_fpage(send_flexpage->base_addr, send_flexpage->order, - (send_flexpage->flags & L4RE_DS_MAP_FLAG_RW) ? L4_FPAGE_RW : L4_FPAGE_RO); -} - -/* Make a representation of a flexpage for the IPC system. */ - -long ipc_prepare_flexpage(Flexpage *flexpage, unsigned long offset, - unsigned long max_offset, l4_addr_t hot_spot, - l4_snd_fpage_t *region) -{ - SendFlexpage send_flexpage = flexpage->to_send(offset, hot_spot, max_offset); - - /* NOTE: Consider l4_fpage_invalid() as the fpage here. */ - - if (!send_flexpage.order) - return -L4_ERANGE; - - region->fpage = ipc_get_fpage(&send_flexpage); - region->snd_base = hot_spot; - - return L4_EOK; -} - -/* Unmap the given flexpage. */ - -void ipc_unmap_flexpage(Flexpage *flexpage) -{ - SendFlexpage send_flexpage = flexpage->to_unmap(); - - l4_task_unmap(L4RE_THIS_TASK_CAP, ipc_get_fpage(&send_flexpage), L4_FP_OTHER_SPACES); -} - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r 405eb83f7eed -r 5e0048b834f2 ipc.h --- a/ipc.h Thu Apr 01 00:57:43 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -#pragma once - -#include - -#include "flexpage.h" - - - -long ipc_prepare_flexpage(Flexpage *flexpage, unsigned long offset, - unsigned long max_offset, l4_addr_t hot_spot, - l4_snd_fpage_t *region); - -void ipc_unmap_flexpage(Flexpage *flexpage); - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r 405eb83f7eed -r 5e0048b834f2 mapping/ipc.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mapping/ipc.cc Fri Apr 02 01:27:50 2021 +0200 @@ -0,0 +1,46 @@ +#include +#include +#include + +#include "ipc.h" +#include "send_flexpage.h" + + + +/* Make an L4 representation of the given flexpage. */ + +static l4_fpage_t ipc_get_fpage(SendFlexpage *send_flexpage) +{ + return l4_fpage(send_flexpage->base_addr, send_flexpage->order, + (send_flexpage->flags & L4RE_DS_MAP_FLAG_RW) ? L4_FPAGE_RW : L4_FPAGE_RO); +} + +/* Make a representation of a flexpage for the IPC system. */ + +long ipc_prepare_flexpage(Flexpage *flexpage, unsigned long offset, + unsigned long max_offset, l4_addr_t hot_spot, + l4_snd_fpage_t *region) +{ + SendFlexpage send_flexpage = flexpage->to_send(offset, hot_spot, max_offset); + + /* NOTE: Consider l4_fpage_invalid() as the fpage here. */ + + if (!send_flexpage.order) + return -L4_ERANGE; + + region->fpage = ipc_get_fpage(&send_flexpage); + region->snd_base = hot_spot; + + return L4_EOK; +} + +/* Unmap the given flexpage. */ + +void ipc_unmap_flexpage(Flexpage *flexpage) +{ + SendFlexpage send_flexpage = flexpage->to_unmap(); + + l4_task_unmap(L4RE_THIS_TASK_CAP, ipc_get_fpage(&send_flexpage), L4_FP_OTHER_SPACES); +} + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r 405eb83f7eed -r 5e0048b834f2 mapping/ipc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mapping/ipc.h Fri Apr 02 01:27:50 2021 +0200 @@ -0,0 +1,15 @@ +#pragma once + +#include + +#include "flexpage.h" + + + +long ipc_prepare_flexpage(Flexpage *flexpage, unsigned long offset, + unsigned long max_offset, l4_addr_t hot_spot, + l4_snd_fpage_t *region); + +void ipc_unmap_flexpage(Flexpage *flexpage); + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r 405eb83f7eed -r 5e0048b834f2 pager.cc --- a/pager.cc Thu Apr 01 00:57:43 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -#include "dataspace_server.h" -#include "ipc.h" -#include "pager.h" - - - -Pager::Pager(PageMapper *mapper, flags_t flags) -: _start(0), _size(0), _mapper(mapper), _flags(flags) -{ - /* Some pagers may not be initialised with a mapper. */ - - if (_mapper != NULL) - _mapper->attach(); -} - -/* Close the pager. */ - -void Pager::close() -{ - if (_mapper != NULL) - _mapper->detach(); -} - -/* Flush data to the file. */ - -long Pager::flush(offset_t populated_size, offset_t *size) -{ - _mapper->flush_all(_start, populated_size); - - *size = _mapper->get_data_size(); - return L4_EOK; -} - -/* Resize the underlying file. */ - -long Pager::resize(offset_t *size) -{ - _mapper->set_data_size(*size); - - *size = _mapper->get_data_size(); - return L4_EOK; -} - -/* Expose a region of the file. */ - -long Pager::mmap(offset_t position, offset_t length, offset_t *start_pos, offset_t *end_pos, offset_t *data_end) -{ - _start = trunc(position, PAGE_SIZE); - _size = round(position + length, PAGE_SIZE) - _start; - - *start_pos = _start; - *end_pos = _start + _size; - *data_end = 0; - - return L4_EOK; -} - -/* Map a flexpage corresponding to the dataspace 'offset' involving a 'hot_spot' - (flexpage offset). */ - -long Pager::map(offset_t offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region) -{ - offset_t file_offset = _start + offset; - offset_t max_offset = _start + _size; - Flexpage *flexpage = _mapper->get(file_offset, flags); - - /* Issue the flexpage via the IPC system. */ - - long err = ipc_prepare_flexpage(flexpage, file_offset, max_offset, hot_spot, region); - - if (!err) - err = complete_Dataspace_map(*region); - - /* After the flexpage is issued, it is queued for future reuse. */ - - _mapper->queue(flexpage); - - if (err) - return err; - - return IPC_MESSAGE_SENT; -} - -/* Return the total size of the data. */ - -offset_t Pager::get_data_size() -{ - return _mapper->get_data_size(); -} - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r 405eb83f7eed -r 5e0048b834f2 pager.h --- a/pager.h Thu Apr 01 00:57:43 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -#pragma once - -#include - -#include "page_mapper.h" -#include "resource.h" - - - -/* A pager exposing a dataspace. */ - -class Pager : public Resource -{ -protected: - offset_t _start, _size; - PageMapper *_mapper; - flags_t _flags; - -public: - explicit Pager(PageMapper *mapper, flags_t flags); - - virtual void close(); - - /* Paging methods. */ - - virtual long map(offset_t offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region); - - /* Limit methods. */ - - offset_t get_data_size(); - - /* File methods. */ - - virtual long flush(offset_t populated_size, offset_t *size); - - virtual long resize(offset_t *size); - - /* Mapped file methods. */ - - virtual long mmap(offset_t position, offset_t length, offset_t *start_pos, offset_t *end_pos, offset_t *data_end); -}; - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r 405eb83f7eed -r 5e0048b834f2 resource.h --- a/resource.h Thu Apr 01 00:57:43 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Common resource classes and functions. - * - * Copyright (C) 2018, 2019, 2020 Paul Boddie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA - */ - -#pragma once - -#include - - - -/* A generic class for an object potentially needing to be closed after use. */ - -class Resource -{ -public: - virtual ~Resource() - { - } - - /* Server details. */ - - virtual int expected_items() = 0; - - virtual ipc_server_handler_type handler() = 0; - - virtual void *interface() = 0; - - /* Deallocation of resources. */ - - virtual void close() - { - } - - /* Activation. */ - - virtual void activate() - { - } -}; diff -r 405eb83f7eed -r 5e0048b834f2 simple_pager.cc --- a/simple_pager.cc Thu Apr 01 00:57:43 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -#include - -#include "dataspace_server.h" -#include "memory_incremental.h" -#include "ipc.h" -#include "simple_pager.h" - - - -SimplePager::SimplePager(Memory *memory) -{ - if (memory == NULL) - _memory = new MemoryIncremental(); - else - _memory = memory; - - _region = _memory->region(); -} - -void SimplePager::close() -{ - if (_region != NULL) - { - _memory->release(_region); - _region = NULL; - } -} - -/* Map a flexpage corresponding to the dataspace 'offset' involving a 'hot_spot' - (flexpage offset). */ - -long SimplePager::map(offset_t offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region) -{ - Flexpage flexpage(_region); - - flexpage.reset(offset); - flexpage.upgrade(flags); - - /* Send the flexpage explicitly. */ - - long err = ipc_prepare_flexpage(&flexpage, offset, _region->size(), hot_spot, region); - - if (err) - return err; - - err = complete_Dataspace_map(*region); - - if (err) - return err; - - return IPC_MESSAGE_SENT; -} - -long SimplePager::info(offset_t *size, flags_t *flags) -{ - *size = _region->size(); - *flags = L4_FPAGE_RW; - - return L4_EOK; -} - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r 405eb83f7eed -r 5e0048b834f2 simple_pager.h --- a/simple_pager.h Thu Apr 01 00:57:43 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -#pragma once - -#include "dataspace_interface.h" -#include "flexpage.h" -#include "memory.h" -#include "resource.h" - - - -/* A simple pager exposing a single memory region as a dataspace. */ - -class SimplePager : public Dataspace, public Resource -{ -protected: - Memory *_memory; - Region *_region; - -public: - explicit SimplePager(Memory *memory=NULL); - - void close(); - - /* Paging methods. */ - - long map(offset_t offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region); - - long info(offset_t *size, flags_t *flags); -}; - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r 405eb83f7eed -r 5e0048b834f2 types.h --- a/types.h Thu Apr 01 00:57:43 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -#pragma once - -/* File identification. */ - -typedef unsigned long fileid_t; - -#define FILEID_INVALID (~0UL) - -// vim: tabstop=4 expandtab shiftwidth=4