# HG changeset patch # User Paul Boddie # Date 1613085663 -3600 # Node ID 71ea18032df4f97269f693780b13bd7892388b19 # Parent 2e0c4ea098ad40746b44a3a46bf90bd698d45e19 Introduced separate test programs for host and test file access. diff -r 2e0c4ea098ad -r 71ea18032df4 Makefile --- a/Makefile Fri Feb 12 00:20:27 2021 +0100 +++ b/Makefile Fri Feb 12 00:21:03 2021 +0100 @@ -1,8 +1,11 @@ PKGDIR ?= . L4DIR ?= $(PKGDIR)/../.. -TARGET = dstest_client dstest_server -MODE = shared +TARGET = \ + dstest_host_client dstest_test_client \ + dstest_host_server dstest_test_server + +MODE = static # Locations for interface input and generated output. @@ -37,28 +40,48 @@ COMMON_SRC_CC = memory_utils.cc -PLAIN_SRC_CC_dstest_client = dstest_client.cc +PLAIN_SRC_CC_dstest_host_client = dstest_host_client.cc + +PLAIN_SRC_CC_dstest_test_client = dstest_test_client.cc -PLAIN_SRC_CC_dstest_server = \ +PLAIN_SRC_CC_dstest_host_server = \ access_map.cc accessing.cc accessor.cc \ - dstest_server.cc flexpage.cc file_pager.cc \ + dstest_host_server.cc flexpage.cc file_pager.cc \ + ipc.cc memory.cc \ + opener_resource.cc opener_context_resource.cc \ + page_mapper.cc page_queue.cc pager.cc pages.cc paging.cc \ + region.cc resource_server.cc simple_pager.cc \ + host_file_accessor.cc host_file_opener.cc + +PLAIN_SRC_CC_dstest_test_server = \ + access_map.cc accessing.cc accessor.cc \ + dstest_test_server.cc flexpage.cc file_pager.cc \ ipc.cc memory.cc \ opener_resource.cc opener_context_resource.cc \ page_mapper.cc page_queue.cc pager.cc pages.cc paging.cc \ region.cc resource_server.cc simple_pager.cc \ - host_file_accessor.cc host_file_opener.cc \ - test_file_accessor.cc test_file_opener.cc \ + test_file_accessor.cc test_file_opener.cc # Normal definitions. -SRC_CC_dstest_client = \ +SRC_CC_dstest_host_client = \ $(CLIENT_INTERFACES_SRC_CC) \ - $(PLAIN_SRC_CC_dstest_client) \ + $(PLAIN_SRC_CC_dstest_host_client) \ $(COMMON_SRC_CC) -SRC_CC_dstest_server = \ +SRC_CC_dstest_test_client = \ + $(CLIENT_INTERFACES_SRC_CC) \ + $(PLAIN_SRC_CC_dstest_test_client) \ + $(COMMON_SRC_CC) + +SRC_CC_dstest_host_server = \ $(SERVER_INTERFACES_SRC_CC) \ - $(PLAIN_SRC_CC_dstest_server) \ + $(PLAIN_SRC_CC_dstest_host_server) \ + $(COMMON_SRC_CC) + +SRC_CC_dstest_test_server = \ + $(SERVER_INTERFACES_SRC_CC) \ + $(PLAIN_SRC_CC_dstest_test_server) \ $(COMMON_SRC_CC) REQUIRES_LIBS = l4re_c-util libipc libstdc++ @@ -68,6 +91,10 @@ include $(L4DIR)/mk/prog.mk include $(IDL_MK_DIR)/interface_rules.mk -$(PLAIN_SRC_CC_dstest_client): $(CLIENT_INTERFACES_SRC_CC) +$(PLAIN_SRC_CC_dstest_host_client): $(CLIENT_INTERFACES_SRC_CC) + +$(PLAIN_SRC_CC_dstest_test_client): $(CLIENT_INTERFACES_SRC_CC) -$(PLAIN_SRC_CC_dstest_server): $(SERVER_INTERFACES_SRC_CC) +$(PLAIN_SRC_CC_dstest_host_server): $(SERVER_INTERFACES_SRC_CC) + +$(PLAIN_SRC_CC_dstest_test_server): $(SERVER_INTERFACES_SRC_CC) diff -r 2e0c4ea098ad -r 71ea18032df4 conf/dstest.cfg --- a/conf/dstest.cfg Fri Feb 12 00:20:27 2021 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ --- vim:set ft=lua: - -local L4 = require("L4"); - -local l = L4.default_loader; - -local server = l:new_channel(); - -l:start({ - caps = { - server = server:svr(), - }, - log = { "server", "r" }, - }, - "rom/dstest_server"); - -l:start({ - caps = { - server = server, - }, - log = { "client", "g" }, - }, - "rom/dstest_client"); diff -r 2e0c4ea098ad -r 71ea18032df4 conf/dstest.list --- a/conf/dstest.list Fri Feb 12 00:20:27 2021 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -entry dstest -roottask moe rom/dstest.cfg -module dstest.cfg -module l4re -module ned -module dstest_client -module dstest_server -module lib4re-c.so -module lib4re-c-util.so -module lib4re.so -module lib4re-util.so -module libc_be_l4refile.so -module libc_be_l4re.so -module libc_be_socket_noop.so -module libc_support_misc.so -module libdl.so -module libipc.so -module libl4sys-direct.so -module libl4sys.so -module libl4util.so -module libld-l4.so -module libpthread.so -module libstdc++.so -module libsupc++.so -module libuc_c.so diff -r 2e0c4ea098ad -r 71ea18032df4 conf/dstest_host.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/conf/dstest_host.cfg Fri Feb 12 00:21:03 2021 +0100 @@ -0,0 +1,23 @@ +-- vim:set ft=lua: + +local L4 = require("L4"); + +local l = L4.default_loader; + +local server = l:new_channel(); + +l:start({ + caps = { + server = server:svr(), + }, + log = { "server", "r" }, + }, + "rom/dstest_host_server"); + +l:startv({ + caps = { + server = server, + }, + log = { "client", "g" }, + }, + "rom/dstest_host_client", "rom/dstest_host.cfg", 1024, 1024); diff -r 2e0c4ea098ad -r 71ea18032df4 conf/dstest_host.list --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/conf/dstest_host.list Fri Feb 12 00:21:03 2021 +0100 @@ -0,0 +1,25 @@ +entry dstest_host +roottask moe rom/dstest_host.cfg +module dstest_host.cfg +module l4re +module ned +module dstest_host_client +module dstest_host_server +module lib4re-c.so +module lib4re-c-util.so +module lib4re.so +module lib4re-util.so +module libc_be_l4refile.so +module libc_be_l4re.so +module libc_be_socket_noop.so +module libc_support_misc.so +module libdl.so +module libipc.so +module libl4sys-direct.so +module libl4sys.so +module libl4util.so +module libld-l4.so +module libpthread.so +module libstdc++.so +module libsupc++.so +module libuc_c.so diff -r 2e0c4ea098ad -r 71ea18032df4 conf/dstest_test.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/conf/dstest_test.cfg Fri Feb 12 00:21:03 2021 +0100 @@ -0,0 +1,23 @@ +-- vim:set ft=lua: + +local L4 = require("L4"); + +local l = L4.default_loader; + +local server = l:new_channel(); + +l:start({ + caps = { + server = server:svr(), + }, + log = { "server", "r" }, + }, + "rom/dstest_test_server"); + +l:start({ + caps = { + server = server, + }, + log = { "client", "g" }, + }, + "rom/dstest_test_client"); diff -r 2e0c4ea098ad -r 71ea18032df4 conf/dstest_test.list --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/conf/dstest_test.list Fri Feb 12 00:21:03 2021 +0100 @@ -0,0 +1,25 @@ +entry dstest_test +roottask moe rom/dstest_test.cfg +module dstest_test.cfg +module l4re +module ned +module dstest_test_client +module dstest_test_server +module lib4re-c.so +module lib4re-c-util.so +module lib4re.so +module lib4re-util.so +module libc_be_l4refile.so +module libc_be_l4re.so +module libc_be_socket_noop.so +module libc_support_misc.so +module libdl.so +module libipc.so +module libl4sys-direct.so +module libl4sys.so +module libl4util.so +module libld-l4.so +module libpthread.so +module libstdc++.so +module libsupc++.so +module libuc_c.so diff -r 2e0c4ea098ad -r 71ea18032df4 dstest_client.cc --- a/dstest_client.cc Fri Feb 12 00:20:27 2021 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,163 +0,0 @@ -/* - * Test dataspace operations. - * - * Copyright (C) 2020, 2021 Paul Boddie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA - */ - -#include -#include - -#include -#include -#include - -#include - -#include "dataspace_client.h" -#include "opener_client.h" -#include "opener_context_client.h" -#include "mapped_file_client.h" -#include "memory_utils.h" - - - -int main(int argc, char *argv[]) -{ - if (argc < 4) - { - printf("Need filename, step and sample size.\n"); - return 1; - } - - /* Obtain filename and access parameters. */ - - char *filename = argv[1]; - unsigned long step = atoi(argv[2]); - unsigned long sample = atoi(argv[3]); - - /* Allocate a buffer for sampling from the file. */ - - char buf[sample + 1]; - - /* Obtain access to the filesystem. */ - - l4_cap_idx_t server = l4re_env_get_cap("server"); - l4_cap_idx_t context_ref; - client_Opener opener(server); - - long err = opener.context(&context_ref); - - if (err) - { - printf("Could not obtain context: %s\n", l4sys_errtostr(err)); - return 1; - } - - client_OpenerContext context(context_ref); - client_Dataspace context_ds(context_ref); - unsigned long size, flags; - - err = context_ds.info(&size, &flags); - - if (err) - { - printf("Could not obtain context info: %s\n", l4sys_errtostr(err)); - return 1; - } - - /* Map context memory to write the filename. */ - - char *memory; - - printf("Attach region of size %ld...\n", size); - - err = ipc_attach_dataspace(context_ref, size, (void **) &memory); - - if (err) - { - printf("Could not map memory: %s\n", l4sys_errtostr(err)); - return 1; - } - - printf("Mapped memory at %p\n", memory); - - /* Write the filename. */ - - strcpy(memory, filename); - - /* Invoke the open method to receive the file reference. */ - - l4_cap_idx_t file; - - err = context.open(L4_FPAGE_RW, &size, &file); - - if (err) - { - printf("Could not obtain file: %s\n", l4sys_errtostr(err)); - return 1; - } - - client_MappedFile obj(file); - - /* Some memory to be mapped. */ - - size_t start_pos, end_pos, data_end; - - printf("Map region from %ld to %ld...\n", 0L, page(10)); - - err = obj.mmap(0, page(10), &start_pos, &end_pos, &data_end); - - if (err) - { - printf("Could not map file region: %s\n", l4sys_errtostr(err)); - return 1; - } - - printf("Mapped region from %ld to %ld with content %ld.\n", - start_pos, end_pos, data_end); - - size = end_pos - start_pos; - - printf("Attach region of size %ld...\n", size); - - err = ipc_attach_dataspace(file, size, (void **) &memory); - - if (err) - { - printf("Could not map memory: %s\n", l4sys_errtostr(err)); - return 1; - } - - printf("Mapped memory at %p\n", memory); - - if (data_end < size) - size = data_end; - - for (unsigned long offset = 0; offset < size; offset += step) - { - unsigned long remaining = size - offset; - unsigned long sample_remaining = remaining < sample ? remaining : sample; - - printf("%ld bytes from %p...\n", sample_remaining, (memory + offset)); - strncpy(buf, (memory + offset), sample_remaining); - buf[sample_remaining] = '\0'; - printf("%s\n", buf); - } - - return 0; -} diff -r 2e0c4ea098ad -r 71ea18032df4 dstest_host_client.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dstest_host_client.cc Fri Feb 12 00:21:03 2021 +0100 @@ -0,0 +1,163 @@ +/* + * Test dataspace operations. + * + * Copyright (C) 2020, 2021 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#include +#include + +#include +#include +#include + +#include + +#include "dataspace_client.h" +#include "opener_client.h" +#include "opener_context_client.h" +#include "mapped_file_client.h" +#include "memory_utils.h" + + + +int main(int argc, char *argv[]) +{ + if (argc < 4) + { + printf("Need filename, step and sample size.\n"); + return 1; + } + + /* Obtain filename and access parameters. */ + + char *filename = argv[1]; + unsigned long step = atoi(argv[2]); + unsigned long sample = atoi(argv[3]); + + /* Allocate a buffer for sampling from the file. */ + + char buf[sample + 1]; + + /* Obtain access to the filesystem. */ + + l4_cap_idx_t server = l4re_env_get_cap("server"); + l4_cap_idx_t context_ref; + client_Opener opener(server); + + long err = opener.context(&context_ref); + + if (err) + { + printf("Could not obtain context: %s\n", l4sys_errtostr(err)); + return 1; + } + + client_OpenerContext context(context_ref); + client_Dataspace context_ds(context_ref); + unsigned long size, flags; + + err = context_ds.info(&size, &flags); + + if (err) + { + printf("Could not obtain context info: %s\n", l4sys_errtostr(err)); + return 1; + } + + /* Map context memory to write the filename. */ + + char *memory; + + printf("Attach region of size %ld...\n", size); + + err = ipc_attach_dataspace(context_ref, size, (void **) &memory); + + if (err) + { + printf("Could not map memory: %s\n", l4sys_errtostr(err)); + return 1; + } + + printf("Mapped memory at %p\n", memory); + + /* Write the filename. */ + + strcpy(memory, filename); + + /* Invoke the open method to receive the file reference. */ + + l4_cap_idx_t file; + + err = context.open(L4_FPAGE_RW, &size, &file); + + if (err) + { + printf("Could not obtain file: %s\n", l4sys_errtostr(err)); + return 1; + } + + client_MappedFile obj(file); + + /* Some memory to be mapped. */ + + size_t start_pos, end_pos, data_end; + + printf("Map region from %ld to %ld...\n", 0L, page(10)); + + err = obj.mmap(0, page(10), &start_pos, &end_pos, &data_end); + + if (err) + { + printf("Could not map file region: %s\n", l4sys_errtostr(err)); + return 1; + } + + printf("Mapped region from %ld to %ld with content %ld.\n", + start_pos, end_pos, data_end); + + size = end_pos - start_pos; + + printf("Attach region of size %ld...\n", size); + + err = ipc_attach_dataspace(file, size, (void **) &memory); + + if (err) + { + printf("Could not map memory: %s\n", l4sys_errtostr(err)); + return 1; + } + + printf("Mapped memory at %p\n", memory); + + if (data_end < size) + size = data_end; + + for (unsigned long offset = 0; offset < size; offset += step) + { + unsigned long remaining = size - offset; + unsigned long sample_remaining = remaining < sample ? remaining : sample; + + printf("%ld bytes from %p...\n", sample_remaining, (memory + offset)); + strncpy(buf, (memory + offset), sample_remaining); + buf[sample_remaining] = '\0'; + printf("%s\n", buf); + } + + return 0; +} diff -r 2e0c4ea098ad -r 71ea18032df4 dstest_host_server.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dstest_host_server.cc Fri Feb 12 00:21:03 2021 +0100 @@ -0,0 +1,65 @@ +/* + * Test dataspace operations. + * + * Copyright (C) 2020, 2021 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#include +#include + +#include +#include +#include + +#include "accessing.h" +#include "memory.h" +#include "memory_utils.h" +#include "pages.h" +#include "paging.h" +#include "resource_server.h" +#include "host_file_opener.h" + + + +const unsigned int MEMORY_PAGES = 10; + +int main(void) +{ + /* Some memory plus infrastructure. */ + + Memory mem(MEMORY_PAGES); + Accessing accessing; + Paging paging; + Pages pages(&mem); + HostFileOpener opener(&accessing, &paging, &pages); + + /* Register a server associating it with the given object. */ + + ResourceServer server(&opener); + long err = server.bind("server"); + + if (err) + { + printf("Could not bind server: %s\n", l4sys_errtostr(err)); + return 1; + } + + printf("Starting server...\n"); + server.start(); + return 0; +} diff -r 2e0c4ea098ad -r 71ea18032df4 dstest_server.cc --- a/dstest_server.cc Fri Feb 12 00:20:27 2021 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * Test dataspace operations. - * - * Copyright (C) 2020, 2021 Paul Boddie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA - */ - -#include -#include - -#include -#include -#include - -#include "accessing.h" -#include "memory.h" -#include "memory_utils.h" -#include "pages.h" -#include "paging.h" -#include "resource_server.h" -#include "host_file_opener.h" -// #include "test_file_opener.h" - - - -const unsigned int MEMORY_PAGES = 10; -const unsigned int FILE_PAGES = 20; - -int main(void) -{ - /* Some memory plus infrastructure. */ - - Memory mem(MEMORY_PAGES); - Accessing accessing; - Paging paging; - Pages pages(&mem); - HostFileOpener opener(&accessing, &paging, &pages); - // TestFileOpener opener(&accessing, &paging, &pages, page(FILE_PAGES)); - - /* Register a server associating it with the given object. */ - - ResourceServer server(&opener); - long err = server.bind("server"); - - if (err) - { - printf("Could not bind server: %s\n", l4sys_errtostr(err)); - return 1; - } - - printf("Starting server...\n"); - server.start(); - return 0; -} diff -r 2e0c4ea098ad -r 71ea18032df4 dstest_test_client.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dstest_test_client.cc Fri Feb 12 00:21:03 2021 +0100 @@ -0,0 +1,314 @@ +/* + * Test dataspace operations. + * + * Copyright (C) 2020, 2021 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "dataspace_client.h" +#include "opener_client.h" +#include "opener_context_client.h" +#include "mapped_file_client.h" +#include "memory_utils.h" + + + +const unsigned int ACTIVITY_ITERATIONS = 100; +const unsigned long NUMBER_OF_FILES = 10; +const unsigned int START_LIMIT = 10; +const unsigned int MAP_PAGES = 20; + + + +static std::mutex _lock; +static std::set _memory; + +static long attach_dataspace(l4_cap_idx_t cap, unsigned long size, void **memory) +{ + std::lock_guard guard(_lock); + + long err = ipc_attach_dataspace(cap, size, memory); + + if (err) + return err; + + if (_memory.find(*memory) != _memory.end()) + { + printf("Memory assigned again: %p\n", *memory); + return -L4_EINVAL; + } + + _memory.insert(*memory); + return L4_EOK; +} + +static long detach_dataspace(void *memory) +{ + std::lock_guard guard(_lock); + + _memory.erase(memory); + return ipc_detach_dataspace(memory); +} + + + +static long activity(l4_cap_idx_t context_ref, unsigned long fileid, unsigned int start_page) +{ + client_OpenerContext context(context_ref); + unsigned long step = page(1); + unsigned long sample = page(1); + + /* Allocate a buffer for sampling from the file. */ + + char buf[sample + 1]; + + /* Invoke the open method to receive the file reference. */ + + unsigned long size; + l4_cap_idx_t file_ref; + + long err = context.open(L4_FPAGE_RW, &size, &file_ref); + + if (err) + { + printf("Could not obtain file for %ld @ page %d: %s\n", fileid, start_page, l4sys_errtostr(err)); + return err; + } + + client_MappedFile file(file_ref); + + /* Some memory to be mapped. */ + + size_t start_pos, end_pos, data_end; + + err = file.mmap(page(start_page), page(MAP_PAGES), &start_pos, &end_pos, &data_end); + + if (err) + { + printf("Could not map file region for %ld @ page %d: %s\n", fileid, start_page, l4sys_errtostr(err)); + ipc_cap_free_um(file_ref); + return err; + } + + //printf("Mapped region from %ld to %ld with content %ld.\n", + // start_pos, end_pos, data_end); + + size = end_pos - start_pos; + + //printf("Attach region of size %ld...\n", size); + + char *memory; + + err = attach_dataspace(file_ref, size, (void **) &memory); + + if (err) + { + printf("Could not map memory for %ld @ page %d: %s\n", fileid, start_page, l4sys_errtostr(err)); + ipc_cap_free_um(file_ref); + return err; + } + + //printf("Mapped memory from %lx / %ld at %p\n", file_ref, page(start_page), memory); + + if (data_end < size) + size = data_end; + + for (unsigned long offset = 0; offset < size; offset += step) + { + unsigned long remaining = size - offset; + unsigned long sample_remaining = remaining < sample ? remaining : sample; + + strncpy(buf, (memory + offset), sample_remaining); + buf[sample_remaining] = '\0'; + //printf("%p: %s\n", (memory + offset), buf); + + /* Test the data obtained. */ + + unsigned long filepos = start_pos + offset; + unsigned long _fileid = 0, _filepos = 0; + char *sep = strchr(buf, ':'); + + if (sep != NULL) + { + *sep = '\0'; sep++; + _fileid = atol(buf); _filepos = atol(sep); + } + + if ((fileid != _fileid) || (filepos != _filepos)) + printf("! %ld:%ld is not %ld:%ld\n", _fileid, _filepos, fileid, filepos); + } + + detach_dataspace(memory); + + //printf("Unmapped memory from %ld at %p\n", page(start_page), memory); + + ipc_cap_free_um(file_ref); + + return L4_EOK; +} + + + +static long activity_iterate(l4_cap_idx_t context_ref, unsigned long fileid, unsigned int start_page) +{ + long err; + + /* Open the file, read pages, close the file, over and over. */ + + for (unsigned int iteration = 0; iteration < ACTIVITY_ITERATIONS; iteration++) + { + err = activity(context_ref, fileid, start_page); + if (err) + break; + } + + //printf("Ending: %ld @ %d\n", fileid, start_page); + return err; +} + + + +static long context_for_file(unsigned long fileid, l4_cap_idx_t *context_ref, char **filename) +{ + /* Obtain access to the filesystem. */ + + l4_cap_idx_t server = l4re_env_get_cap("server"); + client_Opener opener(server); + + long err = opener.context(context_ref); + + if (err) + { + printf("Could not obtain context: %s\n", l4sys_errtostr(err)); + return err; + } + + client_Dataspace context_ds(*context_ref); + unsigned long size, flags; + + err = context_ds.info(&size, &flags); + + if (err) + { + printf("Could not obtain context info: %s\n", l4sys_errtostr(err)); + ipc_cap_free_um(*context_ref); + return err; + } + + /* Map context memory to write the filename. */ + + err = attach_dataspace(*context_ref, size, (void **) filename); + + if (err) + { + printf("Could not map memory: %s\n", l4sys_errtostr(err)); + ipc_cap_free_um(*context_ref); + return err; + } + + /* Write the filename. */ + + sprintf(*filename, "%ld", fileid); + + return L4_EOK; +} + + + +static long activity_for_file(unsigned long fileid) +{ + std::thread *activities[START_LIMIT]; + + l4_cap_idx_t context_ref; + char *filename; + int current = 0; + + long err = context_for_file(fileid, &context_ref, &filename); + + if (err) + return err; + + for (unsigned int start_page = 0; start_page < START_LIMIT; start_page++) + activities[current++] = new std::thread(activity_iterate, context_ref, fileid, start_page); + + /* Wait for the threads. */ + + int limit = current; + + printf("Waiting for %d threads for %ld...\n", limit, fileid); + + for (current = 0; current < limit; current++) + { + activities[current]->join(); + printf("End: %ld @ %d\n", fileid, current); + } + + /* Discard the context. */ + + detach_dataspace(filename); + ipc_cap_free_um(context_ref); + + printf("End: %ld\n", fileid); + return L4_EOK; +} + + + +int main(void) +{ + /* Introduce concurrency control. */ + + ipc_cap_alloc_init(); + + std::thread *activities[NUMBER_OF_FILES]; + + unsigned long fileid; + int current = 0; + + for (fileid = 0; fileid < NUMBER_OF_FILES; fileid++) + activities[current++] = new std::thread(activity_for_file, fileid); + + /* Wait for the threads. */ + + int limit = current; + + printf("Waiting for %d threads...\n", limit); + + for (current = 0; current < limit; current++) + { + activities[current]->join(); + printf("Ended: %d\n", current); + } + + printf("Activities completed.\n"); + + return 0; +} diff -r 2e0c4ea098ad -r 71ea18032df4 dstest_test_server.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dstest_test_server.cc Fri Feb 12 00:21:03 2021 +0100 @@ -0,0 +1,72 @@ +/* + * Test dataspace operations. + * + * Copyright (C) 2020, 2021 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#include +#include + +#include + +#include +#include +#include + +#include "accessing.h" +#include "memory.h" +#include "memory_utils.h" +#include "pages.h" +#include "paging.h" +#include "resource_server.h" +#include "test_file_opener.h" + + + +const unsigned int MEMORY_PAGES = 10; +const unsigned int FILE_PAGES = 20; + +int main(void) +{ + /* Introduce concurrency control. */ + + ipc_cap_alloc_init(); + + /* Some memory plus infrastructure. */ + + Memory mem(MEMORY_PAGES); + Accessing accessing; + Paging paging; + Pages pages(&mem); + TestFileOpener opener(&accessing, &paging, &pages, page(FILE_PAGES)); + + /* Register a server associating it with the given object. */ + + ResourceServer server(&opener); + long err = server.bind("server"); + + if (err) + { + printf("Could not bind server: %s\n", l4sys_errtostr(err)); + return 1; + } + + printf("Starting server...\n"); + server.start(); + return 0; +}