1.1 --- a/Makefile Thu Apr 01 00:39:16 2021 +0200
1.2 +++ b/Makefile Thu Apr 01 00:57:43 2021 +0200
1.3 @@ -43,51 +43,54 @@
1.4
1.5 COMMON_SRC_CC = memory/memory_utils.cc
1.6
1.7 -PLAIN_SRC_CC_dstest_block_client = dstest_block_client.cc file.cc
1.8 +PLAIN_SRC_CC_dstest_block_client = tests/dstest_block_client.cc file.cc
1.9
1.10 -PLAIN_SRC_CC_dstest_host_client = dstest_host_client.cc file.cc
1.11 +PLAIN_SRC_CC_dstest_host_client = tests/dstest_host_client.cc file.cc
1.12
1.13 -PLAIN_SRC_CC_dstest_pipe_client = dstest_pipe_client.cc file.cc
1.14 +PLAIN_SRC_CC_dstest_pipe_client = tests/dstest_pipe_client.cc file.cc
1.15
1.16 -PLAIN_SRC_CC_dstest_test_client = dstest_test_client.cc file.cc
1.17 +PLAIN_SRC_CC_dstest_test_client = tests/dstest_test_client.cc file.cc
1.18
1.19 PLAIN_SRC_CC_common_server = \
1.20 - access_map.cc accessor.cc \
1.21 - flexpage.cc ipc.cc \
1.22 + accessor.cc \
1.23 + ipc.cc \
1.24 + mapping/access_map.cc mapping/flexpage.cc mapping/page_mapper.cc \
1.25 memory/memory_incremental.cc memory/memory_preallocated.cc \
1.26 memory/region.cc \
1.27 - page_mapper.cc pager.cc paging.cc \
1.28 + pager.cc \
1.29 pages/page_queue.cc pages/page_queue_partitioned.cc \
1.30 pages/page_queue_shared.cc pages/pages.cc \
1.31 - resource_server.cc simple_pager.cc
1.32 + resource_server.cc
1.33 +
1.34 +PLAIN_SRC_CC_common_file_server = \
1.35 + files/file_pager.cc files/file_paging.cc \
1.36 + files/opener_resource.cc files/opener_context_resource.cc \
1.37 + simple_pager.cc
1.38
1.39 PLAIN_SRC_CC_dstest_block_server = \
1.40 $(PLAIN_SRC_CC_common_server) \
1.41 - dstest_block_server.cc \
1.42 - files/file_pager.cc \
1.43 - files/opener_resource.cc files/opener_context_resource.cc \
1.44 + $(PLAIN_SRC_CC_common_file_server) \
1.45 files/block_file_accessor.cc files/block_file_opener.cc \
1.46 - files/host_file_accessor.cc files/host_file_opener.cc
1.47 + files/host_file_accessor.cc files/host_file_opener.cc \
1.48 + tests/dstest_block_server.cc
1.49
1.50 PLAIN_SRC_CC_dstest_host_server = \
1.51 $(PLAIN_SRC_CC_common_server) \
1.52 - dstest_host_server.cc \
1.53 - files/file_pager.cc \
1.54 - files/opener_resource.cc files/opener_context_resource.cc \
1.55 - files/host_file_accessor.cc files/host_file_opener.cc
1.56 + $(PLAIN_SRC_CC_common_file_server) \
1.57 + files/host_file_accessor.cc files/host_file_opener.cc \
1.58 + tests/dstest_host_server.cc
1.59
1.60 PLAIN_SRC_CC_dstest_pipe_server = \
1.61 $(PLAIN_SRC_CC_common_server) \
1.62 - dstest_pipe_server.cc \
1.63 pipes/pipe_opener_resource.cc pipes/pipe_pager.cc \
1.64 - pipes/pipe_accessor.cc pipes/pipe_paging.cc
1.65 + pipes/pipe_accessor.cc pipes/pipe_paging.cc \
1.66 + tests/dstest_pipe_server.cc
1.67
1.68 PLAIN_SRC_CC_dstest_test_server = \
1.69 $(PLAIN_SRC_CC_common_server) \
1.70 - dstest_test_server.cc \
1.71 - files/file_pager.cc \
1.72 - files/opener_resource.cc files/opener_context_resource.cc \
1.73 - files/test_file_accessor.cc files/test_file_opener.cc
1.74 + $(PLAIN_SRC_CC_common_file_server) \
1.75 + files/test_file_accessor.cc files/test_file_opener.cc \
1.76 + tests/dstest_test_server.cc
1.77
1.78 # Normal definitions.
1.79
1.80 @@ -133,8 +136,7 @@
1.81
1.82 REQUIRES_LIBS = l4re_c-util libipc libstdc++ libsystypes
1.83
1.84 -PRIVATE_INCDIR = $(PKGDIR) \
1.85 - $(PKGDIR)/files $(PKGDIR)/memory \
1.86 +PRIVATE_INCDIR = $(PKGDIR) $(PKGDIR)/files $(PKGDIR)/mapping $(PKGDIR)/memory \
1.87 $(PKGDIR)/pages $(PKGDIR)/pipes \
1.88 $(IDL_BUILD_DIR) $(IDL_EXPORT_DIR)
1.89
2.1 --- a/access_map.cc Thu Apr 01 00:39:16 2021 +0200
2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2.3 @@ -1,134 +0,0 @@
2.4 -#include "access_map.h"
2.5 -
2.6 -/* Return the flexpage supporting 'position'. */
2.7 -
2.8 -Flexpage *AccessMap::find(offset_t position)
2.9 -{
2.10 - std::lock_guard<std::mutex> guard(_lock);
2.11 -
2.12 - _AccessMap::iterator it = _flexpages.upper_bound(position);
2.13 -
2.14 - if ((_flexpages.size() > 0) && (it != _flexpages.begin()))
2.15 - {
2.16 - it--;
2.17 -
2.18 - if (it->second->supports_position(position))
2.19 - return it->second;
2.20 - }
2.21 -
2.22 - return NULL;
2.23 -}
2.24 -
2.25 -/* Insert a mapping for 'flexpage'. */
2.26 -
2.27 -void AccessMap::insert(Flexpage *flexpage)
2.28 -{
2.29 - std::lock_guard<std::mutex> guard(_lock);
2.30 -
2.31 - _flexpages.insert(_AccessMapEntry(flexpage->base_offset, flexpage));
2.32 -}
2.33 -
2.34 -/* Remove the mapping supported by 'flexpage'.
2.35 -
2.36 - The flexpage may have obtained by another mapper before being purged from
2.37 - this object's mapping and before being purged from the queue (and thus
2.38 - disassociated from this mapper), leaving an opportunity for another mapper to
2.39 - now be removing it here. In such a situation, flushing has already occurred
2.40 - and will not be performed again. */
2.41 -
2.42 -bool AccessMap::remove(PageOwner *owner, Flexpage *flexpage)
2.43 -{
2.44 - std::lock_guard<std::mutex> guard(_lock);
2.45 -
2.46 - _AccessMap::iterator it = _flexpages.find(flexpage->base_offset);
2.47 -
2.48 - if (it != _flexpages.end())
2.49 - {
2.50 - owner->flush(flexpage, true);
2.51 - _flexpages.erase(flexpage->base_offset);
2.52 - return true;
2.53 - }
2.54 -
2.55 - return false;
2.56 -}
2.57 -
2.58 -/* Purge all flexpages, using the 'owner' to flush their contents and
2.59 - 'pages' to make the flexpages available to other accessors. */
2.60 -
2.61 -void AccessMap::purge(PageOwner *owner, Pages *pages)
2.62 -{
2.63 - std::lock_guard<std::mutex> guard(_lock);
2.64 -
2.65 - _AccessMap::iterator it = _flexpages.begin(), entry;
2.66 -
2.67 - while (it != _flexpages.end())
2.68 - {
2.69 - entry = it;
2.70 - it++;
2.71 -
2.72 - Flexpage *flexpage = entry->second;
2.73 -
2.74 - /* Some flexpages may be unavailable in the queue. Only those
2.75 - that can be reserved should be flushed and made available
2.76 - again. */
2.77 -
2.78 - if (pages->reserve(owner, flexpage))
2.79 - {
2.80 - owner->flush(flexpage, true);
2.81 - pages->release(flexpage);
2.82 - _flexpages.erase(entry);
2.83 - }
2.84 - }
2.85 -}
2.86 -
2.87 -/* Flush flexpages in the given range from 'start' with 'size', using 'owner'
2.88 - and 'pages'. */
2.89 -
2.90 -void AccessMap::flush_all(offset_t start, offset_t size, PageOwner *owner, Pages *pages)
2.91 -{
2.92 - offset_t end = start + size;
2.93 -
2.94 - std::lock_guard<std::mutex> guard(_lock);
2.95 -
2.96 - /* The start may be within an existing flexpage where the flexpage size is a
2.97 - page multiple. */
2.98 -
2.99 - _AccessMap::iterator it = _flexpages.upper_bound(start), entry;
2.100 -
2.101 - if ((_flexpages.size() > 0) && (it != _flexpages.begin()))
2.102 - it--;
2.103 -
2.104 - /* Inspect flexpages at or after start until end. */
2.105 -
2.106 - while (it != _flexpages.end())
2.107 - {
2.108 - entry = it;
2.109 - it++;
2.110 -
2.111 - Flexpage *flexpage = entry->second;
2.112 -
2.113 - if (flexpage->base_offset >= end)
2.114 - break;
2.115 -
2.116 - /* Attempt to flush each flexpage, releasing ones that are no longer
2.117 - needed. */
2.118 -
2.119 - if (pages->reserve(owner, flexpage))
2.120 - {
2.121 - owner->flush(flexpage, false);
2.122 -
2.123 - /* Where no users of the flexpage persist, release the flexpage for
2.124 - reuse and remove this entry. */
2.125 -
2.126 - if (!flexpage->valid())
2.127 - {
2.128 - pages->release(flexpage);
2.129 - _flexpages.erase(entry);
2.130 - }
2.131 - else
2.132 - pages->queue(owner, flexpage);
2.133 - }
2.134 - }
2.135 -}
2.136 -
2.137 -// vim: tabstop=4 expandtab shiftwidth=4
3.1 --- a/access_map.h Thu Apr 01 00:39:16 2021 +0200
3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
3.3 @@ -1,35 +0,0 @@
3.4 -#pragma once
3.5 -
3.6 -#include "flexpage.h"
3.7 -#include "page_owner.h"
3.8 -#include "pages.h"
3.9 -
3.10 -#include <map>
3.11 -#include <mutex>
3.12 -
3.13 -/* Collection types. */
3.14 -
3.15 -typedef std::map<offset_t, Flexpage *> _AccessMap;
3.16 -typedef std::pair<offset_t, Flexpage *> _AccessMapEntry;
3.17 -
3.18 -/* A mapping from file positions to flexpages. */
3.19 -
3.20 -class AccessMap
3.21 -{
3.22 -protected:
3.23 - _AccessMap _flexpages;
3.24 - std::mutex _lock;
3.25 -
3.26 -public:
3.27 - Flexpage *find(offset_t position);
3.28 -
3.29 - void insert(Flexpage *flexpage);
3.30 -
3.31 - bool remove(PageOwner *owner, Flexpage *flexpage);
3.32 -
3.33 - void purge(PageOwner *owner, Pages *pages);
3.34 -
3.35 - void flush_all(offset_t start, offset_t size, PageOwner *owner, Pages *pages);
3.36 -};
3.37 -
3.38 -// vim: tabstop=4 expandtab shiftwidth=4
4.1 --- a/dstest_block_client.cc Thu Apr 01 00:39:16 2021 +0200
4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
4.3 @@ -1,128 +0,0 @@
4.4 -/*
4.5 - * Test dataspace operations.
4.6 - *
4.7 - * Copyright (C) 2020, 2021 Paul Boddie <paul@boddie.org.uk>
4.8 - *
4.9 - * This program is free software; you can redistribute it and/or
4.10 - * modify it under the terms of the GNU General Public License as
4.11 - * published by the Free Software Foundation; either version 2 of
4.12 - * the License, or (at your option) any later version.
4.13 - *
4.14 - * This program is distributed in the hope that it will be useful,
4.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
4.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.17 - * GNU General Public License for more details.
4.18 - *
4.19 - * You should have received a copy of the GNU General Public License
4.20 - * along with this program; if not, write to the Free Software
4.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor,
4.22 - * Boston, MA 02110-1301, USA
4.23 - */
4.24 -
4.25 -#include <l4/re/env.h>
4.26 -#include <l4/sys/err.h>
4.27 -
4.28 -#include <stdio.h>
4.29 -#include <string.h>
4.30 -#include <stdlib.h>
4.31 -
4.32 -#include "file.h"
4.33 -#include "memory_utils.h"
4.34 -
4.35 -
4.36 -
4.37 -static void show(file_t *file, unsigned long step, unsigned long sample)
4.38 -{
4.39 - /* Allocate a buffer for sampling from the file. */
4.40 -
4.41 - char buf[sample + 1];
4.42 -
4.43 - for (unsigned long offset = 0; offset < file_populated_span(file); offset += step)
4.44 - {
4.45 - unsigned long remaining = file_populated_span(file) - offset;
4.46 - unsigned long sample_remaining = remaining < sample ? remaining : sample;
4.47 -
4.48 - printf("%ld bytes from %p...\n", sample_remaining, (file->memory + offset));
4.49 - strncpy(buf, (file->memory + offset), sample_remaining);
4.50 - buf[sample_remaining] = '\0';
4.51 - printf("%s\n", buf);
4.52 - }
4.53 -}
4.54 -
4.55 -int main(int argc, char *argv[])
4.56 -{
4.57 - if (argc < 4)
4.58 - {
4.59 - printf("Need filename, step and sample size.\n");
4.60 - return 1;
4.61 - }
4.62 -
4.63 - /* Obtain filename and access parameters. */
4.64 -
4.65 - char *filename = argv[1];
4.66 - unsigned long step = atoi(argv[2]);
4.67 - unsigned long sample = atoi(argv[3]);
4.68 -
4.69 - /* Obtain access to the filesystem. */
4.70 -
4.71 - l4_cap_idx_t server = l4re_env_get_cap("server");
4.72 -
4.73 - /* Invoke the open method to receive the file reference. */
4.74 -
4.75 - file_t file;
4.76 - long err = file_open(&file, filename, server);
4.77 -
4.78 - if (err)
4.79 - {
4.80 - printf("Could not obtain file: %s\n", l4sys_errtostr(err));
4.81 - return 1;
4.82 - }
4.83 -
4.84 - /* A region of the file is mapped. */
4.85 -
4.86 - err = file_mmap(&file, 0, page(10));
4.87 -
4.88 - if (err)
4.89 - {
4.90 - printf("Could not map file region: %s\n", l4sys_errtostr(err));
4.91 - return 1;
4.92 - }
4.93 -
4.94 - show(&file, step, sample);
4.95 -
4.96 - /* Resizing must occur before writing beyond the end of file. Otherwise, the
4.97 - data may get discarded if the supporting flexpage needs to be flushed. */
4.98 -
4.99 - offset_t new_region = round(file_populated_span(&file), page(1));
4.100 -
4.101 - printf("Resize to %ld...\n", new_region + file_populated_span(&file));
4.102 -
4.103 - err = file_resize(&file, new_region + file_populated_span(&file));
4.104 -
4.105 - if (err)
4.106 - {
4.107 - printf("Could not resize file: %s\n", l4sys_errtostr(err));
4.108 - return 1;
4.109 - }
4.110 -
4.111 - printf("Resized file...\n");
4.112 -
4.113 - /* Copy the sampled data to another file region. */
4.114 -
4.115 - printf("Copy data to %ld...\n", new_region);
4.116 -
4.117 - for (unsigned long offset = 0; offset < file_populated_span(&file); offset += step)
4.118 - {
4.119 - memcpy(file.memory + new_region + offset, file.memory + offset, sample);
4.120 - if (step > sample)
4.121 - memset(file.memory + new_region + offset + sample, 0, step - sample);
4.122 - }
4.123 -
4.124 - show(&file, step, sample);
4.125 -
4.126 - printf("File shown.\n");
4.127 -
4.128 - return 0;
4.129 -}
4.130 -
4.131 -// vim: tabstop=2 expandtab shiftwidth=2
5.1 --- a/dstest_block_server.cc Thu Apr 01 00:39:16 2021 +0200
5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
5.3 @@ -1,65 +0,0 @@
5.4 -/*
5.5 - * Test dataspace operations.
5.6 - *
5.7 - * Copyright (C) 2020, 2021 Paul Boddie <paul@boddie.org.uk>
5.8 - *
5.9 - * This program is free software; you can redistribute it and/or
5.10 - * modify it under the terms of the GNU General Public License as
5.11 - * published by the Free Software Foundation; either version 2 of
5.12 - * the License, or (at your option) any later version.
5.13 - *
5.14 - * This program is distributed in the hope that it will be useful,
5.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
5.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5.17 - * GNU General Public License for more details.
5.18 - *
5.19 - * You should have received a copy of the GNU General Public License
5.20 - * along with this program; if not, write to the Free Software
5.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor,
5.22 - * Boston, MA 02110-1301, USA
5.23 - */
5.24 -
5.25 -#include <l4/re/env.h>
5.26 -#include <l4/sys/err.h>
5.27 -
5.28 -#include <stdio.h>
5.29 -#include <string.h>
5.30 -#include <stdlib.h>
5.31 -
5.32 -#include "memory_incremental.h"
5.33 -#include "memory_utils.h"
5.34 -#include "page_queue_shared.h"
5.35 -#include "pages.h"
5.36 -#include "resource_server.h"
5.37 -#include "block_file_opener.h"
5.38 -
5.39 -
5.40 -
5.41 -const unsigned int MEMORY_PAGES = 10;
5.42 -
5.43 -int main(void)
5.44 -{
5.45 - /* Some memory plus infrastructure. */
5.46 -
5.47 - MemoryIncremental mem(MEMORY_PAGES);
5.48 - PageQueueShared queue;
5.49 - Pages pages(&mem, &queue);
5.50 - BlockFileOpener opener(&pages);
5.51 -
5.52 - /* Register a server associating it with the given object. */
5.53 -
5.54 - ResourceServer server(&opener);
5.55 - long err = server.bind("server");
5.56 -
5.57 - if (err)
5.58 - {
5.59 - printf("Could not bind server: %s\n", l4sys_errtostr(err));
5.60 - return 1;
5.61 - }
5.62 -
5.63 - printf("Starting server...\n");
5.64 - server.start();
5.65 - return 0;
5.66 -}
5.67 -
5.68 -// vim: tabstop=2 expandtab shiftwidth=2
6.1 --- a/dstest_host_client.cc Thu Apr 01 00:39:16 2021 +0200
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,93 +0,0 @@
6.4 -/*
6.5 - * Test dataspace operations.
6.6 - *
6.7 - * Copyright (C) 2020, 2021 Paul Boddie <paul@boddie.org.uk>
6.8 - *
6.9 - * This program is free software; you can redistribute it and/or
6.10 - * modify it under the terms of the GNU General Public License as
6.11 - * published by the Free Software Foundation; either version 2 of
6.12 - * the License, or (at your option) any later version.
6.13 - *
6.14 - * This program is distributed in the hope that it will be useful,
6.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.17 - * GNU General Public License for more details.
6.18 - *
6.19 - * You should have received a copy of the GNU General Public License
6.20 - * along with this program; if not, write to the Free Software
6.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor,
6.22 - * Boston, MA 02110-1301, USA
6.23 - */
6.24 -
6.25 -#include <l4/re/env.h>
6.26 -#include <l4/sys/err.h>
6.27 -
6.28 -#include <stdio.h>
6.29 -#include <string.h>
6.30 -#include <stdlib.h>
6.31 -
6.32 -#include "file.h"
6.33 -#include "memory_utils.h"
6.34 -
6.35 -
6.36 -
6.37 -int main(int argc, char *argv[])
6.38 -{
6.39 - if (argc < 4)
6.40 - {
6.41 - printf("Need filename, step and sample size.\n");
6.42 - return 1;
6.43 - }
6.44 -
6.45 - /* Obtain filename and access parameters. */
6.46 -
6.47 - char *filename = argv[1];
6.48 - unsigned long step = atoi(argv[2]);
6.49 - unsigned long sample = atoi(argv[3]);
6.50 -
6.51 - /* Allocate a buffer for sampling from the file. */
6.52 -
6.53 - char buf[sample + 1];
6.54 -
6.55 - /* Obtain access to the filesystem. */
6.56 -
6.57 - l4_cap_idx_t server = l4re_env_get_cap("server");
6.58 -
6.59 - /* Invoke the open method to receive the file reference. */
6.60 -
6.61 - file_t file;
6.62 - long err = file_open(&file, filename, server);
6.63 -
6.64 - if (err)
6.65 - {
6.66 - printf("Could not obtain file: %s\n", l4sys_errtostr(err));
6.67 - return 1;
6.68 - }
6.69 -
6.70 - /* A region of the file is mapped. */
6.71 -
6.72 - err = file_mmap(&file, 0, page(10));
6.73 -
6.74 - if (err)
6.75 - {
6.76 - printf("Could not map file region: %s\n", l4sys_errtostr(err));
6.77 - return 1;
6.78 - }
6.79 -
6.80 - for (unsigned long offset = 0; offset < file_populated_span(&file); offset += step)
6.81 - {
6.82 - unsigned long remaining = file_populated_span(&file) - offset;
6.83 - unsigned long sample_remaining = remaining < sample ? remaining : sample;
6.84 -
6.85 - printf("%ld bytes from %p...\n", sample_remaining, (file.memory + offset));
6.86 - strncpy(buf, (file.memory + offset), sample_remaining);
6.87 - buf[sample_remaining] = '\0';
6.88 - printf("%s\n", buf);
6.89 - }
6.90 -
6.91 - printf("File shown.\n");
6.92 -
6.93 - return 0;
6.94 -}
6.95 -
6.96 -// vim: tabstop=2 expandtab shiftwidth=2
7.1 --- a/dstest_host_server.cc Thu Apr 01 00:39:16 2021 +0200
7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
7.3 @@ -1,63 +0,0 @@
7.4 -/*
7.5 - * Test dataspace operations.
7.6 - *
7.7 - * Copyright (C) 2020, 2021 Paul Boddie <paul@boddie.org.uk>
7.8 - *
7.9 - * This program is free software; you can redistribute it and/or
7.10 - * modify it under the terms of the GNU General Public License as
7.11 - * published by the Free Software Foundation; either version 2 of
7.12 - * the License, or (at your option) any later version.
7.13 - *
7.14 - * This program is distributed in the hope that it will be useful,
7.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
7.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7.17 - * GNU General Public License for more details.
7.18 - *
7.19 - * You should have received a copy of the GNU General Public License
7.20 - * along with this program; if not, write to the Free Software
7.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor,
7.22 - * Boston, MA 02110-1301, USA
7.23 - */
7.24 -
7.25 -#include <l4/re/env.h>
7.26 -#include <l4/sys/err.h>
7.27 -
7.28 -#include <stdio.h>
7.29 -#include <string.h>
7.30 -#include <stdlib.h>
7.31 -
7.32 -#include "memory_incremental.h"
7.33 -#include "memory_utils.h"
7.34 -#include "page_queue_shared.h"
7.35 -#include "pages.h"
7.36 -#include "resource_server.h"
7.37 -#include "host_file_opener.h"
7.38 -
7.39 -
7.40 -
7.41 -const unsigned int MEMORY_PAGES = 10;
7.42 -
7.43 -int main(void)
7.44 -{
7.45 - /* Some memory plus infrastructure. */
7.46 -
7.47 - MemoryIncremental mem(MEMORY_PAGES);
7.48 - PageQueueShared queue;
7.49 - Pages pages(&mem, &queue);
7.50 - HostFileOpener opener(&pages);
7.51 -
7.52 - /* Register a server associating it with the given object. */
7.53 -
7.54 - ResourceServer server(&opener);
7.55 - long err = server.bind("server");
7.56 -
7.57 - if (err)
7.58 - {
7.59 - printf("Could not bind server: %s\n", l4sys_errtostr(err));
7.60 - return 1;
7.61 - }
7.62 -
7.63 - printf("Starting server...\n");
7.64 - server.start();
7.65 - return 0;
7.66 -}
8.1 --- a/dstest_pipe_client.cc Thu Apr 01 00:39:16 2021 +0200
8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
8.3 @@ -1,121 +0,0 @@
8.4 -/*
8.5 - * Test pipe operations.
8.6 - *
8.7 - * Copyright (C) 2020, 2021 Paul Boddie <paul@boddie.org.uk>
8.8 - *
8.9 - * This program is free software; you can redistribute it and/or
8.10 - * modify it under the terms of the GNU General Public License as
8.11 - * published by the Free Software Foundation; either version 2 of
8.12 - * the License, or (at your option) any later version.
8.13 - *
8.14 - * This program is distributed in the hope that it will be useful,
8.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
8.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8.17 - * GNU General Public License for more details.
8.18 - *
8.19 - * You should have received a copy of the GNU General Public License
8.20 - * along with this program; if not, write to the Free Software
8.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor,
8.22 - * Boston, MA 02110-1301, USA
8.23 - */
8.24 -
8.25 -#include <l4/re/env.h>
8.26 -#include <l4/sys/err.h>
8.27 -
8.28 -#include <stdio.h>
8.29 -#include <string.h>
8.30 -#include <stdlib.h>
8.31 -
8.32 -#include "file.h"
8.33 -#include "memory_utils.h"
8.34 -
8.35 -
8.36 -
8.37 -static void show(file_t *file, offset_t step, offset_t sample)
8.38 -{
8.39 - /* Allocate a buffer for sampling from the file. */
8.40 -
8.41 - char buf[sample + 1];
8.42 -
8.43 - for (offset_t offset = 0; offset < file_populated_span(file); offset += step)
8.44 - {
8.45 - printf("show %ld of %ld...\n", offset, file_populated_span(file));
8.46 -
8.47 - unsigned long remaining = file_populated_span(file) - offset;
8.48 - unsigned long sample_remaining = remaining < sample ? remaining : sample;
8.49 -
8.50 - printf("%ld bytes from %p...\n", sample_remaining, (file->memory + offset));
8.51 - strncpy(buf, (file->memory + offset), sample_remaining);
8.52 - buf[sample_remaining] = '\0';
8.53 - printf("%s\n", buf);
8.54 - }
8.55 -}
8.56 -
8.57 -
8.58 -
8.59 -const unsigned int PIPE_PAGES = 2;
8.60 -
8.61 -int main(void)
8.62 -{
8.63 - /* Obtain access to the filesystem. */
8.64 -
8.65 - l4_cap_idx_t server = l4re_env_get_cap("server");
8.66 -
8.67 - /* Invoke the open method to receive the file reference. */
8.68 -
8.69 - file_t reader, writer;
8.70 - long err = pipe_open(page(PIPE_PAGES), &reader, &writer, server);
8.71 -
8.72 - if (err)
8.73 - {
8.74 - printf("Could not obtain pipe: %s\n", l4sys_errtostr(err));
8.75 - return 1;
8.76 - }
8.77 -
8.78 - /* Use the writer to fill the pipe with data. */
8.79 -
8.80 - for (int region = 0; region < 3; region++)
8.81 - {
8.82 - printf("Write %ld to pipe at %p...\n", file_span(&writer), writer.memory);
8.83 -
8.84 - memset(writer.memory, (int) 'a' + region, file_span(&writer));
8.85 -
8.86 - err = pipe_written(&writer, file_span(&writer));
8.87 -
8.88 - if (err)
8.89 - {
8.90 - printf("Written data error: %s\n", l4sys_errtostr(err));
8.91 - return 1;
8.92 - }
8.93 -
8.94 - show(&writer, page(1), 60);
8.95 -
8.96 - err = pipe_next(&writer);
8.97 -
8.98 - if (err)
8.99 - {
8.100 - printf("Region traversal error at region %d: %s\n", region, l4sys_errtostr(err));
8.101 - break;
8.102 - }
8.103 - }
8.104 -
8.105 - /* Use the reader to obtain data from the pipe. */
8.106 -
8.107 - err = pipe_current(&reader);
8.108 -
8.109 - while (!err)
8.110 - {
8.111 - printf("show...\n");
8.112 - show(&reader, page(1), 60);
8.113 - err = pipe_next(&reader);
8.114 - }
8.115 -
8.116 - if (err)
8.117 - printf("Reading termination condition: %s\n", l4sys_errtostr(err));
8.118 -
8.119 - printf("Data shown.\n");
8.120 -
8.121 - return 0;
8.122 -}
8.123 -
8.124 -// vim: tabstop=2 expandtab shiftwidth=2
9.1 --- a/dstest_pipe_server.cc Thu Apr 01 00:39:16 2021 +0200
9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
9.3 @@ -1,57 +0,0 @@
9.4 -/*
9.5 - * Test pipe operations.
9.6 - *
9.7 - * Copyright (C) 2020, 2021 Paul Boddie <paul@boddie.org.uk>
9.8 - *
9.9 - * This program is free software; you can redistribute it and/or
9.10 - * modify it under the terms of the GNU General Public License as
9.11 - * published by the Free Software Foundation; either version 2 of
9.12 - * the License, or (at your option) any later version.
9.13 - *
9.14 - * This program is distributed in the hope that it will be useful,
9.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
9.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9.17 - * GNU General Public License for more details.
9.18 - *
9.19 - * You should have received a copy of the GNU General Public License
9.20 - * along with this program; if not, write to the Free Software
9.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor,
9.22 - * Boston, MA 02110-1301, USA
9.23 - */
9.24 -
9.25 -#include <l4/sys/err.h>
9.26 -
9.27 -#include <stdio.h>
9.28 -
9.29 -#include "memory_incremental.h"
9.30 -#include "pipe_opener_resource.h"
9.31 -#include "resource_server.h"
9.32 -
9.33 -
9.34 -
9.35 -const unsigned int MEMORY_PAGES = 20;
9.36 -
9.37 -int main(void)
9.38 -{
9.39 - /* Some memory plus infrastructure. */
9.40 -
9.41 - MemoryIncremental mem(MEMORY_PAGES);
9.42 - PipeOpenerResource opener(&mem);
9.43 -
9.44 - /* Register a server associating it with the given object. */
9.45 -
9.46 - ResourceServer server(&opener);
9.47 - long err = server.bind("server");
9.48 -
9.49 - if (err)
9.50 - {
9.51 - printf("Could not bind server: %s\n", l4sys_errtostr(err));
9.52 - return 1;
9.53 - }
9.54 -
9.55 - printf("Starting server...\n");
9.56 - server.start();
9.57 - return 0;
9.58 -}
9.59 -
9.60 -// vim: tabstop=2 expandtab shiftwidth=2
10.1 --- a/dstest_test_client.cc Thu Apr 01 00:39:16 2021 +0200
10.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
10.3 @@ -1,242 +0,0 @@
10.4 -/*
10.5 - * Test dataspace operations.
10.6 - *
10.7 - * Copyright (C) 2020, 2021 Paul Boddie <paul@boddie.org.uk>
10.8 - *
10.9 - * This program is free software; you can redistribute it and/or
10.10 - * modify it under the terms of the GNU General Public License as
10.11 - * published by the Free Software Foundation; either version 2 of
10.12 - * the License, or (at your option) any later version.
10.13 - *
10.14 - * This program is distributed in the hope that it will be useful,
10.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
10.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10.17 - * GNU General Public License for more details.
10.18 - *
10.19 - * You should have received a copy of the GNU General Public License
10.20 - * along with this program; if not, write to the Free Software
10.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor,
10.22 - * Boston, MA 02110-1301, USA
10.23 - */
10.24 -
10.25 -#include <l4/re/env.h>
10.26 -#include <l4/sys/err.h>
10.27 -
10.28 -#include <stdio.h>
10.29 -#include <string.h>
10.30 -#include <stdlib.h>
10.31 -#include <time.h>
10.32 -
10.33 -#include <system_error>
10.34 -#include <thread>
10.35 -
10.36 -#include <ipc/thread.h>
10.37 -
10.38 -#include "file.h"
10.39 -#include "memory_utils.h"
10.40 -
10.41 -
10.42 -
10.43 -/* Test parameters affected by capability limits. */
10.44 -
10.45 -const unsigned long NUMBER_OF_FILES = 10;
10.46 -const unsigned int START_LIMIT = 10;
10.47 -const unsigned int ACTIVITY_ITERATIONS = 20;
10.48 -
10.49 -/* Test parameters unaffected by any capability limits. */
10.50 -
10.51 -const unsigned int MAP_PAGES = 20;
10.52 -const unsigned int REGION_ITERATIONS = 20;
10.53 -
10.54 -
10.55 -
10.56 -/* An activity opening and reading from a file. */
10.57 -
10.58 -static long activity(file_t *context, unsigned long fileid, unsigned int start_page)
10.59 -{
10.60 - unsigned long step = page(1);
10.61 - unsigned long sample = page(1);
10.62 -
10.63 - /* Allocate a buffer for sampling from the file. */
10.64 -
10.65 - char buf[sample + 1];
10.66 -
10.67 - /* Invoke the open method to receive the file reference. */
10.68 -
10.69 - file_t file;
10.70 -
10.71 - long err = file_context_open(&file, context);
10.72 -
10.73 - if (err)
10.74 - {
10.75 - printf("Could not obtain file for %ld @ page %d: %s\n", fileid, start_page, l4sys_errtostr(err));
10.76 - return err;
10.77 - }
10.78 -
10.79 - /* A region of the file is mapped. */
10.80 -
10.81 - err = file_mmap(&file, page(start_page), page(MAP_PAGES));
10.82 -
10.83 - if (err)
10.84 - {
10.85 - printf("Could not map file region for %ld @ page %d: %s\n", fileid, start_page, l4sys_errtostr(err));
10.86 - file_close(&file);
10.87 - return err;
10.88 - }
10.89 -
10.90 - /* Read the region a number of times. */
10.91 -
10.92 - for (unsigned int read_counter = 0; read_counter < REGION_ITERATIONS; read_counter++)
10.93 - {
10.94 - for (unsigned long offset = 0; offset < file_populated_span(&file); offset += step)
10.95 - {
10.96 - unsigned long remaining = file_populated_span(&file) - offset;
10.97 - unsigned long sample_remaining = remaining < sample ? remaining : sample;
10.98 -
10.99 - strncpy(buf, (file.memory + offset), sample_remaining);
10.100 - buf[sample_remaining] = '\0';
10.101 -
10.102 - /* Test the data obtained. */
10.103 -
10.104 - unsigned long filepos = file.start_pos + offset;
10.105 - unsigned long _fileid = 0, _filepos = 0;
10.106 - char *sep = strchr(buf, ':');
10.107 -
10.108 - if (sep != NULL)
10.109 - {
10.110 - *sep = '\0'; sep++;
10.111 - _fileid = atol(buf); _filepos = atol(sep);
10.112 - }
10.113 -
10.114 - if ((fileid != _fileid) || (filepos != _filepos))
10.115 - printf("! %ld:%ld is not %ld:%ld\n", _fileid, _filepos, fileid, filepos);
10.116 - }
10.117 - }
10.118 -
10.119 - file_close(&file);
10.120 -
10.121 - return L4_EOK;
10.122 -}
10.123 -
10.124 -
10.125 -
10.126 -static long activity_iterate(file_t *context, unsigned long fileid, unsigned int start_page)
10.127 -{
10.128 - long err;
10.129 -
10.130 - /* Open the file, read pages, close the file, over and over. */
10.131 -
10.132 - for (unsigned int iteration = 0; iteration < ACTIVITY_ITERATIONS; iteration++)
10.133 - {
10.134 - err = activity(context, fileid, start_page);
10.135 - if (err)
10.136 - break;
10.137 - }
10.138 -
10.139 - return err;
10.140 -}
10.141 -
10.142 -
10.143 -
10.144 -static long context_for_file(unsigned long fileid, file_t *file, l4_cap_idx_t server)
10.145 -{
10.146 - long err = file_context(file, server);
10.147 -
10.148 - if (err)
10.149 - {
10.150 - printf("Could not obtain context: %s\n", l4sys_errtostr(err));
10.151 - file_close(file);
10.152 - return err;
10.153 - }
10.154 -
10.155 - /* Write the filename. */
10.156 -
10.157 - sprintf(file->memory, "%ld", fileid);
10.158 -
10.159 - return L4_EOK;
10.160 -}
10.161 -
10.162 -
10.163 -
10.164 -int main(void)
10.165 -{
10.166 - long err;
10.167 -
10.168 - /* Introduce concurrency control. */
10.169 -
10.170 - err = ipc_thread_init();
10.171 -
10.172 - if (err)
10.173 - {
10.174 - printf("Initialisation error: %s\n", l4sys_errtostr(err));
10.175 - return 1;
10.176 - }
10.177 -
10.178 - /* Retain activity and context details. */
10.179 -
10.180 - std::thread *activities[NUMBER_OF_FILES * START_LIMIT];
10.181 - file_t contexts[NUMBER_OF_FILES];
10.182 -
10.183 - /* Obtain access to the filesystem. */
10.184 -
10.185 - l4_cap_idx_t server = l4re_env_get_cap("server");
10.186 -
10.187 - /* Obtain opener contexts for the files. */
10.188 -
10.189 - unsigned long fileid;
10.190 -
10.191 - for (fileid = 0; fileid < NUMBER_OF_FILES; fileid++)
10.192 - {
10.193 - err = context_for_file(fileid, &contexts[fileid], server);
10.194 -
10.195 - if (err)
10.196 - {
10.197 - printf("Context allocation failed.\n");
10.198 - return 1;
10.199 - }
10.200 - }
10.201 -
10.202 - /* Start threads accessing all the files. */
10.203 -
10.204 - printf("Starting threads...\n");
10.205 -
10.206 - time_t t = time(NULL);
10.207 - int current = 0;
10.208 - unsigned long errors = 0;
10.209 -
10.210 - for (fileid = 0; fileid < NUMBER_OF_FILES; fileid++)
10.211 - {
10.212 - for (unsigned int start_page = 0; start_page < START_LIMIT; start_page++)
10.213 - {
10.214 - try
10.215 - {
10.216 - activities[current++] = new std::thread(activity_iterate, &contexts[fileid], fileid, start_page);
10.217 - }
10.218 - catch (const std::system_error &exc)
10.219 - {
10.220 - errors++;
10.221 - }
10.222 - }
10.223 - }
10.224 -
10.225 - /* Wait for the threads. */
10.226 -
10.227 - int limit = current;
10.228 -
10.229 - printf("Waiting for %d threads...\n", limit);
10.230 -
10.231 - for (current = 0; current < limit; current++)
10.232 - activities[current]->join();
10.233 -
10.234 - /* Discard the contexts. */
10.235 -
10.236 - for (fileid = 0; fileid < NUMBER_OF_FILES; fileid++)
10.237 - file_close(&contexts[fileid]);
10.238 -
10.239 - t = time(NULL) - t;
10.240 - printf("Activities completed in %ld seconds (with %ld threads not started).\n", t, errors);
10.241 -
10.242 - return 0;
10.243 -}
10.244 -
10.245 -// vim: tabstop=2 expandtab shiftwidth=2
11.1 --- a/dstest_test_server.cc Thu Apr 01 00:39:16 2021 +0200
11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
11.3 @@ -1,88 +0,0 @@
11.4 -/*
11.5 - * Test dataspace operations.
11.6 - *
11.7 - * Copyright (C) 2020, 2021 Paul Boddie <paul@boddie.org.uk>
11.8 - *
11.9 - * This program is free software; you can redistribute it and/or
11.10 - * modify it under the terms of the GNU General Public License as
11.11 - * published by the Free Software Foundation; either version 2 of
11.12 - * the License, or (at your option) any later version.
11.13 - *
11.14 - * This program is distributed in the hope that it will be useful,
11.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
11.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11.17 - * GNU General Public License for more details.
11.18 - *
11.19 - * You should have received a copy of the GNU General Public License
11.20 - * along with this program; if not, write to the Free Software
11.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor,
11.22 - * Boston, MA 02110-1301, USA
11.23 - */
11.24 -
11.25 -#include <l4/re/env.h>
11.26 -#include <l4/sys/err.h>
11.27 -
11.28 -#include <ipc/thread.h>
11.29 -
11.30 -#include <stdio.h>
11.31 -#include <string.h>
11.32 -#include <stdlib.h>
11.33 -
11.34 -#include "memory_incremental.h"
11.35 -#include "memory_utils.h"
11.36 -#include "page_queue_shared.h"
11.37 -#include "pages.h"
11.38 -#include "resource_server.h"
11.39 -#include "test_file_opener.h"
11.40 -
11.41 -
11.42 -
11.43 -const unsigned int REGION_PAGES = 8;
11.44 -const unsigned int MEMORY_PAGES = REGION_PAGES * 10;
11.45 -const unsigned int FILE_PAGES = 20;
11.46 -
11.47 -int main(int argc, char *argv[])
11.48 -{
11.49 - long err;
11.50 -
11.51 - /* Introduce concurrency control. */
11.52 -
11.53 - err = ipc_thread_init();
11.54 -
11.55 - if (err)
11.56 - {
11.57 - printf("Initialisation error: %s\n", l4sys_errtostr(err));
11.58 - return 1;
11.59 - }
11.60 -
11.61 - /* Configure the number of available pages using any argument. */
11.62 -
11.63 - unsigned int memory_pages = MEMORY_PAGES;
11.64 -
11.65 - if (argc > 1)
11.66 - memory_pages = atoi(argv[1]) * REGION_PAGES;
11.67 -
11.68 - /* Some memory plus infrastructure. */
11.69 -
11.70 - MemoryIncremental mem(memory_pages, page(REGION_PAGES));
11.71 - PageQueueShared queue;
11.72 - Pages pages(&mem, &queue);
11.73 - TestFileOpener opener(&pages, page(FILE_PAGES));
11.74 -
11.75 - /* Register a server associating it with the given object. */
11.76 -
11.77 - ResourceServer server(&opener);
11.78 - err = server.bind("server");
11.79 -
11.80 - if (err)
11.81 - {
11.82 - printf("Could not bind server: %s\n", l4sys_errtostr(err));
11.83 - return 1;
11.84 - }
11.85 -
11.86 - printf("Starting server...\n");
11.87 - server.start();
11.88 - return 0;
11.89 -}
11.90 -
11.91 -// vim: tabstop=2 expandtab shiftwidth=2
12.1 --- a/files/file_pager.cc Thu Apr 01 00:39:16 2021 +0200
12.2 +++ b/files/file_pager.cc Thu Apr 01 00:57:43 2021 +0200
12.3 @@ -5,7 +5,7 @@
12.4 mapper for moderating access to loaded pages. */
12.5
12.6 FilePager::FilePager(fileid_t fileid, PageMapper *mapper, flags_t flags,
12.7 - Paging *paging)
12.8 + FilePaging *paging)
12.9 : Pager(mapper, flags), _paging(paging), fileid(fileid)
12.10 {
12.11 }
13.1 --- a/files/file_pager.h Thu Apr 01 00:39:16 2021 +0200
13.2 +++ b/files/file_pager.h Thu Apr 01 00:57:43 2021 +0200
13.3 @@ -2,20 +2,20 @@
13.4
13.5 #include "mapped_file_object_interface.h"
13.6 #include "pager.h"
13.7 -#include "paging.h"
13.8 +#include "file_paging.h"
13.9
13.10 /* A pager abstraction for a file. */
13.11
13.12 class FilePager : public Pager, public MappedFileObject
13.13 {
13.14 protected:
13.15 - Paging *_paging;
13.16 + FilePaging *_paging;
13.17
13.18 public:
13.19 fileid_t fileid;
13.20
13.21 explicit FilePager(fileid_t fileid, PageMapper *mapper, flags_t flags,
13.22 - Paging *paging);
13.23 + FilePaging *paging);
13.24
13.25 virtual void close();
13.26
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/files/file_paging.cc Thu Apr 01 00:57:43 2021 +0200
14.3 @@ -0,0 +1,88 @@
14.4 +#include "file_pager.h"
14.5 +#include "file_paging.h"
14.6 +
14.7 +
14.8 +
14.9 +FilePaging::FilePaging(Pages *pages)
14.10 +: _pages(pages)
14.11 +{
14.12 +}
14.13 +
14.14 +/* Return any registered page mapper for the given 'fileid' or NULL if no such
14.15 + mapper is registered. */
14.16 +
14.17 +PageMapper *FilePaging::get(fileid_t fileid)
14.18 +{
14.19 + FileMapping::iterator entry = _mappers.find(fileid);
14.20 + PageMapper *mapper;
14.21 +
14.22 + if (entry == _mappers.end())
14.23 + mapper = NULL;
14.24 + else
14.25 + mapper = entry->second;
14.26 +
14.27 + return mapper;
14.28 +}
14.29 +
14.30 +/* Register a page 'mapper' for the given 'fileid'. */
14.31 +
14.32 +void FilePaging::set(fileid_t fileid, PageMapper *mapper)
14.33 +{
14.34 + FileMapping::iterator entry = _mappers.find(fileid);
14.35 +
14.36 + if (entry == _mappers.end())
14.37 + _mappers[fileid] = mapper;
14.38 +}
14.39 +
14.40 +/* Obtain a page mapper for the 'fileid' or register a new one in the
14.41 + paging object. */
14.42 +
14.43 +PageMapper *FilePaging::get_mapper(fileid_t fileid)
14.44 +{
14.45 + /* Obtain any registered page mapper. */
14.46 +
14.47 + PageMapper *mapper = get(fileid);
14.48 +
14.49 + if (mapper != NULL)
14.50 + return mapper;
14.51 +
14.52 + /* Make an accessor and page mapper, registering the mapper. */
14.53 +
14.54 + Accessor *accessor = make_accessor(fileid);
14.55 + mapper = new PageMapper(accessor, _pages);
14.56 +
14.57 + set(fileid, mapper);
14.58 +
14.59 + return mapper;
14.60 +}
14.61 +
14.62 +
14.63 +
14.64 +/* Return a pager initialised with a page mapper. */
14.65 +
14.66 +Pager *FilePaging::get_pager(fileid_t fileid, flags_t flags)
14.67 +{
14.68 + std::lock_guard<std::mutex> guard(_lock);
14.69 +
14.70 + /* Initialise the pager with the mapper and a reference to this object for
14.71 + closing the mapper and accessor. */
14.72 +
14.73 + PageMapper *mapper = get_mapper(fileid);
14.74 + return new FilePager(fileid, mapper, flags, this);
14.75 +}
14.76 +
14.77 +/* Detach a pager, potentially removing its resources. */
14.78 +
14.79 +void FilePaging::detach_pager(fileid_t fileid, PageMapper *mapper)
14.80 +{
14.81 + std::lock_guard<std::mutex> guard(_lock);
14.82 +
14.83 + if (!mapper->detach())
14.84 + {
14.85 + _mappers.erase(fileid);
14.86 + delete mapper->accessor();
14.87 + delete mapper;
14.88 + }
14.89 +}
14.90 +
14.91 +// vim: tabstop=4 expandtab shiftwidth=4
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/files/file_paging.h Thu Apr 01 00:57:43 2021 +0200
15.3 @@ -0,0 +1,59 @@
15.4 +#pragma once
15.5 +
15.6 +#include <map>
15.7 +#include <mutex>
15.8 +
15.9 +#include "accessor.h"
15.10 +#include "pager.h"
15.11 +#include "page_mapper.h"
15.12 +
15.13 +
15.14 +
15.15 +/* Mapping type from accessors to page mappers. */
15.16 +
15.17 +typedef std::map<fileid_t, PageMapper *> FileMapping;
15.18 +typedef std::pair<fileid_t, PageMapper *> FileMappingEntry;
15.19 +
15.20 +
15.21 +
15.22 +/* A registry of mappers for accessors. */
15.23 +
15.24 +class FilePaging
15.25 +{
15.26 +protected:
15.27 + Pages *_pages;
15.28 +
15.29 + FileMapping _mappers;
15.30 + std::mutex _lock;
15.31 +
15.32 + /* Pager initialisation methods. */
15.33 +
15.34 + PageMapper *get_mapper(fileid_t fileid);
15.35 +
15.36 + Pager *get_pager(fileid_t fileid, flags_t flags);
15.37 +
15.38 + /* Configurable methods. */
15.39 +
15.40 + virtual fileid_t get_fileid(const char *path) = 0;
15.41 +
15.42 + virtual Accessor *make_accessor(fileid_t fileid) = 0;
15.43 +
15.44 + /* Mapper registry access. */
15.45 +
15.46 + PageMapper *get(fileid_t fileid);
15.47 +
15.48 + void set(fileid_t fileid, PageMapper *mapper);
15.49 +
15.50 +public:
15.51 + explicit FilePaging(Pages *pages);
15.52 +
15.53 + virtual ~FilePaging()
15.54 + {
15.55 + }
15.56 +
15.57 + /* Methods for the pager. */
15.58 +
15.59 + void detach_pager(fileid_t fileid, PageMapper *mapper);
15.60 +};
15.61 +
15.62 +// vim: tabstop=4 expandtab shiftwidth=4
16.1 --- a/files/opener_resource.cc Thu Apr 01 00:39:16 2021 +0200
16.2 +++ b/files/opener_resource.cc Thu Apr 01 00:57:43 2021 +0200
16.3 @@ -5,7 +5,7 @@
16.4 /* Support for providing access to files. */
16.5
16.6 OpenerResource::OpenerResource(Pages *pages)
16.7 -: Paging(pages)
16.8 +: FilePaging(pages)
16.9 {
16.10 }
16.11
17.1 --- a/files/opener_resource.h Thu Apr 01 00:39:16 2021 +0200
17.2 +++ b/files/opener_resource.h Thu Apr 01 00:57:43 2021 +0200
17.3 @@ -2,15 +2,15 @@
17.4
17.5 #include <l4/sys/ipc.h>
17.6
17.7 +#include "file_paging.h"
17.8 #include "opener_context_resource.h"
17.9 #include "opener_interface.h"
17.10 -#include "paging.h"
17.11 #include "pages.h"
17.12 #include "resource.h"
17.13
17.14 /* Support for providing access to files. */
17.15
17.16 -class OpenerResource : public Resource, public Paging, public Opener
17.17 +class OpenerResource : public Resource, public FilePaging, public Opener
17.18 {
17.19 public:
17.20 explicit OpenerResource(Pages *pages);
18.1 --- a/flexpage.cc Thu Apr 01 00:39:16 2021 +0200
18.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
18.3 @@ -1,137 +0,0 @@
18.4 -#include <algorithm>
18.5 -
18.6 -#include "flexpage.h"
18.7 -
18.8 -
18.9 -
18.10 -/* Reset the flexpage using 'offset', being the file offset. */
18.11 -
18.12 -void Flexpage::reset(offset_t offset)
18.13 -{
18.14 - _counter = 0;
18.15 -
18.16 - /* By definition (see "Flexible-Sized Page Objects - Object-Orientation
18.17 - in Operation Systems"), flexpages are aligned to multiples of their
18.18 - size.
18.19 -
18.20 - The size of the flexpage depends on the amount of space around the
18.21 - accessed page. It cannot exceed the size of the memory region. */
18.22 -
18.23 - size = max_multiple(region->start, region->end, PAGE_SIZE);
18.24 -
18.25 - /* The base address of the flexpage is computed from the region start
18.26 - and flexpage size. It will be no lower than the region start.
18.27 -
18.28 - Sent flexpages may use higher bases due to receive window constraints,
18.29 - these being communicated by the "hot spot". */
18.30 -
18.31 - base_addr = round(region->start, size);
18.32 -
18.33 - /* Get the file offset for the base of the flexpage. This will be a
18.34 - multiple of the flexpage size for alignment purposes. */
18.35 -
18.36 - base_offset = trunc(offset, size);
18.37 -
18.38 - /* The page being accessed is relative to the base.
18.39 - (This is transient information recording the initialising access
18.40 - details.) */
18.41 -
18.42 - page_offset = trunc(offset - base_offset, PAGE_SIZE);
18.43 - page_addr = base_addr + page_offset;
18.44 -}
18.45 -
18.46 -bool Flexpage::decrement()
18.47 -{
18.48 - if (_counter)
18.49 - {
18.50 - _counter--;
18.51 - return _counter == 0;
18.52 - }
18.53 - else
18.54 - return 0;
18.55 -}
18.56 -
18.57 -void Flexpage::increment()
18.58 -{
18.59 - _counter++;
18.60 -}
18.61 -
18.62 -void Flexpage::invalidate()
18.63 -{
18.64 - _counter = 0;
18.65 -}
18.66 -
18.67 -bool Flexpage::valid()
18.68 -{
18.69 - return _counter != 0;
18.70 -}
18.71 -
18.72 -/* Return whether the flexpage supports the given file 'position'. */
18.73 -
18.74 -bool Flexpage::supports_position(offset_t position)
18.75 -{
18.76 - return (base_offset <= position) && (position < (base_offset + size));
18.77 -}
18.78 -
18.79 -void Flexpage::upgrade(flags_t flags)
18.80 -{
18.81 - if (flags && (flags != _flags))
18.82 - _flags |= flags;
18.83 -}
18.84 -
18.85 -/* Return a "send" flexpage for an access to 'offset' by positioning it relative
18.86 - to 'hot_spot' for the receive flexpage window. */
18.87 -
18.88 -SendFlexpage Flexpage::to_send(offset_t offset, offset_t hot_spot, offset_t max_offset)
18.89 -{
18.90 - /* The dataspace offset of the flexpage base is a multiple of the flexpage
18.91 - size. */
18.92 -
18.93 - offset_t receive_base_offset = trunc(offset, size);
18.94 -
18.95 - /* The offset of the accessed page within the flexpage is constrained by the
18.96 - current flexpage size. */
18.97 -
18.98 - offset_t page_offset = trunc(offset - receive_base_offset, PAGE_SIZE);
18.99 -
18.100 - /* The receive flexpage offset (hot spot) must be constrained to the
18.101 - flexpage, both the size and the start. */
18.102 -
18.103 - offset_t receive_size;
18.104 -
18.105 - if (max_offset)
18.106 - {
18.107 - receive_size = trunc_multiple(max_offset - receive_base_offset, PAGE_SIZE);
18.108 - receive_size = std::min(size, receive_size);
18.109 - }
18.110 - else
18.111 - receive_size = size;
18.112 -
18.113 - if (!receive_size)
18.114 - return SendFlexpage(base_addr, page_order(0), _flags);
18.115 -
18.116 - offset_t receive_page_offset = hot_spot % receive_size;
18.117 -
18.118 - while ((receive_size > PAGE_SIZE) && (receive_page_offset != page_offset))
18.119 - {
18.120 - receive_size /= 2;
18.121 - receive_page_offset = hot_spot % receive_size;
18.122 - }
18.123 -
18.124 - /* The flexpage base address is adjusted using the difference in page
18.125 - offsets. Where the receive flexpage offset is constained further, the
18.126 - base address will be raised to become closer to the accessed page. */
18.127 -
18.128 - offset_t adjustment = page_offset - receive_page_offset;
18.129 -
18.130 - return SendFlexpage(base_addr + adjustment, page_order(receive_size), _flags);
18.131 -}
18.132 -
18.133 -/* Return a representation of the flexpage for unmapping. */
18.134 -
18.135 -SendFlexpage Flexpage::to_unmap()
18.136 -{
18.137 - return SendFlexpage(base_addr, page_order(size), _flags);
18.138 -}
18.139 -
18.140 -// vim: tabstop=4 expandtab shiftwidth=4
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/mapping/access_map.cc Thu Apr 01 00:57:43 2021 +0200
20.3 @@ -0,0 +1,134 @@
20.4 +#include "access_map.h"
20.5 +
20.6 +/* Return the flexpage supporting 'position'. */
20.7 +
20.8 +Flexpage *AccessMap::find(offset_t position)
20.9 +{
20.10 + std::lock_guard<std::mutex> guard(_lock);
20.11 +
20.12 + _AccessMap::iterator it = _flexpages.upper_bound(position);
20.13 +
20.14 + if ((_flexpages.size() > 0) && (it != _flexpages.begin()))
20.15 + {
20.16 + it--;
20.17 +
20.18 + if (it->second->supports_position(position))
20.19 + return it->second;
20.20 + }
20.21 +
20.22 + return NULL;
20.23 +}
20.24 +
20.25 +/* Insert a mapping for 'flexpage'. */
20.26 +
20.27 +void AccessMap::insert(Flexpage *flexpage)
20.28 +{
20.29 + std::lock_guard<std::mutex> guard(_lock);
20.30 +
20.31 + _flexpages.insert(_AccessMapEntry(flexpage->base_offset, flexpage));
20.32 +}
20.33 +
20.34 +/* Remove the mapping supported by 'flexpage'.
20.35 +
20.36 + The flexpage may have obtained by another mapper before being purged from
20.37 + this object's mapping and before being purged from the queue (and thus
20.38 + disassociated from this mapper), leaving an opportunity for another mapper to
20.39 + now be removing it here. In such a situation, flushing has already occurred
20.40 + and will not be performed again. */
20.41 +
20.42 +bool AccessMap::remove(PageOwner *owner, Flexpage *flexpage)
20.43 +{
20.44 + std::lock_guard<std::mutex> guard(_lock);
20.45 +
20.46 + _AccessMap::iterator it = _flexpages.find(flexpage->base_offset);
20.47 +
20.48 + if (it != _flexpages.end())
20.49 + {
20.50 + owner->flush(flexpage, true);
20.51 + _flexpages.erase(flexpage->base_offset);
20.52 + return true;
20.53 + }
20.54 +
20.55 + return false;
20.56 +}
20.57 +
20.58 +/* Purge all flexpages, using the 'owner' to flush their contents and
20.59 + 'pages' to make the flexpages available to other accessors. */
20.60 +
20.61 +void AccessMap::purge(PageOwner *owner, Pages *pages)
20.62 +{
20.63 + std::lock_guard<std::mutex> guard(_lock);
20.64 +
20.65 + _AccessMap::iterator it = _flexpages.begin(), entry;
20.66 +
20.67 + while (it != _flexpages.end())
20.68 + {
20.69 + entry = it;
20.70 + it++;
20.71 +
20.72 + Flexpage *flexpage = entry->second;
20.73 +
20.74 + /* Some flexpages may be unavailable in the queue. Only those
20.75 + that can be reserved should be flushed and made available
20.76 + again. */
20.77 +
20.78 + if (pages->reserve(owner, flexpage))
20.79 + {
20.80 + owner->flush(flexpage, true);
20.81 + pages->release(flexpage);
20.82 + _flexpages.erase(entry);
20.83 + }
20.84 + }
20.85 +}
20.86 +
20.87 +/* Flush flexpages in the given range from 'start' with 'size', using 'owner'
20.88 + and 'pages'. */
20.89 +
20.90 +void AccessMap::flush_all(offset_t start, offset_t size, PageOwner *owner, Pages *pages)
20.91 +{
20.92 + offset_t end = start + size;
20.93 +
20.94 + std::lock_guard<std::mutex> guard(_lock);
20.95 +
20.96 + /* The start may be within an existing flexpage where the flexpage size is a
20.97 + page multiple. */
20.98 +
20.99 + _AccessMap::iterator it = _flexpages.upper_bound(start), entry;
20.100 +
20.101 + if ((_flexpages.size() > 0) && (it != _flexpages.begin()))
20.102 + it--;
20.103 +
20.104 + /* Inspect flexpages at or after start until end. */
20.105 +
20.106 + while (it != _flexpages.end())
20.107 + {
20.108 + entry = it;
20.109 + it++;
20.110 +
20.111 + Flexpage *flexpage = entry->second;
20.112 +
20.113 + if (flexpage->base_offset >= end)
20.114 + break;
20.115 +
20.116 + /* Attempt to flush each flexpage, releasing ones that are no longer
20.117 + needed. */
20.118 +
20.119 + if (pages->reserve(owner, flexpage))
20.120 + {
20.121 + owner->flush(flexpage, false);
20.122 +
20.123 + /* Where no users of the flexpage persist, release the flexpage for
20.124 + reuse and remove this entry. */
20.125 +
20.126 + if (!flexpage->valid())
20.127 + {
20.128 + pages->release(flexpage);
20.129 + _flexpages.erase(entry);
20.130 + }
20.131 + else
20.132 + pages->queue(owner, flexpage);
20.133 + }
20.134 + }
20.135 +}
20.136 +
20.137 +// vim: tabstop=4 expandtab shiftwidth=4
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/mapping/access_map.h Thu Apr 01 00:57:43 2021 +0200
21.3 @@ -0,0 +1,35 @@
21.4 +#pragma once
21.5 +
21.6 +#include "flexpage.h"
21.7 +#include "page_owner.h"
21.8 +#include "pages.h"
21.9 +
21.10 +#include <map>
21.11 +#include <mutex>
21.12 +
21.13 +/* Collection types. */
21.14 +
21.15 +typedef std::map<offset_t, Flexpage *> _AccessMap;
21.16 +typedef std::pair<offset_t, Flexpage *> _AccessMapEntry;
21.17 +
21.18 +/* A mapping from file positions to flexpages. */
21.19 +
21.20 +class AccessMap
21.21 +{
21.22 +protected:
21.23 + _AccessMap _flexpages;
21.24 + std::mutex _lock;
21.25 +
21.26 +public:
21.27 + Flexpage *find(offset_t position);
21.28 +
21.29 + void insert(Flexpage *flexpage);
21.30 +
21.31 + bool remove(PageOwner *owner, Flexpage *flexpage);
21.32 +
21.33 + void purge(PageOwner *owner, Pages *pages);
21.34 +
21.35 + void flush_all(offset_t start, offset_t size, PageOwner *owner, Pages *pages);
21.36 +};
21.37 +
21.38 +// vim: tabstop=4 expandtab shiftwidth=4
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/mapping/flexpage.cc Thu Apr 01 00:57:43 2021 +0200
22.3 @@ -0,0 +1,137 @@
22.4 +#include <algorithm>
22.5 +
22.6 +#include "flexpage.h"
22.7 +
22.8 +
22.9 +
22.10 +/* Reset the flexpage using 'offset', being the file offset. */
22.11 +
22.12 +void Flexpage::reset(offset_t offset)
22.13 +{
22.14 + _counter = 0;
22.15 +
22.16 + /* By definition (see "Flexible-Sized Page Objects - Object-Orientation
22.17 + in Operation Systems"), flexpages are aligned to multiples of their
22.18 + size.
22.19 +
22.20 + The size of the flexpage depends on the amount of space around the
22.21 + accessed page. It cannot exceed the size of the memory region. */
22.22 +
22.23 + size = max_multiple(region->start, region->end, PAGE_SIZE);
22.24 +
22.25 + /* The base address of the flexpage is computed from the region start
22.26 + and flexpage size. It will be no lower than the region start.
22.27 +
22.28 + Sent flexpages may use higher bases due to receive window constraints,
22.29 + these being communicated by the "hot spot". */
22.30 +
22.31 + base_addr = round(region->start, size);
22.32 +
22.33 + /* Get the file offset for the base of the flexpage. This will be a
22.34 + multiple of the flexpage size for alignment purposes. */
22.35 +
22.36 + base_offset = trunc(offset, size);
22.37 +
22.38 + /* The page being accessed is relative to the base.
22.39 + (This is transient information recording the initialising access
22.40 + details.) */
22.41 +
22.42 + page_offset = trunc(offset - base_offset, PAGE_SIZE);
22.43 + page_addr = base_addr + page_offset;
22.44 +}
22.45 +
22.46 +bool Flexpage::decrement()
22.47 +{
22.48 + if (_counter)
22.49 + {
22.50 + _counter--;
22.51 + return _counter == 0;
22.52 + }
22.53 + else
22.54 + return 0;
22.55 +}
22.56 +
22.57 +void Flexpage::increment()
22.58 +{
22.59 + _counter++;
22.60 +}
22.61 +
22.62 +void Flexpage::invalidate()
22.63 +{
22.64 + _counter = 0;
22.65 +}
22.66 +
22.67 +bool Flexpage::valid()
22.68 +{
22.69 + return _counter != 0;
22.70 +}
22.71 +
22.72 +/* Return whether the flexpage supports the given file 'position'. */
22.73 +
22.74 +bool Flexpage::supports_position(offset_t position)
22.75 +{
22.76 + return (base_offset <= position) && (position < (base_offset + size));
22.77 +}
22.78 +
22.79 +void Flexpage::upgrade(flags_t flags)
22.80 +{
22.81 + if (flags && (flags != _flags))
22.82 + _flags |= flags;
22.83 +}
22.84 +
22.85 +/* Return a "send" flexpage for an access to 'offset' by positioning it relative
22.86 + to 'hot_spot' for the receive flexpage window. */
22.87 +
22.88 +SendFlexpage Flexpage::to_send(offset_t offset, offset_t hot_spot, offset_t max_offset)
22.89 +{
22.90 + /* The dataspace offset of the flexpage base is a multiple of the flexpage
22.91 + size. */
22.92 +
22.93 + offset_t receive_base_offset = trunc(offset, size);
22.94 +
22.95 + /* The offset of the accessed page within the flexpage is constrained by the
22.96 + current flexpage size. */
22.97 +
22.98 + offset_t page_offset = trunc(offset - receive_base_offset, PAGE_SIZE);
22.99 +
22.100 + /* The receive flexpage offset (hot spot) must be constrained to the
22.101 + flexpage, both the size and the start. */
22.102 +
22.103 + offset_t receive_size;
22.104 +
22.105 + if (max_offset)
22.106 + {
22.107 + receive_size = trunc_multiple(max_offset - receive_base_offset, PAGE_SIZE);
22.108 + receive_size = std::min(size, receive_size);
22.109 + }
22.110 + else
22.111 + receive_size = size;
22.112 +
22.113 + if (!receive_size)
22.114 + return SendFlexpage(base_addr, page_order(0), _flags);
22.115 +
22.116 + offset_t receive_page_offset = hot_spot % receive_size;
22.117 +
22.118 + while ((receive_size > PAGE_SIZE) && (receive_page_offset != page_offset))
22.119 + {
22.120 + receive_size /= 2;
22.121 + receive_page_offset = hot_spot % receive_size;
22.122 + }
22.123 +
22.124 + /* The flexpage base address is adjusted using the difference in page
22.125 + offsets. Where the receive flexpage offset is constained further, the
22.126 + base address will be raised to become closer to the accessed page. */
22.127 +
22.128 + offset_t adjustment = page_offset - receive_page_offset;
22.129 +
22.130 + return SendFlexpage(base_addr + adjustment, page_order(receive_size), _flags);
22.131 +}
22.132 +
22.133 +/* Return a representation of the flexpage for unmapping. */
22.134 +
22.135 +SendFlexpage Flexpage::to_unmap()
22.136 +{
22.137 + return SendFlexpage(base_addr, page_order(size), _flags);
22.138 +}
22.139 +
22.140 +// vim: tabstop=4 expandtab shiftwidth=4
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/mapping/page_mapper.cc Thu Apr 01 00:57:43 2021 +0200
24.3 @@ -0,0 +1,175 @@
24.4 +#include "ipc.h"
24.5 +#include "page_mapper.h"
24.6 +
24.7 +
24.8 +
24.9 +PageMapper::PageMapper(Accessor *accessor, Pages *pages)
24.10 +: _accessor(accessor), _pages(pages), _attached(0)
24.11 +{
24.12 +}
24.13 +
24.14 +/* Accounting methods. */
24.15 +
24.16 +/* Attach a pager, opening the accessor if required. */
24.17 +
24.18 +void PageMapper::attach()
24.19 +{
24.20 + std::lock_guard<std::mutex> guard(_lock);
24.21 +
24.22 + if (!_attached)
24.23 + _accessor->open();
24.24 +
24.25 + _attached += 1;
24.26 +}
24.27 +
24.28 +/* Detach a pager, purging active pages and closing the accessor if no more
24.29 + pagers are attached. Return whether any pagers are still attached. */
24.30 +
24.31 +unsigned int PageMapper::detach()
24.32 +{
24.33 + std::lock_guard<std::mutex> guard(_lock);
24.34 +
24.35 + if (_attached)
24.36 + {
24.37 + _attached -= 1;
24.38 +
24.39 + if (!_attached)
24.40 + {
24.41 + _map.purge(this, _pages);
24.42 + _accessor->close();
24.43 + }
24.44 + }
24.45 +
24.46 + return _attached;
24.47 +}
24.48 +
24.49 +/* Interface for the pager. */
24.50 +
24.51 +/* Return a flexpage providing access to the indicated file 'offset'.
24.52 +
24.53 + The returned flexpage will either be an existing, compatible flexpage or a
24.54 + completely new flexpage.
24.55 +
24.56 + This method locks the mapper to prevent concurrent queries with the same
24.57 + details, with the lock held until the queue operation releases the lock. */
24.58 +
24.59 +Flexpage *PageMapper::get(offset_t offset, flags_t flags)
24.60 +{
24.61 + _lock.lock();
24.62 +
24.63 + Flexpage *f = find(offset);
24.64 +
24.65 + if (f == NULL)
24.66 + f = flexpage(offset);
24.67 +
24.68 + /* Record a new user of the flexpage and upgrade the access flags. */
24.69 +
24.70 + f->increment();
24.71 + f->upgrade(flags);
24.72 + return f;
24.73 +}
24.74 +
24.75 +/* Queue the given 'flexpage' in the page collection, making it available for
24.76 + eventual reuse.
24.77 +
24.78 + This method unlocks the mapper. */
24.79 +
24.80 +void PageMapper::queue(Flexpage *flexpage)
24.81 +{
24.82 + _pages->queue(this, flexpage);
24.83 +
24.84 + _lock.unlock();
24.85 +}
24.86 +
24.87 +/* Flush pages in the given range from 'start' with 'size'. */
24.88 +
24.89 +void PageMapper::flush_all(offset_t start, offset_t size)
24.90 +{
24.91 + std::lock_guard<std::mutex> guard(_lock);
24.92 +
24.93 + _map.flush_all(start, size, this, _pages);
24.94 +}
24.95 +
24.96 +/* Return the maximum extent of the mapped resource. */
24.97 +
24.98 +offset_t PageMapper::get_data_size()
24.99 +{
24.100 + return _accessor->get_size();
24.101 +}
24.102 +
24.103 +/* Set the maximum extent of the mapped resource. */
24.104 +
24.105 +void PageMapper::set_data_size(offset_t size)
24.106 +{
24.107 + _accessor->set_size(size);
24.108 +}
24.109 +
24.110 +/* Internal flexpage retrieval methods. */
24.111 +
24.112 +/* Find an existing flexpage for 'offset'. Where the accessor has registered a
24.113 + compatible flexpage, an attempt is made to reserve it in the page collection;
24.114 + if this succeeds, the flexpage is returned. Otherwise, NULL is returned. */
24.115 +
24.116 +Flexpage *PageMapper::find(offset_t offset)
24.117 +{
24.118 + Flexpage *flexpage = _map.find(offset);
24.119 +
24.120 + /* Between finding and reserving a flexpage, there is a possibility that
24.121 + another accessor might acquire the flexpage, issue it, and even purge
24.122 + it. */
24.123 +
24.124 + if ((flexpage != NULL) && _pages->reserve(this, flexpage))
24.125 + return flexpage;
24.126 + else
24.127 + return NULL;
24.128 +}
24.129 +
24.130 +/* Obtain a new flexpage for the file 'offset'. If the page collection is unable
24.131 + to obtain a completely new flexpage, an existing flexpage is requested from
24.132 + the page collection and recycled.
24.133 +
24.134 + The obtained flexpage is filled with content. */
24.135 +
24.136 +Flexpage *PageMapper::flexpage(offset_t offset)
24.137 +{
24.138 + Flexpage *flexpage = _pages->flexpage();
24.139 +
24.140 + /* Obtain an existing flexpage and reuse it. */
24.141 +
24.142 + if (flexpage == NULL)
24.143 + flexpage = _pages->remove();
24.144 +
24.145 + flexpage->reset(offset);
24.146 +
24.147 + fill(flexpage);
24.148 + _map.insert(flexpage);
24.149 + return flexpage;
24.150 +}
24.151 +
24.152 +/* Interface for the page collection. */
24.153 +
24.154 +/* Remove the record of 'flexpage' in this accessor, flushing its content. */
24.155 +
24.156 +void PageMapper::remove(Flexpage *flexpage)
24.157 +{
24.158 + _map.remove(this, flexpage);
24.159 +}
24.160 +
24.161 +/* Data transfer methods. */
24.162 +
24.163 +void PageMapper::fill(Flexpage *flexpage)
24.164 +{
24.165 + _accessor->fill(flexpage);
24.166 +}
24.167 +
24.168 +void PageMapper::flush(Flexpage *flexpage, bool purge)
24.169 +{
24.170 + if (flexpage->decrement() || purge)
24.171 + {
24.172 + _accessor->flush(flexpage);
24.173 + ipc_unmap_flexpage(flexpage);
24.174 + flexpage->invalidate();
24.175 + }
24.176 +}
24.177 +
24.178 +// vim: tabstop=4 expandtab shiftwidth=4
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/mapping/page_mapper.h Thu Apr 01 00:57:43 2021 +0200
25.3 @@ -0,0 +1,64 @@
25.4 +#pragma once
25.5 +
25.6 +#include "access_map.h"
25.7 +#include "accessor.h"
25.8 +#include "page_owner.h"
25.9 +
25.10 +#include <mutex>
25.11 +
25.12 +/* A file mapper, associating flexpages with file regions. */
25.13 +
25.14 +class PageMapper : public PageOwner
25.15 +{
25.16 +protected:
25.17 + AccessMap _map;
25.18 + Accessor *_accessor;
25.19 + Pages *_pages;
25.20 + unsigned int _attached;
25.21 +
25.22 + /* Serialisation of accesses. */
25.23 +
25.24 + std::mutex _lock;
25.25 +
25.26 + /* Internal flexpage retrieval methods. */
25.27 +
25.28 + Flexpage *find(offset_t offset);
25.29 +
25.30 + Flexpage *flexpage(offset_t offset);
25.31 +
25.32 +public:
25.33 + explicit PageMapper(Accessor *accessor, Pages *pages);
25.34 +
25.35 + /* Accounting methods. */
25.36 +
25.37 + void attach();
25.38 +
25.39 + unsigned int detach();
25.40 +
25.41 + Accessor *accessor()
25.42 + { return _accessor; }
25.43 +
25.44 + /* Interface for the pager. */
25.45 +
25.46 + Flexpage *get(offset_t offset, flags_t flags);
25.47 +
25.48 + void queue(Flexpage *flexpage);
25.49 +
25.50 + void flush_all(offset_t start, offset_t size);
25.51 +
25.52 + offset_t get_data_size();
25.53 +
25.54 + void set_data_size(offset_t size);
25.55 +
25.56 + /* Data transfer methods, implementing PageOwner. */
25.57 +
25.58 + void fill(Flexpage *flexpage);
25.59 +
25.60 + void flush(Flexpage *flexpage, bool purge);
25.61 +
25.62 + /* Interface for the page collection, implementing PageOwner. */
25.63 +
25.64 + void remove(Flexpage *flexpage);
25.65 +};
25.66 +
25.67 +// vim: tabstop=4 expandtab shiftwidth=4
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/mapping/send_flexpage.h Thu Apr 01 00:57:43 2021 +0200
27.3 @@ -0,0 +1,21 @@
27.4 +#pragma once
27.5 +
27.6 +#include "types.h"
27.7 +
27.8 +/* A "send" flexpage abstraction. */
27.9 +
27.10 +class SendFlexpage
27.11 +{
27.12 +public:
27.13 + offset_t base_addr;
27.14 + unsigned int order;
27.15 + flags_t flags;
27.16 +
27.17 + explicit SendFlexpage(offset_t base_addr, unsigned int order,
27.18 + flags_t flags)
27.19 + : base_addr(base_addr), order(order), flags(flags)
27.20 + {
27.21 + }
27.22 +};
27.23 +
27.24 +// vim: tabstop=4 expandtab shiftwidth=4
28.1 --- a/page_mapper.cc Thu Apr 01 00:39:16 2021 +0200
28.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
28.3 @@ -1,175 +0,0 @@
28.4 -#include "ipc.h"
28.5 -#include "page_mapper.h"
28.6 -
28.7 -
28.8 -
28.9 -PageMapper::PageMapper(Accessor *accessor, Pages *pages)
28.10 -: _accessor(accessor), _pages(pages), _attached(0)
28.11 -{
28.12 -}
28.13 -
28.14 -/* Accounting methods. */
28.15 -
28.16 -/* Attach a pager, opening the accessor if required. */
28.17 -
28.18 -void PageMapper::attach()
28.19 -{
28.20 - std::lock_guard<std::mutex> guard(_lock);
28.21 -
28.22 - if (!_attached)
28.23 - _accessor->open();
28.24 -
28.25 - _attached += 1;
28.26 -}
28.27 -
28.28 -/* Detach a pager, purging active pages and closing the accessor if no more
28.29 - pagers are attached. Return whether any pagers are still attached. */
28.30 -
28.31 -unsigned int PageMapper::detach()
28.32 -{
28.33 - std::lock_guard<std::mutex> guard(_lock);
28.34 -
28.35 - if (_attached)
28.36 - {
28.37 - _attached -= 1;
28.38 -
28.39 - if (!_attached)
28.40 - {
28.41 - _map.purge(this, _pages);
28.42 - _accessor->close();
28.43 - }
28.44 - }
28.45 -
28.46 - return _attached;
28.47 -}
28.48 -
28.49 -/* Interface for the pager. */
28.50 -
28.51 -/* Return a flexpage providing access to the indicated file 'offset'.
28.52 -
28.53 - The returned flexpage will either be an existing, compatible flexpage or a
28.54 - completely new flexpage.
28.55 -
28.56 - This method locks the mapper to prevent concurrent queries with the same
28.57 - details, with the lock held until the queue operation releases the lock. */
28.58 -
28.59 -Flexpage *PageMapper::get(offset_t offset, flags_t flags)
28.60 -{
28.61 - _lock.lock();
28.62 -
28.63 - Flexpage *f = find(offset);
28.64 -
28.65 - if (f == NULL)
28.66 - f = flexpage(offset);
28.67 -
28.68 - /* Record a new user of the flexpage and upgrade the access flags. */
28.69 -
28.70 - f->increment();
28.71 - f->upgrade(flags);
28.72 - return f;
28.73 -}
28.74 -
28.75 -/* Queue the given 'flexpage' in the page collection, making it available for
28.76 - eventual reuse.
28.77 -
28.78 - This method unlocks the mapper. */
28.79 -
28.80 -void PageMapper::queue(Flexpage *flexpage)
28.81 -{
28.82 - _pages->queue(this, flexpage);
28.83 -
28.84 - _lock.unlock();
28.85 -}
28.86 -
28.87 -/* Flush pages in the given range from 'start' with 'size'. */
28.88 -
28.89 -void PageMapper::flush_all(offset_t start, offset_t size)
28.90 -{
28.91 - std::lock_guard<std::mutex> guard(_lock);
28.92 -
28.93 - _map.flush_all(start, size, this, _pages);
28.94 -}
28.95 -
28.96 -/* Return the maximum extent of the mapped resource. */
28.97 -
28.98 -offset_t PageMapper::get_data_size()
28.99 -{
28.100 - return _accessor->get_size();
28.101 -}
28.102 -
28.103 -/* Set the maximum extent of the mapped resource. */
28.104 -
28.105 -void PageMapper::set_data_size(offset_t size)
28.106 -{
28.107 - _accessor->set_size(size);
28.108 -}
28.109 -
28.110 -/* Internal flexpage retrieval methods. */
28.111 -
28.112 -/* Find an existing flexpage for 'offset'. Where the accessor has registered a
28.113 - compatible flexpage, an attempt is made to reserve it in the page collection;
28.114 - if this succeeds, the flexpage is returned. Otherwise, NULL is returned. */
28.115 -
28.116 -Flexpage *PageMapper::find(offset_t offset)
28.117 -{
28.118 - Flexpage *flexpage = _map.find(offset);
28.119 -
28.120 - /* Between finding and reserving a flexpage, there is a possibility that
28.121 - another accessor might acquire the flexpage, issue it, and even purge
28.122 - it. */
28.123 -
28.124 - if ((flexpage != NULL) && _pages->reserve(this, flexpage))
28.125 - return flexpage;
28.126 - else
28.127 - return NULL;
28.128 -}
28.129 -
28.130 -/* Obtain a new flexpage for the file 'offset'. If the page collection is unable
28.131 - to obtain a completely new flexpage, an existing flexpage is requested from
28.132 - the page collection and recycled.
28.133 -
28.134 - The obtained flexpage is filled with content. */
28.135 -
28.136 -Flexpage *PageMapper::flexpage(offset_t offset)
28.137 -{
28.138 - Flexpage *flexpage = _pages->flexpage();
28.139 -
28.140 - /* Obtain an existing flexpage and reuse it. */
28.141 -
28.142 - if (flexpage == NULL)
28.143 - flexpage = _pages->remove();
28.144 -
28.145 - flexpage->reset(offset);
28.146 -
28.147 - fill(flexpage);
28.148 - _map.insert(flexpage);
28.149 - return flexpage;
28.150 -}
28.151 -
28.152 -/* Interface for the page collection. */
28.153 -
28.154 -/* Remove the record of 'flexpage' in this accessor, flushing its content. */
28.155 -
28.156 -void PageMapper::remove(Flexpage *flexpage)
28.157 -{
28.158 - _map.remove(this, flexpage);
28.159 -}
28.160 -
28.161 -/* Data transfer methods. */
28.162 -
28.163 -void PageMapper::fill(Flexpage *flexpage)
28.164 -{
28.165 - _accessor->fill(flexpage);
28.166 -}
28.167 -
28.168 -void PageMapper::flush(Flexpage *flexpage, bool purge)
28.169 -{
28.170 - if (flexpage->decrement() || purge)
28.171 - {
28.172 - _accessor->flush(flexpage);
28.173 - ipc_unmap_flexpage(flexpage);
28.174 - flexpage->invalidate();
28.175 - }
28.176 -}
28.177 -
28.178 -// vim: tabstop=4 expandtab shiftwidth=4
29.1 --- a/page_mapper.h Thu Apr 01 00:39:16 2021 +0200
29.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
29.3 @@ -1,64 +0,0 @@
29.4 -#pragma once
29.5 -
29.6 -#include "access_map.h"
29.7 -#include "accessor.h"
29.8 -#include "page_owner.h"
29.9 -
29.10 -#include <mutex>
29.11 -
29.12 -/* A file mapper, associating flexpages with file regions. */
29.13 -
29.14 -class PageMapper : public PageOwner
29.15 -{
29.16 -protected:
29.17 - AccessMap _map;
29.18 - Accessor *_accessor;
29.19 - Pages *_pages;
29.20 - unsigned int _attached;
29.21 -
29.22 - /* Serialisation of accesses. */
29.23 -
29.24 - std::mutex _lock;
29.25 -
29.26 - /* Internal flexpage retrieval methods. */
29.27 -
29.28 - Flexpage *find(offset_t offset);
29.29 -
29.30 - Flexpage *flexpage(offset_t offset);
29.31 -
29.32 -public:
29.33 - explicit PageMapper(Accessor *accessor, Pages *pages);
29.34 -
29.35 - /* Accounting methods. */
29.36 -
29.37 - void attach();
29.38 -
29.39 - unsigned int detach();
29.40 -
29.41 - Accessor *accessor()
29.42 - { return _accessor; }
29.43 -
29.44 - /* Interface for the pager. */
29.45 -
29.46 - Flexpage *get(offset_t offset, flags_t flags);
29.47 -
29.48 - void queue(Flexpage *flexpage);
29.49 -
29.50 - void flush_all(offset_t start, offset_t size);
29.51 -
29.52 - offset_t get_data_size();
29.53 -
29.54 - void set_data_size(offset_t size);
29.55 -
29.56 - /* Data transfer methods, implementing PageOwner. */
29.57 -
29.58 - void fill(Flexpage *flexpage);
29.59 -
29.60 - void flush(Flexpage *flexpage, bool purge);
29.61 -
29.62 - /* Interface for the page collection, implementing PageOwner. */
29.63 -
29.64 - void remove(Flexpage *flexpage);
29.65 -};
29.66 -
29.67 -// vim: tabstop=4 expandtab shiftwidth=4
31.1 --- a/paging.cc Thu Apr 01 00:39:16 2021 +0200
31.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
31.3 @@ -1,88 +0,0 @@
31.4 -#include "file_pager.h"
31.5 -#include "paging.h"
31.6 -
31.7 -
31.8 -
31.9 -Paging::Paging(Pages *pages)
31.10 -: _pages(pages)
31.11 -{
31.12 -}
31.13 -
31.14 -/* Return any registered page mapper for the given 'fileid' or NULL if no such
31.15 - mapper is registered. */
31.16 -
31.17 -PageMapper *Paging::get(fileid_t fileid)
31.18 -{
31.19 - FileMapping::iterator entry = _mappers.find(fileid);
31.20 - PageMapper *mapper;
31.21 -
31.22 - if (entry == _mappers.end())
31.23 - mapper = NULL;
31.24 - else
31.25 - mapper = entry->second;
31.26 -
31.27 - return mapper;
31.28 -}
31.29 -
31.30 -/* Register a page 'mapper' for the given 'fileid'. */
31.31 -
31.32 -void Paging::set(fileid_t fileid, PageMapper *mapper)
31.33 -{
31.34 - FileMapping::iterator entry = _mappers.find(fileid);
31.35 -
31.36 - if (entry == _mappers.end())
31.37 - _mappers[fileid] = mapper;
31.38 -}
31.39 -
31.40 -/* Obtain a page mapper for the 'fileid' or register a new one in the
31.41 - paging object. */
31.42 -
31.43 -PageMapper *Paging::get_mapper(fileid_t fileid)
31.44 -{
31.45 - /* Obtain any registered page mapper. */
31.46 -
31.47 - PageMapper *mapper = get(fileid);
31.48 -
31.49 - if (mapper != NULL)
31.50 - return mapper;
31.51 -
31.52 - /* Make an accessor and page mapper, registering the mapper. */
31.53 -
31.54 - Accessor *accessor = make_accessor(fileid);
31.55 - mapper = new PageMapper(accessor, _pages);
31.56 -
31.57 - set(fileid, mapper);
31.58 -
31.59 - return mapper;
31.60 -}
31.61 -
31.62 -
31.63 -
31.64 -/* Return a pager initialised with a page mapper. */
31.65 -
31.66 -Pager *Paging::get_pager(fileid_t fileid, flags_t flags)
31.67 -{
31.68 - std::lock_guard<std::mutex> guard(_lock);
31.69 -
31.70 - /* Initialise the pager with the mapper and a reference to this object for
31.71 - closing the mapper and accessor. */
31.72 -
31.73 - PageMapper *mapper = get_mapper(fileid);
31.74 - return new FilePager(fileid, mapper, flags, this);
31.75 -}
31.76 -
31.77 -/* Detach a pager, potentially removing its resources. */
31.78 -
31.79 -void Paging::detach_pager(fileid_t fileid, PageMapper *mapper)
31.80 -{
31.81 - std::lock_guard<std::mutex> guard(_lock);
31.82 -
31.83 - if (!mapper->detach())
31.84 - {
31.85 - _mappers.erase(fileid);
31.86 - delete mapper->accessor();
31.87 - delete mapper;
31.88 - }
31.89 -}
31.90 -
31.91 -// vim: tabstop=4 expandtab shiftwidth=4
32.1 --- a/paging.h Thu Apr 01 00:39:16 2021 +0200
32.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
32.3 @@ -1,59 +0,0 @@
32.4 -#pragma once
32.5 -
32.6 -#include <map>
32.7 -#include <mutex>
32.8 -
32.9 -#include "accessor.h"
32.10 -#include "pager.h"
32.11 -#include "page_mapper.h"
32.12 -
32.13 -
32.14 -
32.15 -/* Mapping type from accessors to page mappers. */
32.16 -
32.17 -typedef std::map<fileid_t, PageMapper *> FileMapping;
32.18 -typedef std::pair<fileid_t, PageMapper *> FileMappingEntry;
32.19 -
32.20 -
32.21 -
32.22 -/* A registry of mappers for accessors. */
32.23 -
32.24 -class Paging
32.25 -{
32.26 -protected:
32.27 - Pages *_pages;
32.28 -
32.29 - FileMapping _mappers;
32.30 - std::mutex _lock;
32.31 -
32.32 - /* Pager initialisation methods. */
32.33 -
32.34 - PageMapper *get_mapper(fileid_t fileid);
32.35 -
32.36 - Pager *get_pager(fileid_t fileid, flags_t flags);
32.37 -
32.38 - /* Configurable methods. */
32.39 -
32.40 - virtual fileid_t get_fileid(const char *path) = 0;
32.41 -
32.42 - virtual Accessor *make_accessor(fileid_t fileid) = 0;
32.43 -
32.44 - /* Mapper registry access. */
32.45 -
32.46 - PageMapper *get(fileid_t fileid);
32.47 -
32.48 - void set(fileid_t fileid, PageMapper *mapper);
32.49 -
32.50 -public:
32.51 - explicit Paging(Pages *pages);
32.52 -
32.53 - virtual ~Paging()
32.54 - {
32.55 - }
32.56 -
32.57 - /* Methods for the pager. */
32.58 -
32.59 - void detach_pager(fileid_t fileid, PageMapper *mapper);
32.60 -};
32.61 -
32.62 -// vim: tabstop=4 expandtab shiftwidth=4
33.1 --- a/send_flexpage.h Thu Apr 01 00:39:16 2021 +0200
33.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
33.3 @@ -1,21 +0,0 @@
33.4 -#pragma once
33.5 -
33.6 -#include "types.h"
33.7 -
33.8 -/* A "send" flexpage abstraction. */
33.9 -
33.10 -class SendFlexpage
33.11 -{
33.12 -public:
33.13 - offset_t base_addr;
33.14 - unsigned int order;
33.15 - flags_t flags;
33.16 -
33.17 - explicit SendFlexpage(offset_t base_addr, unsigned int order,
33.18 - flags_t flags)
33.19 - : base_addr(base_addr), order(order), flags(flags)
33.20 - {
33.21 - }
33.22 -};
33.23 -
33.24 -// vim: tabstop=4 expandtab shiftwidth=4
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/tests/dstest_block_client.cc Thu Apr 01 00:57:43 2021 +0200
34.3 @@ -0,0 +1,128 @@
34.4 +/*
34.5 + * Test dataspace operations.
34.6 + *
34.7 + * Copyright (C) 2020, 2021 Paul Boddie <paul@boddie.org.uk>
34.8 + *
34.9 + * This program is free software; you can redistribute it and/or
34.10 + * modify it under the terms of the GNU General Public License as
34.11 + * published by the Free Software Foundation; either version 2 of
34.12 + * the License, or (at your option) any later version.
34.13 + *
34.14 + * This program is distributed in the hope that it will be useful,
34.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
34.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34.17 + * GNU General Public License for more details.
34.18 + *
34.19 + * You should have received a copy of the GNU General Public License
34.20 + * along with this program; if not, write to the Free Software
34.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
34.22 + * Boston, MA 02110-1301, USA
34.23 + */
34.24 +
34.25 +#include <l4/re/env.h>
34.26 +#include <l4/sys/err.h>
34.27 +
34.28 +#include <stdio.h>
34.29 +#include <string.h>
34.30 +#include <stdlib.h>
34.31 +
34.32 +#include "file.h"
34.33 +#include "memory_utils.h"
34.34 +
34.35 +
34.36 +
34.37 +static void show(file_t *file, unsigned long step, unsigned long sample)
34.38 +{
34.39 + /* Allocate a buffer for sampling from the file. */
34.40 +
34.41 + char buf[sample + 1];
34.42 +
34.43 + for (unsigned long offset = 0; offset < file_populated_span(file); offset += step)
34.44 + {
34.45 + unsigned long remaining = file_populated_span(file) - offset;
34.46 + unsigned long sample_remaining = remaining < sample ? remaining : sample;
34.47 +
34.48 + printf("%ld bytes from %p...\n", sample_remaining, (file->memory + offset));
34.49 + strncpy(buf, (file->memory + offset), sample_remaining);
34.50 + buf[sample_remaining] = '\0';
34.51 + printf("%s\n", buf);
34.52 + }
34.53 +}
34.54 +
34.55 +int main(int argc, char *argv[])
34.56 +{
34.57 + if (argc < 4)
34.58 + {
34.59 + printf("Need filename, step and sample size.\n");
34.60 + return 1;
34.61 + }
34.62 +
34.63 + /* Obtain filename and access parameters. */
34.64 +
34.65 + char *filename = argv[1];
34.66 + unsigned long step = atoi(argv[2]);
34.67 + unsigned long sample = atoi(argv[3]);
34.68 +
34.69 + /* Obtain access to the filesystem. */
34.70 +
34.71 + l4_cap_idx_t server = l4re_env_get_cap("server");
34.72 +
34.73 + /* Invoke the open method to receive the file reference. */
34.74 +
34.75 + file_t file;
34.76 + long err = file_open(&file, filename, server);
34.77 +
34.78 + if (err)
34.79 + {
34.80 + printf("Could not obtain file: %s\n", l4sys_errtostr(err));
34.81 + return 1;
34.82 + }
34.83 +
34.84 + /* A region of the file is mapped. */
34.85 +
34.86 + err = file_mmap(&file, 0, page(10));
34.87 +
34.88 + if (err)
34.89 + {
34.90 + printf("Could not map file region: %s\n", l4sys_errtostr(err));
34.91 + return 1;
34.92 + }
34.93 +
34.94 + show(&file, step, sample);
34.95 +
34.96 + /* Resizing must occur before writing beyond the end of file. Otherwise, the
34.97 + data may get discarded if the supporting flexpage needs to be flushed. */
34.98 +
34.99 + offset_t new_region = round(file_populated_span(&file), page(1));
34.100 +
34.101 + printf("Resize to %ld...\n", new_region + file_populated_span(&file));
34.102 +
34.103 + err = file_resize(&file, new_region + file_populated_span(&file));
34.104 +
34.105 + if (err)
34.106 + {
34.107 + printf("Could not resize file: %s\n", l4sys_errtostr(err));
34.108 + return 1;
34.109 + }
34.110 +
34.111 + printf("Resized file...\n");
34.112 +
34.113 + /* Copy the sampled data to another file region. */
34.114 +
34.115 + printf("Copy data to %ld...\n", new_region);
34.116 +
34.117 + for (unsigned long offset = 0; offset < file_populated_span(&file); offset += step)
34.118 + {
34.119 + memcpy(file.memory + new_region + offset, file.memory + offset, sample);
34.120 + if (step > sample)
34.121 + memset(file.memory + new_region + offset + sample, 0, step - sample);
34.122 + }
34.123 +
34.124 + show(&file, step, sample);
34.125 +
34.126 + printf("File shown.\n");
34.127 +
34.128 + return 0;
34.129 +}
34.130 +
34.131 +// vim: tabstop=2 expandtab shiftwidth=2
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
35.2 +++ b/tests/dstest_block_server.cc Thu Apr 01 00:57:43 2021 +0200
35.3 @@ -0,0 +1,65 @@
35.4 +/*
35.5 + * Test dataspace operations.
35.6 + *
35.7 + * Copyright (C) 2020, 2021 Paul Boddie <paul@boddie.org.uk>
35.8 + *
35.9 + * This program is free software; you can redistribute it and/or
35.10 + * modify it under the terms of the GNU General Public License as
35.11 + * published by the Free Software Foundation; either version 2 of
35.12 + * the License, or (at your option) any later version.
35.13 + *
35.14 + * This program is distributed in the hope that it will be useful,
35.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
35.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35.17 + * GNU General Public License for more details.
35.18 + *
35.19 + * You should have received a copy of the GNU General Public License
35.20 + * along with this program; if not, write to the Free Software
35.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
35.22 + * Boston, MA 02110-1301, USA
35.23 + */
35.24 +
35.25 +#include <l4/re/env.h>
35.26 +#include <l4/sys/err.h>
35.27 +
35.28 +#include <stdio.h>
35.29 +#include <string.h>
35.30 +#include <stdlib.h>
35.31 +
35.32 +#include "memory_incremental.h"
35.33 +#include "memory_utils.h"
35.34 +#include "page_queue_shared.h"
35.35 +#include "pages.h"
35.36 +#include "resource_server.h"
35.37 +#include "block_file_opener.h"
35.38 +
35.39 +
35.40 +
35.41 +const unsigned int MEMORY_PAGES = 10;
35.42 +
35.43 +int main(void)
35.44 +{
35.45 + /* Some memory plus infrastructure. */
35.46 +
35.47 + MemoryIncremental mem(MEMORY_PAGES);
35.48 + PageQueueShared queue;
35.49 + Pages pages(&mem, &queue);
35.50 + BlockFileOpener opener(&pages);
35.51 +
35.52 + /* Register a server associating it with the given object. */
35.53 +
35.54 + ResourceServer server(&opener);
35.55 + long err = server.bind("server");
35.56 +
35.57 + if (err)
35.58 + {
35.59 + printf("Could not bind server: %s\n", l4sys_errtostr(err));
35.60 + return 1;
35.61 + }
35.62 +
35.63 + printf("Starting server...\n");
35.64 + server.start();
35.65 + return 0;
35.66 +}
35.67 +
35.68 +// vim: tabstop=2 expandtab shiftwidth=2
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
36.2 +++ b/tests/dstest_host_client.cc Thu Apr 01 00:57:43 2021 +0200
36.3 @@ -0,0 +1,93 @@
36.4 +/*
36.5 + * Test dataspace operations.
36.6 + *
36.7 + * Copyright (C) 2020, 2021 Paul Boddie <paul@boddie.org.uk>
36.8 + *
36.9 + * This program is free software; you can redistribute it and/or
36.10 + * modify it under the terms of the GNU General Public License as
36.11 + * published by the Free Software Foundation; either version 2 of
36.12 + * the License, or (at your option) any later version.
36.13 + *
36.14 + * This program is distributed in the hope that it will be useful,
36.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
36.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36.17 + * GNU General Public License for more details.
36.18 + *
36.19 + * You should have received a copy of the GNU General Public License
36.20 + * along with this program; if not, write to the Free Software
36.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
36.22 + * Boston, MA 02110-1301, USA
36.23 + */
36.24 +
36.25 +#include <l4/re/env.h>
36.26 +#include <l4/sys/err.h>
36.27 +
36.28 +#include <stdio.h>
36.29 +#include <string.h>
36.30 +#include <stdlib.h>
36.31 +
36.32 +#include "file.h"
36.33 +#include "memory_utils.h"
36.34 +
36.35 +
36.36 +
36.37 +int main(int argc, char *argv[])
36.38 +{
36.39 + if (argc < 4)
36.40 + {
36.41 + printf("Need filename, step and sample size.\n");
36.42 + return 1;
36.43 + }
36.44 +
36.45 + /* Obtain filename and access parameters. */
36.46 +
36.47 + char *filename = argv[1];
36.48 + unsigned long step = atoi(argv[2]);
36.49 + unsigned long sample = atoi(argv[3]);
36.50 +
36.51 + /* Allocate a buffer for sampling from the file. */
36.52 +
36.53 + char buf[sample + 1];
36.54 +
36.55 + /* Obtain access to the filesystem. */
36.56 +
36.57 + l4_cap_idx_t server = l4re_env_get_cap("server");
36.58 +
36.59 + /* Invoke the open method to receive the file reference. */
36.60 +
36.61 + file_t file;
36.62 + long err = file_open(&file, filename, server);
36.63 +
36.64 + if (err)
36.65 + {
36.66 + printf("Could not obtain file: %s\n", l4sys_errtostr(err));
36.67 + return 1;
36.68 + }
36.69 +
36.70 + /* A region of the file is mapped. */
36.71 +
36.72 + err = file_mmap(&file, 0, page(10));
36.73 +
36.74 + if (err)
36.75 + {
36.76 + printf("Could not map file region: %s\n", l4sys_errtostr(err));
36.77 + return 1;
36.78 + }
36.79 +
36.80 + for (unsigned long offset = 0; offset < file_populated_span(&file); offset += step)
36.81 + {
36.82 + unsigned long remaining = file_populated_span(&file) - offset;
36.83 + unsigned long sample_remaining = remaining < sample ? remaining : sample;
36.84 +
36.85 + printf("%ld bytes from %p...\n", sample_remaining, (file.memory + offset));
36.86 + strncpy(buf, (file.memory + offset), sample_remaining);
36.87 + buf[sample_remaining] = '\0';
36.88 + printf("%s\n", buf);
36.89 + }
36.90 +
36.91 + printf("File shown.\n");
36.92 +
36.93 + return 0;
36.94 +}
36.95 +
36.96 +// vim: tabstop=2 expandtab shiftwidth=2
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
37.2 +++ b/tests/dstest_host_server.cc Thu Apr 01 00:57:43 2021 +0200
37.3 @@ -0,0 +1,63 @@
37.4 +/*
37.5 + * Test dataspace operations.
37.6 + *
37.7 + * Copyright (C) 2020, 2021 Paul Boddie <paul@boddie.org.uk>
37.8 + *
37.9 + * This program is free software; you can redistribute it and/or
37.10 + * modify it under the terms of the GNU General Public License as
37.11 + * published by the Free Software Foundation; either version 2 of
37.12 + * the License, or (at your option) any later version.
37.13 + *
37.14 + * This program is distributed in the hope that it will be useful,
37.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
37.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37.17 + * GNU General Public License for more details.
37.18 + *
37.19 + * You should have received a copy of the GNU General Public License
37.20 + * along with this program; if not, write to the Free Software
37.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
37.22 + * Boston, MA 02110-1301, USA
37.23 + */
37.24 +
37.25 +#include <l4/re/env.h>
37.26 +#include <l4/sys/err.h>
37.27 +
37.28 +#include <stdio.h>
37.29 +#include <string.h>
37.30 +#include <stdlib.h>
37.31 +
37.32 +#include "memory_incremental.h"
37.33 +#include "memory_utils.h"
37.34 +#include "page_queue_shared.h"
37.35 +#include "pages.h"
37.36 +#include "resource_server.h"
37.37 +#include "host_file_opener.h"
37.38 +
37.39 +
37.40 +
37.41 +const unsigned int MEMORY_PAGES = 10;
37.42 +
37.43 +int main(void)
37.44 +{
37.45 + /* Some memory plus infrastructure. */
37.46 +
37.47 + MemoryIncremental mem(MEMORY_PAGES);
37.48 + PageQueueShared queue;
37.49 + Pages pages(&mem, &queue);
37.50 + HostFileOpener opener(&pages);
37.51 +
37.52 + /* Register a server associating it with the given object. */
37.53 +
37.54 + ResourceServer server(&opener);
37.55 + long err = server.bind("server");
37.56 +
37.57 + if (err)
37.58 + {
37.59 + printf("Could not bind server: %s\n", l4sys_errtostr(err));
37.60 + return 1;
37.61 + }
37.62 +
37.63 + printf("Starting server...\n");
37.64 + server.start();
37.65 + return 0;
37.66 +}
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
38.2 +++ b/tests/dstest_pipe_client.cc Thu Apr 01 00:57:43 2021 +0200
38.3 @@ -0,0 +1,121 @@
38.4 +/*
38.5 + * Test pipe operations.
38.6 + *
38.7 + * Copyright (C) 2020, 2021 Paul Boddie <paul@boddie.org.uk>
38.8 + *
38.9 + * This program is free software; you can redistribute it and/or
38.10 + * modify it under the terms of the GNU General Public License as
38.11 + * published by the Free Software Foundation; either version 2 of
38.12 + * the License, or (at your option) any later version.
38.13 + *
38.14 + * This program is distributed in the hope that it will be useful,
38.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
38.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38.17 + * GNU General Public License for more details.
38.18 + *
38.19 + * You should have received a copy of the GNU General Public License
38.20 + * along with this program; if not, write to the Free Software
38.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
38.22 + * Boston, MA 02110-1301, USA
38.23 + */
38.24 +
38.25 +#include <l4/re/env.h>
38.26 +#include <l4/sys/err.h>
38.27 +
38.28 +#include <stdio.h>
38.29 +#include <string.h>
38.30 +#include <stdlib.h>
38.31 +
38.32 +#include "file.h"
38.33 +#include "memory_utils.h"
38.34 +
38.35 +
38.36 +
38.37 +static void show(file_t *file, offset_t step, offset_t sample)
38.38 +{
38.39 + /* Allocate a buffer for sampling from the file. */
38.40 +
38.41 + char buf[sample + 1];
38.42 +
38.43 + for (offset_t offset = 0; offset < file_populated_span(file); offset += step)
38.44 + {
38.45 + printf("show %ld of %ld...\n", offset, file_populated_span(file));
38.46 +
38.47 + unsigned long remaining = file_populated_span(file) - offset;
38.48 + unsigned long sample_remaining = remaining < sample ? remaining : sample;
38.49 +
38.50 + printf("%ld bytes from %p...\n", sample_remaining, (file->memory + offset));
38.51 + strncpy(buf, (file->memory + offset), sample_remaining);
38.52 + buf[sample_remaining] = '\0';
38.53 + printf("%s\n", buf);
38.54 + }
38.55 +}
38.56 +
38.57 +
38.58 +
38.59 +const unsigned int PIPE_PAGES = 2;
38.60 +
38.61 +int main(void)
38.62 +{
38.63 + /* Obtain access to the filesystem. */
38.64 +
38.65 + l4_cap_idx_t server = l4re_env_get_cap("server");
38.66 +
38.67 + /* Invoke the open method to receive the file reference. */
38.68 +
38.69 + file_t reader, writer;
38.70 + long err = pipe_open(page(PIPE_PAGES), &reader, &writer, server);
38.71 +
38.72 + if (err)
38.73 + {
38.74 + printf("Could not obtain pipe: %s\n", l4sys_errtostr(err));
38.75 + return 1;
38.76 + }
38.77 +
38.78 + /* Use the writer to fill the pipe with data. */
38.79 +
38.80 + for (int region = 0; region < 3; region++)
38.81 + {
38.82 + printf("Write %ld to pipe at %p...\n", file_span(&writer), writer.memory);
38.83 +
38.84 + memset(writer.memory, (int) 'a' + region, file_span(&writer));
38.85 +
38.86 + err = pipe_written(&writer, file_span(&writer));
38.87 +
38.88 + if (err)
38.89 + {
38.90 + printf("Written data error: %s\n", l4sys_errtostr(err));
38.91 + return 1;
38.92 + }
38.93 +
38.94 + show(&writer, page(1), 60);
38.95 +
38.96 + err = pipe_next(&writer);
38.97 +
38.98 + if (err)
38.99 + {
38.100 + printf("Region traversal error at region %d: %s\n", region, l4sys_errtostr(err));
38.101 + break;
38.102 + }
38.103 + }
38.104 +
38.105 + /* Use the reader to obtain data from the pipe. */
38.106 +
38.107 + err = pipe_current(&reader);
38.108 +
38.109 + while (!err)
38.110 + {
38.111 + printf("show...\n");
38.112 + show(&reader, page(1), 60);
38.113 + err = pipe_next(&reader);
38.114 + }
38.115 +
38.116 + if (err)
38.117 + printf("Reading termination condition: %s\n", l4sys_errtostr(err));
38.118 +
38.119 + printf("Data shown.\n");
38.120 +
38.121 + return 0;
38.122 +}
38.123 +
38.124 +// vim: tabstop=2 expandtab shiftwidth=2
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
39.2 +++ b/tests/dstest_pipe_server.cc Thu Apr 01 00:57:43 2021 +0200
39.3 @@ -0,0 +1,57 @@
39.4 +/*
39.5 + * Test pipe operations.
39.6 + *
39.7 + * Copyright (C) 2020, 2021 Paul Boddie <paul@boddie.org.uk>
39.8 + *
39.9 + * This program is free software; you can redistribute it and/or
39.10 + * modify it under the terms of the GNU General Public License as
39.11 + * published by the Free Software Foundation; either version 2 of
39.12 + * the License, or (at your option) any later version.
39.13 + *
39.14 + * This program is distributed in the hope that it will be useful,
39.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
39.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39.17 + * GNU General Public License for more details.
39.18 + *
39.19 + * You should have received a copy of the GNU General Public License
39.20 + * along with this program; if not, write to the Free Software
39.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
39.22 + * Boston, MA 02110-1301, USA
39.23 + */
39.24 +
39.25 +#include <l4/sys/err.h>
39.26 +
39.27 +#include <stdio.h>
39.28 +
39.29 +#include "memory_incremental.h"
39.30 +#include "pipe_opener_resource.h"
39.31 +#include "resource_server.h"
39.32 +
39.33 +
39.34 +
39.35 +const unsigned int MEMORY_PAGES = 20;
39.36 +
39.37 +int main(void)
39.38 +{
39.39 + /* Some memory plus infrastructure. */
39.40 +
39.41 + MemoryIncremental mem(MEMORY_PAGES);
39.42 + PipeOpenerResource opener(&mem);
39.43 +
39.44 + /* Register a server associating it with the given object. */
39.45 +
39.46 + ResourceServer server(&opener);
39.47 + long err = server.bind("server");
39.48 +
39.49 + if (err)
39.50 + {
39.51 + printf("Could not bind server: %s\n", l4sys_errtostr(err));
39.52 + return 1;
39.53 + }
39.54 +
39.55 + printf("Starting server...\n");
39.56 + server.start();
39.57 + return 0;
39.58 +}
39.59 +
39.60 +// vim: tabstop=2 expandtab shiftwidth=2
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
40.2 +++ b/tests/dstest_test_client.cc Thu Apr 01 00:57:43 2021 +0200
40.3 @@ -0,0 +1,242 @@
40.4 +/*
40.5 + * Test dataspace operations.
40.6 + *
40.7 + * Copyright (C) 2020, 2021 Paul Boddie <paul@boddie.org.uk>
40.8 + *
40.9 + * This program is free software; you can redistribute it and/or
40.10 + * modify it under the terms of the GNU General Public License as
40.11 + * published by the Free Software Foundation; either version 2 of
40.12 + * the License, or (at your option) any later version.
40.13 + *
40.14 + * This program is distributed in the hope that it will be useful,
40.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
40.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40.17 + * GNU General Public License for more details.
40.18 + *
40.19 + * You should have received a copy of the GNU General Public License
40.20 + * along with this program; if not, write to the Free Software
40.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
40.22 + * Boston, MA 02110-1301, USA
40.23 + */
40.24 +
40.25 +#include <l4/re/env.h>
40.26 +#include <l4/sys/err.h>
40.27 +
40.28 +#include <stdio.h>
40.29 +#include <string.h>
40.30 +#include <stdlib.h>
40.31 +#include <time.h>
40.32 +
40.33 +#include <system_error>
40.34 +#include <thread>
40.35 +
40.36 +#include <ipc/thread.h>
40.37 +
40.38 +#include "file.h"
40.39 +#include "memory_utils.h"
40.40 +
40.41 +
40.42 +
40.43 +/* Test parameters affected by capability limits. */
40.44 +
40.45 +const unsigned long NUMBER_OF_FILES = 10;
40.46 +const unsigned int START_LIMIT = 10;
40.47 +const unsigned int ACTIVITY_ITERATIONS = 20;
40.48 +
40.49 +/* Test parameters unaffected by any capability limits. */
40.50 +
40.51 +const unsigned int MAP_PAGES = 20;
40.52 +const unsigned int REGION_ITERATIONS = 20;
40.53 +
40.54 +
40.55 +
40.56 +/* An activity opening and reading from a file. */
40.57 +
40.58 +static long activity(file_t *context, unsigned long fileid, unsigned int start_page)
40.59 +{
40.60 + unsigned long step = page(1);
40.61 + unsigned long sample = page(1);
40.62 +
40.63 + /* Allocate a buffer for sampling from the file. */
40.64 +
40.65 + char buf[sample + 1];
40.66 +
40.67 + /* Invoke the open method to receive the file reference. */
40.68 +
40.69 + file_t file;
40.70 +
40.71 + long err = file_context_open(&file, context);
40.72 +
40.73 + if (err)
40.74 + {
40.75 + printf("Could not obtain file for %ld @ page %d: %s\n", fileid, start_page, l4sys_errtostr(err));
40.76 + return err;
40.77 + }
40.78 +
40.79 + /* A region of the file is mapped. */
40.80 +
40.81 + err = file_mmap(&file, page(start_page), page(MAP_PAGES));
40.82 +
40.83 + if (err)
40.84 + {
40.85 + printf("Could not map file region for %ld @ page %d: %s\n", fileid, start_page, l4sys_errtostr(err));
40.86 + file_close(&file);
40.87 + return err;
40.88 + }
40.89 +
40.90 + /* Read the region a number of times. */
40.91 +
40.92 + for (unsigned int read_counter = 0; read_counter < REGION_ITERATIONS; read_counter++)
40.93 + {
40.94 + for (unsigned long offset = 0; offset < file_populated_span(&file); offset += step)
40.95 + {
40.96 + unsigned long remaining = file_populated_span(&file) - offset;
40.97 + unsigned long sample_remaining = remaining < sample ? remaining : sample;
40.98 +
40.99 + strncpy(buf, (file.memory + offset), sample_remaining);
40.100 + buf[sample_remaining] = '\0';
40.101 +
40.102 + /* Test the data obtained. */
40.103 +
40.104 + unsigned long filepos = file.start_pos + offset;
40.105 + unsigned long _fileid = 0, _filepos = 0;
40.106 + char *sep = strchr(buf, ':');
40.107 +
40.108 + if (sep != NULL)
40.109 + {
40.110 + *sep = '\0'; sep++;
40.111 + _fileid = atol(buf); _filepos = atol(sep);
40.112 + }
40.113 +
40.114 + if ((fileid != _fileid) || (filepos != _filepos))
40.115 + printf("! %ld:%ld is not %ld:%ld\n", _fileid, _filepos, fileid, filepos);
40.116 + }
40.117 + }
40.118 +
40.119 + file_close(&file);
40.120 +
40.121 + return L4_EOK;
40.122 +}
40.123 +
40.124 +
40.125 +
40.126 +static long activity_iterate(file_t *context, unsigned long fileid, unsigned int start_page)
40.127 +{
40.128 + long err;
40.129 +
40.130 + /* Open the file, read pages, close the file, over and over. */
40.131 +
40.132 + for (unsigned int iteration = 0; iteration < ACTIVITY_ITERATIONS; iteration++)
40.133 + {
40.134 + err = activity(context, fileid, start_page);
40.135 + if (err)
40.136 + break;
40.137 + }
40.138 +
40.139 + return err;
40.140 +}
40.141 +
40.142 +
40.143 +
40.144 +static long context_for_file(unsigned long fileid, file_t *file, l4_cap_idx_t server)
40.145 +{
40.146 + long err = file_context(file, server);
40.147 +
40.148 + if (err)
40.149 + {
40.150 + printf("Could not obtain context: %s\n", l4sys_errtostr(err));
40.151 + file_close(file);
40.152 + return err;
40.153 + }
40.154 +
40.155 + /* Write the filename. */
40.156 +
40.157 + sprintf(file->memory, "%ld", fileid);
40.158 +
40.159 + return L4_EOK;
40.160 +}
40.161 +
40.162 +
40.163 +
40.164 +int main(void)
40.165 +{
40.166 + long err;
40.167 +
40.168 + /* Introduce concurrency control. */
40.169 +
40.170 + err = ipc_thread_init();
40.171 +
40.172 + if (err)
40.173 + {
40.174 + printf("Initialisation error: %s\n", l4sys_errtostr(err));
40.175 + return 1;
40.176 + }
40.177 +
40.178 + /* Retain activity and context details. */
40.179 +
40.180 + std::thread *activities[NUMBER_OF_FILES * START_LIMIT];
40.181 + file_t contexts[NUMBER_OF_FILES];
40.182 +
40.183 + /* Obtain access to the filesystem. */
40.184 +
40.185 + l4_cap_idx_t server = l4re_env_get_cap("server");
40.186 +
40.187 + /* Obtain opener contexts for the files. */
40.188 +
40.189 + unsigned long fileid;
40.190 +
40.191 + for (fileid = 0; fileid < NUMBER_OF_FILES; fileid++)
40.192 + {
40.193 + err = context_for_file(fileid, &contexts[fileid], server);
40.194 +
40.195 + if (err)
40.196 + {
40.197 + printf("Context allocation failed.\n");
40.198 + return 1;
40.199 + }
40.200 + }
40.201 +
40.202 + /* Start threads accessing all the files. */
40.203 +
40.204 + printf("Starting threads...\n");
40.205 +
40.206 + time_t t = time(NULL);
40.207 + int current = 0;
40.208 + unsigned long errors = 0;
40.209 +
40.210 + for (fileid = 0; fileid < NUMBER_OF_FILES; fileid++)
40.211 + {
40.212 + for (unsigned int start_page = 0; start_page < START_LIMIT; start_page++)
40.213 + {
40.214 + try
40.215 + {
40.216 + activities[current++] = new std::thread(activity_iterate, &contexts[fileid], fileid, start_page);
40.217 + }
40.218 + catch (const std::system_error &exc)
40.219 + {
40.220 + errors++;
40.221 + }
40.222 + }
40.223 + }
40.224 +
40.225 + /* Wait for the threads. */
40.226 +
40.227 + int limit = current;
40.228 +
40.229 + printf("Waiting for %d threads...\n", limit);
40.230 +
40.231 + for (current = 0; current < limit; current++)
40.232 + activities[current]->join();
40.233 +
40.234 + /* Discard the contexts. */
40.235 +
40.236 + for (fileid = 0; fileid < NUMBER_OF_FILES; fileid++)
40.237 + file_close(&contexts[fileid]);
40.238 +
40.239 + t = time(NULL) - t;
40.240 + printf("Activities completed in %ld seconds (with %ld threads not started).\n", t, errors);
40.241 +
40.242 + return 0;
40.243 +}
40.244 +
40.245 +// vim: tabstop=2 expandtab shiftwidth=2
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
41.2 +++ b/tests/dstest_test_server.cc Thu Apr 01 00:57:43 2021 +0200
41.3 @@ -0,0 +1,88 @@
41.4 +/*
41.5 + * Test dataspace operations.
41.6 + *
41.7 + * Copyright (C) 2020, 2021 Paul Boddie <paul@boddie.org.uk>
41.8 + *
41.9 + * This program is free software; you can redistribute it and/or
41.10 + * modify it under the terms of the GNU General Public License as
41.11 + * published by the Free Software Foundation; either version 2 of
41.12 + * the License, or (at your option) any later version.
41.13 + *
41.14 + * This program is distributed in the hope that it will be useful,
41.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
41.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41.17 + * GNU General Public License for more details.
41.18 + *
41.19 + * You should have received a copy of the GNU General Public License
41.20 + * along with this program; if not, write to the Free Software
41.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
41.22 + * Boston, MA 02110-1301, USA
41.23 + */
41.24 +
41.25 +#include <l4/re/env.h>
41.26 +#include <l4/sys/err.h>
41.27 +
41.28 +#include <ipc/thread.h>
41.29 +
41.30 +#include <stdio.h>
41.31 +#include <string.h>
41.32 +#include <stdlib.h>
41.33 +
41.34 +#include "memory_incremental.h"
41.35 +#include "memory_utils.h"
41.36 +#include "page_queue_shared.h"
41.37 +#include "pages.h"
41.38 +#include "resource_server.h"
41.39 +#include "test_file_opener.h"
41.40 +
41.41 +
41.42 +
41.43 +const unsigned int REGION_PAGES = 8;
41.44 +const unsigned int MEMORY_PAGES = REGION_PAGES * 10;
41.45 +const unsigned int FILE_PAGES = 20;
41.46 +
41.47 +int main(int argc, char *argv[])
41.48 +{
41.49 + long err;
41.50 +
41.51 + /* Introduce concurrency control. */
41.52 +
41.53 + err = ipc_thread_init();
41.54 +
41.55 + if (err)
41.56 + {
41.57 + printf("Initialisation error: %s\n", l4sys_errtostr(err));
41.58 + return 1;
41.59 + }
41.60 +
41.61 + /* Configure the number of available pages using any argument. */
41.62 +
41.63 + unsigned int memory_pages = MEMORY_PAGES;
41.64 +
41.65 + if (argc > 1)
41.66 + memory_pages = atoi(argv[1]) * REGION_PAGES;
41.67 +
41.68 + /* Some memory plus infrastructure. */
41.69 +
41.70 + MemoryIncremental mem(memory_pages, page(REGION_PAGES));
41.71 + PageQueueShared queue;
41.72 + Pages pages(&mem, &queue);
41.73 + TestFileOpener opener(&pages, page(FILE_PAGES));
41.74 +
41.75 + /* Register a server associating it with the given object. */
41.76 +
41.77 + ResourceServer server(&opener);
41.78 + err = server.bind("server");
41.79 +
41.80 + if (err)
41.81 + {
41.82 + printf("Could not bind server: %s\n", l4sys_errtostr(err));
41.83 + return 1;
41.84 + }
41.85 +
41.86 + printf("Starting server...\n");
41.87 + server.start();
41.88 + return 0;
41.89 +}
41.90 +
41.91 +// vim: tabstop=2 expandtab shiftwidth=2