1.1 --- a/Control Tue Apr 13 00:03:18 2021 +0200 1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 @@ -1,3 +0,0 @@ 1.4 -requires: libstdc++ libc libipc 1.5 -provides: dstest 1.6 -maintainer: paul@boddie.org.uk
2.1 --- a/Makefile Tue Apr 13 00:03:18 2021 +0200 2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 2.3 @@ -1,175 +0,0 @@ 2.4 -PKGDIR ?= . 2.5 -L4DIR ?= $(PKGDIR)/../.. 2.6 - 2.7 -TARGET = \ 2.8 - dstest_block_client dstest_block_client_simple \ 2.9 - dstest_host_client \ 2.10 - dstest_pipe_client \ 2.11 - dstest_test_client \ 2.12 - dstest_block_server \ 2.13 - dstest_host_server \ 2.14 - dstest_pipe_server \ 2.15 - dstest_test_server 2.16 - 2.17 -MODE = static 2.18 - 2.19 -# Locations for interface input and generated output. 2.20 - 2.21 -IDL_DIR = $(L4DIR)/pkg/libsystypes/idl 2.22 -IDL_MK_DIR = $(L4DIR)/idl4re/mk 2.23 -IDL_BUILD_DIR = . 2.24 -IDL_EXPORT_DIR = . 2.25 - 2.26 -include $(IDL_MK_DIR)/idl.mk 2.27 - 2.28 -# Compound interfaces. 2.29 - 2.30 -mapped_file_object_NAME = MappedFileObject 2.31 -mapped_file_object_INTERFACES = dataspace file mapped_file 2.32 - 2.33 -opener_context_object_NAME = OpenerContextObject 2.34 -opener_context_object_INTERFACES = dataspace opener_context 2.35 - 2.36 -pipe_object_NAME = PipeObject 2.37 -pipe_object_INTERFACES = dataspace pipe 2.38 - 2.39 -COMP_INTERFACES_CC = mapped_file_object opener_context_object pipe_object 2.40 - 2.41 -# Individual interfaces. 2.42 - 2.43 -CLIENT_INTERFACES_CC = dataspace file mapped_file opener opener_context pipe pipe_opener 2.44 - 2.45 -SERVER_INTERFACES_CC = opener pipe_opener $(call common_interfaces,$(COMP_INTERFACES_CC)) 2.46 - 2.47 -# Generated and plain source files. 2.48 - 2.49 -CLIENT_INTERFACES_SRC_CC = $(call interfaces_to_client_cc,$(CLIENT_INTERFACES_CC)) 2.50 - 2.51 -SERVER_INTERFACES_SRC_CC = $(call interfaces_to_server_cc,$(SERVER_INTERFACES_CC) $(COMP_INTERFACES_CC)) 2.52 - 2.53 -COMMON_SRC_CC = memory/memory_utils.cc 2.54 - 2.55 -PLAIN_SRC_CC_dstest_block_client = tests/dstest_block_client.cc client/file.cc 2.56 - 2.57 -PLAIN_SRC_CC_dstest_block_client_simple = tests/dstest_block_client_simple.cc client/client.cc client/file.cc 2.58 - 2.59 -PLAIN_SRC_CC_dstest_host_client = tests/dstest_host_client.cc client/file.cc 2.60 - 2.61 -PLAIN_SRC_CC_dstest_pipe_client = tests/dstest_pipe_client.cc client/file.cc 2.62 - 2.63 -PLAIN_SRC_CC_dstest_test_client = tests/dstest_test_client.cc client/file.cc 2.64 - 2.65 -PLAIN_SRC_CC_common_server = \ 2.66 - generic/accessor.cc generic/pager.cc \ 2.67 - generic/resource_server.cc \ 2.68 - mapping/access_map.cc mapping/flexpage.cc mapping/ipc.cc \ 2.69 - memory/memory_incremental.cc mapping/page_mapper.cc \ 2.70 - memory/memory_preallocated.cc memory/region.cc \ 2.71 - pages/page_queue.cc pages/page_queue_partitioned.cc \ 2.72 - pages/page_queue_shared.cc pages/pages.cc 2.73 - 2.74 -PLAIN_SRC_CC_common_file_server = \ 2.75 - files/file_pager.cc files/file_paging.cc \ 2.76 - files/opener_resource.cc files/opener_context_resource.cc \ 2.77 - generic/simple_pager.cc 2.78 - 2.79 -PLAIN_SRC_CC_dstest_block_server = \ 2.80 - $(PLAIN_SRC_CC_common_server) \ 2.81 - $(PLAIN_SRC_CC_common_file_server) \ 2.82 - files/block_file_accessor.cc files/block_file_opener.cc \ 2.83 - files/host_file_accessor.cc files/host_file_opener.cc \ 2.84 - servers/block_file_server.cc 2.85 - 2.86 -PLAIN_SRC_CC_dstest_host_server = \ 2.87 - $(PLAIN_SRC_CC_common_server) \ 2.88 - $(PLAIN_SRC_CC_common_file_server) \ 2.89 - files/host_file_accessor.cc files/host_file_opener.cc \ 2.90 - servers/host_file_server.cc 2.91 - 2.92 -PLAIN_SRC_CC_dstest_pipe_server = \ 2.93 - $(PLAIN_SRC_CC_common_server) \ 2.94 - pipes/pipe_opener_resource.cc pipes/pipe_pager.cc \ 2.95 - pipes/pipe_accessor.cc pipes/pipe_paging.cc \ 2.96 - servers/pipe_server.cc 2.97 - 2.98 -PLAIN_SRC_CC_dstest_test_server = \ 2.99 - $(PLAIN_SRC_CC_common_server) \ 2.100 - $(PLAIN_SRC_CC_common_file_server) \ 2.101 - files/test_file_accessor.cc files/test_file_opener.cc \ 2.102 - servers/test_file_server.cc 2.103 - 2.104 -# Normal definitions. 2.105 - 2.106 -SRC_CC_dstest_block_client = \ 2.107 - $(CLIENT_INTERFACES_SRC_CC) \ 2.108 - $(PLAIN_SRC_CC_dstest_block_client) \ 2.109 - $(COMMON_SRC_CC) 2.110 - 2.111 -SRC_CC_dstest_block_client_simple = \ 2.112 - $(CLIENT_INTERFACES_SRC_CC) \ 2.113 - $(PLAIN_SRC_CC_dstest_block_client_simple) \ 2.114 - $(COMMON_SRC_CC) 2.115 - 2.116 -SRC_CC_dstest_host_client = \ 2.117 - $(CLIENT_INTERFACES_SRC_CC) \ 2.118 - $(PLAIN_SRC_CC_dstest_host_client) \ 2.119 - $(COMMON_SRC_CC) 2.120 - 2.121 -SRC_CC_dstest_pipe_client = \ 2.122 - $(CLIENT_INTERFACES_SRC_CC) \ 2.123 - $(PLAIN_SRC_CC_dstest_pipe_client) \ 2.124 - $(COMMON_SRC_CC) 2.125 - 2.126 -SRC_CC_dstest_test_client = \ 2.127 - $(CLIENT_INTERFACES_SRC_CC) \ 2.128 - $(PLAIN_SRC_CC_dstest_test_client) \ 2.129 - $(COMMON_SRC_CC) 2.130 - 2.131 -SRC_CC_dstest_block_server = \ 2.132 - $(SERVER_INTERFACES_SRC_CC) \ 2.133 - $(PLAIN_SRC_CC_dstest_block_server) \ 2.134 - $(COMMON_SRC_CC) 2.135 - 2.136 -SRC_CC_dstest_host_server = \ 2.137 - $(SERVER_INTERFACES_SRC_CC) \ 2.138 - $(PLAIN_SRC_CC_dstest_host_server) \ 2.139 - $(COMMON_SRC_CC) 2.140 - 2.141 -SRC_CC_dstest_pipe_server = \ 2.142 - $(SERVER_INTERFACES_SRC_CC) \ 2.143 - $(PLAIN_SRC_CC_dstest_pipe_server) \ 2.144 - $(COMMON_SRC_CC) 2.145 - 2.146 -SRC_CC_dstest_test_server = \ 2.147 - $(SERVER_INTERFACES_SRC_CC) \ 2.148 - $(PLAIN_SRC_CC_dstest_test_server) \ 2.149 - $(COMMON_SRC_CC) 2.150 - 2.151 -REQUIRES_LIBS = l4re_c-util libipc libstdc++ libsystypes 2.152 - 2.153 -PRIVATE_INCDIR = $(PKGDIR) $(PKGDIR)/client \ 2.154 - $(PKGDIR)/files $(PKGDIR)/generic \ 2.155 - $(PKGDIR)/mapping $(PKGDIR)/memory \ 2.156 - $(PKGDIR)/pages $(PKGDIR)/pipes \ 2.157 - $(IDL_BUILD_DIR) $(IDL_EXPORT_DIR) 2.158 - 2.159 -include $(L4DIR)/mk/prog.mk 2.160 -include $(IDL_MK_DIR)/interface_rules.mk 2.161 - 2.162 -$(PLAIN_SRC_CC_dstest_block_client): $(CLIENT_INTERFACES_SRC_CC) 2.163 - 2.164 -$(PLAIN_SRC_CC_dstest_block_client_simple): $(CLIENT_INTERFACES_SRC_CC) 2.165 - 2.166 -$(PLAIN_SRC_CC_dstest_host_client): $(CLIENT_INTERFACES_SRC_CC) 2.167 - 2.168 -$(PLAIN_SRC_CC_dstest_pipe_client): $(CLIENT_INTERFACES_SRC_CC) 2.169 - 2.170 -$(PLAIN_SRC_CC_dstest_test_client): $(CLIENT_INTERFACES_SRC_CC) 2.171 - 2.172 -$(PLAIN_SRC_CC_dstest_block_server): $(SERVER_INTERFACES_SRC_CC) 2.173 - 2.174 -$(PLAIN_SRC_CC_dstest_host_server): $(SERVER_INTERFACES_SRC_CC) 2.175 - 2.176 -$(PLAIN_SRC_CC_dstest_pipe_server): $(SERVER_INTERFACES_SRC_CC) 2.177 - 2.178 -$(PLAIN_SRC_CC_dstest_test_server): $(SERVER_INTERFACES_SRC_CC)
3.1 --- a/client/client.cc Tue Apr 13 00:03:18 2021 +0200 3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3 @@ -1,390 +0,0 @@ 3.4 -/* 3.5 - * Filesystem client functions. 3.6 - * 3.7 - * Copyright (C) 2018, 2019, 2020, 2021 Paul Boddie <paul@boddie.org.uk> 3.8 - * 3.9 - * This program is free software; you can redistribute it and/or 3.10 - * modify it under the terms of the GNU General Public License as 3.11 - * published by the Free Software Foundation; either version 2 of 3.12 - * the License, or (at your option) any later version. 3.13 - * 3.14 - * This program is distributed in the hope that it will be useful, 3.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 3.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 3.17 - * GNU General Public License for more details. 3.18 - * 3.19 - * You should have received a copy of the GNU General Public License 3.20 - * along with this program; if not, write to the Free Software 3.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 3.22 - * Boston, MA 02110-1301, USA 3.23 - */ 3.24 - 3.25 -#include <l4/re/env.h> 3.26 - 3.27 -#include <stdio.h> 3.28 -#include <stdlib.h> 3.29 - 3.30 -#include "client.h" 3.31 - 3.32 - 3.33 - 3.34 -/* Default size of pipe regions. */ 3.35 - 3.36 -const offset_t DEFAULT_PIPE_SIZE = 4096; 3.37 - 3.38 - 3.39 - 3.40 -/* Close a filesystem object. */ 3.41 - 3.42 -void client_close(file_t *file) 3.43 -{ 3.44 - if (file == NULL) 3.45 - return; 3.46 - 3.47 - file_close(file); 3.48 - free(file); 3.49 -} 3.50 - 3.51 - 3.52 - 3.53 -/* Open a filesystem object. */ 3.54 - 3.55 -file_t *client_open(const char *name, flags_t flags) 3.56 -{ 3.57 - file_t *file = (file_t *) malloc(sizeof(file_t)); 3.58 - 3.59 - if (file == NULL) 3.60 - return NULL; 3.61 - 3.62 - l4_cap_idx_t server = l4re_env_get_cap("server"); 3.63 - 3.64 - if (file_open(file, name, flags, server)) 3.65 - { 3.66 - free(file); 3.67 - return NULL; 3.68 - } 3.69 - 3.70 - return file; 3.71 -} 3.72 - 3.73 - 3.74 - 3.75 -/* Open a pipe object. */ 3.76 - 3.77 -long client_pipe(file_t **reader, file_t **writer) 3.78 -{ 3.79 - *reader = (file_t *) malloc(sizeof(file_t)); 3.80 - 3.81 - if (*reader == NULL) 3.82 - return -L4_ENOMEM; 3.83 - 3.84 - *writer = (file_t *) malloc(sizeof(file_t)); 3.85 - 3.86 - if (*writer == NULL) 3.87 - { 3.88 - free(*reader); 3.89 - return -L4_ENOMEM; 3.90 - } 3.91 - 3.92 - l4_cap_idx_t server = l4re_env_get_cap("pipes"); 3.93 - 3.94 - long err = pipe_open(DEFAULT_PIPE_SIZE, *reader, *writer, server); 3.95 - 3.96 - if (err) 3.97 - { 3.98 - free(*reader); 3.99 - free(*writer); 3.100 - } 3.101 - 3.102 - return err; 3.103 -} 3.104 - 3.105 - 3.106 - 3.107 -/* Flush data conditionally to the filesystem object. */ 3.108 - 3.109 -static long _flush(file_t *file, offset_t position) 3.110 -{ 3.111 - long err; 3.112 - 3.113 - /* Where the position is outside the current region, re-map. */ 3.114 - 3.115 - if ((position < file->start_pos) || (position >= file->end_pos)) 3.116 - { 3.117 - if (file->can_mmap) 3.118 - { 3.119 - if (file_mmap(file, position, file_span(file))) 3.120 - return -L4_EIO; 3.121 - } 3.122 - 3.123 - /* Strict conditions for region navigation in pipes. */ 3.124 - 3.125 - else if ((position != file->end_pos) || 3.126 - (client_next_region(file) == NULL)) 3.127 - return -L4_EIO; 3.128 - } 3.129 - 3.130 - /* Otherwise, flush any written data in the current region and update the 3.131 - file size details. */ 3.132 - 3.133 - else 3.134 - { 3.135 - err = client_flush(file); 3.136 - 3.137 - if (err) 3.138 - return err; 3.139 - } 3.140 - 3.141 - /* Update the current data offset. */ 3.142 - 3.143 - file->data_current = position - file->start_pos; 3.144 - return L4_EOK; 3.145 -} 3.146 - 3.147 - 3.148 - 3.149 -/* Flush data explicitly to the filesystem object. */ 3.150 - 3.151 -long client_flush(file_t *file) 3.152 -{ 3.153 - if (file == NULL) 3.154 - return -L4_EINVAL; 3.155 - 3.156 - /* Flush and retain most buffer settings. */ 3.157 - 3.158 - return file_flush(file); 3.159 -} 3.160 - 3.161 - 3.162 - 3.163 -/* Map a memory region to a file. */ 3.164 - 3.165 -void *client_mmap(file_t *file, offset_t position, offset_t length) 3.166 -{ 3.167 - if ((file == NULL) || (file_mmap(file, position, length))) 3.168 - return NULL; 3.169 - 3.170 - return file->memory; 3.171 -} 3.172 - 3.173 - 3.174 - 3.175 -/* Obtain the current region of a pipe. */ 3.176 - 3.177 -void *client_current_region(file_t *file) 3.178 -{ 3.179 - if ((file == NULL) || (pipe_current(file))) 3.180 - return NULL; 3.181 - 3.182 - return file->memory; 3.183 -} 3.184 - 3.185 - 3.186 - 3.187 -/* Obtain the next region of a pipe. */ 3.188 - 3.189 -void *client_next_region(file_t *file) 3.190 -{ 3.191 - if ((file == NULL) || (pipe_next(file))) 3.192 - return NULL; 3.193 - 3.194 - return file->memory; 3.195 -} 3.196 - 3.197 - 3.198 - 3.199 -/* Read from the filesystem object into the buffer provided. */ 3.200 - 3.201 -offset_t client_read(file_t *file, void *buf, offset_t count) 3.202 -{ 3.203 - if (file == NULL) 3.204 - return 0; 3.205 - 3.206 - /* Amount available in the descriptor buffer already. */ 3.207 - 3.208 - offset_t available = file_data_available(file); 3.209 - offset_t to_transfer, total = 0; 3.210 - 3.211 - while (count > 0) 3.212 - { 3.213 - /* If there is no data, try and obtain more data. */ 3.214 - 3.215 - if (!available) 3.216 - { 3.217 - /* Flush any unwritten data, preparing to read from the file position at 3.218 - the end of the data, and returning if no new data is available. */ 3.219 - 3.220 - if (_flush(file, file_data_end_position(file))) 3.221 - break; 3.222 - 3.223 - available = file_data_available(file); 3.224 - 3.225 - if (!available) 3.226 - break; 3.227 - } 3.228 - 3.229 - /* Transfer data into the supplied buffer. */ 3.230 - 3.231 - to_transfer = available <= count ? available : count; 3.232 - 3.233 - file_data_read(file, (char *) buf, to_transfer); 3.234 - 3.235 - /* Update counters. */ 3.236 - 3.237 - available -= to_transfer; 3.238 - 3.239 - count -= to_transfer; 3.240 - total += to_transfer; 3.241 - 3.242 - buf = ((char *) buf + to_transfer); 3.243 - } 3.244 - 3.245 - return total; 3.246 -} 3.247 - 3.248 - 3.249 - 3.250 -/* Ensure that the buffer can provide the needed data. */ 3.251 - 3.252 -offset_t client_seek(file_t *file, offset_t offset, int whence) 3.253 -{ 3.254 - if (file == NULL) 3.255 - return 0; 3.256 - 3.257 - offset_t position, current = file_data_current_position(file), change; 3.258 - 3.259 - switch (whence) 3.260 - { 3.261 - case SEEK_SET: 3.262 - position = offset; 3.263 - break; 3.264 - 3.265 - case SEEK_CUR: 3.266 - position = current + offset; 3.267 - break; 3.268 - 3.269 - case SEEK_END: 3.270 - position = file->size + offset; 3.271 - break; 3.272 - 3.273 - default: 3.274 - /* NOTE: Set errno to EINVAL. */ 3.275 - return -1; 3.276 - } 3.277 - 3.278 - /* Retain the current position if unchanged. */ 3.279 - 3.280 - if (position == current) 3.281 - return position; 3.282 - 3.283 - /* Move forward in the file. */ 3.284 - 3.285 - if (position > current) 3.286 - { 3.287 - change = position - current; 3.288 - 3.289 - /* Move towards the end of available data. 3.290 - Request new data if not enough is available. */ 3.291 - 3.292 - if (change <= file_data_available(file)) 3.293 - { 3.294 - file->data_current += change; 3.295 - return position; 3.296 - } 3.297 - } 3.298 - 3.299 - /* Move backward in the file. */ 3.300 - 3.301 - else 3.302 - { 3.303 - change = current - position; 3.304 - 3.305 - /* Move towards the start of available data. 3.306 - Request new data if moving beyond the start of the data. */ 3.307 - 3.308 - if (change <= file->data_current) 3.309 - { 3.310 - file->data_current -= change; 3.311 - return position; 3.312 - } 3.313 - } 3.314 - 3.315 - /* Handle unwritten data and reset the buffer for reading. */ 3.316 - 3.317 - _flush(file, position); 3.318 - return position; 3.319 -} 3.320 - 3.321 - 3.322 - 3.323 -long client_tell(file_t *file) 3.324 -{ 3.325 - if (file == NULL) 3.326 - return -L4_EINVAL; 3.327 - 3.328 - return file_data_current_position(file); 3.329 -} 3.330 - 3.331 - 3.332 - 3.333 -/* Write to the filesystem object from the buffer provided. */ 3.334 - 3.335 -offset_t client_write(file_t *file, const void *buf, offset_t count) 3.336 -{ 3.337 - if (file == NULL) 3.338 - return 0; 3.339 - 3.340 - /* Attempt to ensure that the file can accept the amount of data to be 3.341 - written. This may not resize to the needed amount if a file has a fixed 3.342 - size, but data will still be written to any available space. */ 3.343 - 3.344 - offset_t needed_size = file_data_current_position(file) + count; 3.345 - 3.346 - if (file->size < needed_size) 3.347 - { 3.348 - file_resize(file, needed_size); 3.349 - 3.350 - if (file->size < needed_size) 3.351 - count = file->size - file_data_current_position(file); 3.352 - } 3.353 - 3.354 - /* Space remaining in the descriptor buffer. */ 3.355 - 3.356 - offset_t space = file_data_space(file); 3.357 - offset_t to_transfer, total = 0; 3.358 - 3.359 - while (count > 0) 3.360 - { 3.361 - /* If no space is available, try and send data, reset the buffer. */ 3.362 - 3.363 - if (!space) 3.364 - { 3.365 - /* Flush any unwritten data and continue writing from the current data 3.366 - position. */ 3.367 - 3.368 - if (_flush(file, file_data_current_position(file))) 3.369 - break; 3.370 - 3.371 - space = file_data_space(file); 3.372 - } 3.373 - 3.374 - /* Transfer data into the supplied buffer. */ 3.375 - 3.376 - to_transfer = space <= count ? space : count; 3.377 - 3.378 - file_data_write(file, (char *) buf, to_transfer); 3.379 - 3.380 - /* Update counters. */ 3.381 - 3.382 - space -= to_transfer; 3.383 - 3.384 - count -= to_transfer; 3.385 - total += to_transfer; 3.386 - 3.387 - buf = ((char *) buf + to_transfer); 3.388 - } 3.389 - 3.390 - return total; 3.391 -} 3.392 - 3.393 -// vim: tabstop=2 expandtab shiftwidth=2
4.1 --- a/client/client.h Tue Apr 13 00:03:18 2021 +0200 4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 4.3 @@ -1,56 +0,0 @@ 4.4 -/* 4.5 - * Filesystem client functions. 4.6 - * 4.7 - * Copyright (C) 2018, 2019, 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 -#pragma once 4.26 - 4.27 -#include "file.h" 4.28 - 4.29 -EXTERN_C_BEGIN 4.30 - 4.31 -/* File operations. */ 4.32 - 4.33 -void client_close(file_t *file); 4.34 -file_t *client_open(const char *name, flags_t flags); 4.35 -long client_pipe(file_t **reader, file_t **writer); 4.36 - 4.37 -/* File and region operations. */ 4.38 - 4.39 -long client_flush(file_t *file); 4.40 -void *client_mmap(file_t *file, offset_t position, offset_t length); 4.41 - 4.42 -/* Pipe region operations. */ 4.43 - 4.44 -void *client_current_region(file_t *file); 4.45 -void *client_next_region(file_t *file); 4.46 - 4.47 -/* File data operations. */ 4.48 - 4.49 -offset_t client_read(file_t *file, void *buf, offset_t count); 4.50 -offset_t client_write(file_t *file, const void *buf, offset_t count); 4.51 - 4.52 -/* File navigation operations. */ 4.53 - 4.54 -offset_t client_seek(file_t *file, offset_t offset, int whence); 4.55 -long client_tell(file_t *file); 4.56 - 4.57 -EXTERN_C_END 4.58 - 4.59 -// vim: tabstop=2 expandtab shiftwidth=2
5.1 --- a/client/file.cc Tue Apr 13 00:03:18 2021 +0200 5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 5.3 @@ -1,452 +0,0 @@ 5.4 -/* 5.5 - * File access convenience functions. 5.6 - * 5.7 - * Copyright (C) 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 <ipc/cap_alloc.h> 5.26 -#include <ipc/mem_ipc.h> 5.27 - 5.28 -#include <string.h> 5.29 - 5.30 -#include "dataspace_client.h" 5.31 -#include "file_client.h" 5.32 -#include "opener_client.h" 5.33 -#include "opener_context_client.h" 5.34 -#include "pipe_client.h" 5.35 -#include "pipe_opener_client.h" 5.36 -#include "mapped_file_client.h" 5.37 - 5.38 -#include "file.h" 5.39 - 5.40 - 5.41 - 5.42 -/* Update the extent of the file in a region using the region start and end 5.43 - positions and the file size. */ 5.44 - 5.45 -static void _update_extent(file_t *file) 5.46 -{ 5.47 - /* Handle files ending after or within the region. */ 5.48 - 5.49 - if (file->size > file->start_pos) 5.50 - { 5.51 - if (file->size > file->end_pos) 5.52 - file->data_end = file->end_pos - file->start_pos; 5.53 - else 5.54 - file->data_end = file->size - file->start_pos; 5.55 - } 5.56 - 5.57 - /* Handle files ending before the region. */ 5.58 - 5.59 - else 5.60 - file->data_end = 0; 5.61 -} 5.62 - 5.63 - 5.64 - 5.65 -/* Initialise the given file structure. */ 5.66 - 5.67 -void file_init(file_t *file) 5.68 -{ 5.69 - file->memory = NULL; 5.70 - file->ref = L4_INVALID_CAP; 5.71 - file->start_pos = 0; 5.72 - file->end_pos = 0; 5.73 - file->data_end = 0; 5.74 - file->data_current = 0; 5.75 - file->can_mmap = 1; 5.76 -} 5.77 - 5.78 - 5.79 - 5.80 -/* Release resources for the given file. */ 5.81 - 5.82 -void file_close(file_t *file) 5.83 -{ 5.84 - if (l4_is_valid_cap(file->ref)) 5.85 - ipc_cap_free_um(file->ref); 5.86 - 5.87 - if (file->memory != NULL) 5.88 - ipc_detach_dataspace(file->memory); 5.89 - 5.90 - file_init(file); 5.91 -} 5.92 - 5.93 -/* Open a file using the given structure, indicating the filename and 5.94 - filesystem server. The file_mmap function should be used to obtain access to 5.95 - memory providing file data. This is a convenience function invoking 5.96 - file_context and file_context_open. */ 5.97 - 5.98 -long file_open(file_t *file, const char *filename, flags_t flags, l4_cap_idx_t server) 5.99 -{ 5.100 - file_t context; 5.101 - long err; 5.102 - 5.103 - err = file_context(&context, server); 5.104 - if (err) 5.105 - return err; 5.106 - 5.107 - if (!file_string_set(&context, filename, 0, NULL)) 5.108 - return -L4_ENOMEM; 5.109 - 5.110 - err = file_context_open(file, flags, &context); 5.111 - 5.112 - /* Close the context, although a separate mechanism could permit contexts to 5.113 - open several files. */ 5.114 - 5.115 - file_close(&context); 5.116 - return err; 5.117 -} 5.118 - 5.119 - 5.120 - 5.121 -/* Initialise a file structure for a context obtained from the given server 5.122 - attaching memory to communicate filename information. */ 5.123 - 5.124 -long file_context(file_t *file, l4_cap_idx_t server) 5.125 -{ 5.126 - if (l4_is_invalid_cap(server)) 5.127 - return -L4_EINVAL; 5.128 - 5.129 - client_Opener opener(server); 5.130 - offset_t size; 5.131 - flags_t flags; 5.132 - long err; 5.133 - 5.134 - file_init(file); 5.135 - 5.136 - err = opener.context(&file->ref); 5.137 - if (err) 5.138 - return err; 5.139 - 5.140 - client_Dataspace context_ds(file->ref); 5.141 - 5.142 - err = context_ds.info(&size, &flags); 5.143 - if (err) 5.144 - return err; 5.145 - 5.146 - file->start_pos = 0; 5.147 - file->end_pos = size; 5.148 - 5.149 - return ipc_attach_dataspace(file->ref, size, (void **) &file->memory); 5.150 -} 5.151 - 5.152 -/* Open a file using the given structure and context. */ 5.153 - 5.154 -long file_context_open(file_t *file, flags_t flags, file_t *context) 5.155 -{ 5.156 - client_OpenerContext openercontext(context->ref); 5.157 - file_init(file); 5.158 - return openercontext.open(flags, &file->size, &file->ref); 5.159 -} 5.160 - 5.161 - 5.162 - 5.163 -/* Flush populated data and obtain an updated file size and populated data 5.164 - details. */ 5.165 - 5.166 -long file_flush(file_t *file) 5.167 -{ 5.168 - client_File _file(file->ref); 5.169 - long err = _file.flush(file->data_current, &file->size); 5.170 - 5.171 - if (err) 5.172 - return err; 5.173 - 5.174 - _update_extent(file); 5.175 - 5.176 - return L4_EOK; 5.177 -} 5.178 - 5.179 -/* Map a region of the given file to a memory region, obtaining an updated file 5.180 - size and populated data details. Unmap any previously mapped region. */ 5.181 - 5.182 -long file_mmap(file_t *file, offset_t position, offset_t length) 5.183 -{ 5.184 - char *memory = file->memory; 5.185 - client_MappedFile mapped_file(file->ref); 5.186 - long err = mapped_file.mmap(position, length, &file->start_pos, 5.187 - &file->end_pos, &file->size); 5.188 - 5.189 - if (err) 5.190 - return err; 5.191 - 5.192 - _update_extent(file); 5.193 - 5.194 - err = ipc_attach_dataspace(file->ref, file_span(file), (void **) &file->memory); 5.195 - if (err) 5.196 - return err; 5.197 - 5.198 - if (memory != NULL) 5.199 - ipc_detach_dataspace(memory); 5.200 - 5.201 - return L4_EOK; 5.202 -} 5.203 - 5.204 -/* Resize a file, obtaining updated file size and populated data details. */ 5.205 - 5.206 -long file_resize(file_t *file, offset_t size) 5.207 -{ 5.208 - client_File _file(file->ref); 5.209 - offset_t file_size = size; 5.210 - long err = _file.resize(&file_size); 5.211 - 5.212 - if (err) 5.213 - return err; 5.214 - 5.215 - file->size = file_size; 5.216 - _update_extent(file); 5.217 - return L4_EOK; 5.218 -} 5.219 - 5.220 - 5.221 - 5.222 -/* Return the amount of data in the mapped region for the given file. */ 5.223 - 5.224 -offset_t file_populated_span(file_t *file) 5.225 -{ 5.226 - offset_t size = file_span(file); 5.227 - return (file->data_end < size) ? file->data_end : size; 5.228 -} 5.229 - 5.230 -/* Return the size of the mapped region for the given file. */ 5.231 - 5.232 -offset_t file_span(file_t *file) 5.233 -{ 5.234 - return file->end_pos - file->start_pos; 5.235 -} 5.236 - 5.237 - 5.238 - 5.239 -/* Get a pointer to any terminated string at the given offset or NULL if the 5.240 - data from offset is not terminated. */ 5.241 - 5.242 -char *file_string_get(file_t *file, offset_t offset) 5.243 -{ 5.244 - offset_t limit = file_span(file) - offset; 5.245 - 5.246 - if (strnlen(file->memory + offset, limit) < limit) 5.247 - return file->memory + offset; 5.248 - else 5.249 - return NULL; 5.250 -} 5.251 - 5.252 -/* Copy a string to the mapped region at the given offset, returning 1 (true) 5.253 - where all characters were copied, 0 (false) otherwise. The precise number of 5.254 - characters copied, excluding the zero terminator is provided via the written 5.255 - parameter if it is not specified as NULL. */ 5.256 - 5.257 -int file_string_set(file_t *file, const char *data, offset_t offset, 5.258 - offset_t *written) 5.259 -{ 5.260 - offset_t i, pos, limit = file_span(file); 5.261 - 5.262 - /* Do not attempt to copy data with an invalid offset. */ 5.263 - 5.264 - if (offset >= limit) 5.265 - { 5.266 - if (written != NULL) 5.267 - *written = 0; 5.268 - return 0; 5.269 - } 5.270 - 5.271 - /* Copy the data to the given offset, stopping at the end of the region. */ 5.272 - 5.273 - for (i = 0, pos = offset; pos < limit; i++, pos++) 5.274 - { 5.275 - file->memory[pos] = data[i]; 5.276 - 5.277 - /* Terminator written, can return immediately. */ 5.278 - 5.279 - if (!data[i]) 5.280 - { 5.281 - if (written != NULL) 5.282 - *written = pos - offset; 5.283 - return 1; 5.284 - } 5.285 - } 5.286 - 5.287 - /* Terminate the incomplete string at the end of the region. */ 5.288 - 5.289 - file->memory[limit - 1] = '\0'; 5.290 - if (written != NULL) 5.291 - *written = limit - 1 - offset; 5.292 - return 0; 5.293 -} 5.294 - 5.295 - 5.296 - 5.297 -/* Return the number of remaining populated bytes in the region. */ 5.298 - 5.299 -offset_t file_data_available(file_t *file) 5.300 -{ 5.301 - return file_populated_span(file) - file->data_current; 5.302 -} 5.303 - 5.304 -/* Return the current data offset in the region. */ 5.305 - 5.306 -char *file_data_current(file_t *file) 5.307 -{ 5.308 - return file->memory + file->data_current; 5.309 -} 5.310 - 5.311 -/* Return the current access position in the file. */ 5.312 - 5.313 -offset_t file_data_current_position(file_t *file) 5.314 -{ 5.315 - return file->start_pos + file->data_current; 5.316 -} 5.317 - 5.318 -/* Return the position of the end of the populated bytes in the region. */ 5.319 - 5.320 -offset_t file_data_end_position(file_t *file) 5.321 -{ 5.322 - return file->start_pos + file->data_end; 5.323 -} 5.324 - 5.325 -/* Return the amount of remaining space in the region. */ 5.326 - 5.327 -offset_t file_data_space(file_t *file) 5.328 -{ 5.329 - return file_span(file) - file->data_current; 5.330 -} 5.331 - 5.332 - 5.333 - 5.334 -/* Copy data to the given buffer from the current data position, updating the 5.335 - position. */ 5.336 - 5.337 -void file_data_read(file_t *file, char *buf, size_t to_transfer) 5.338 -{ 5.339 - memcpy(buf, file_data_current(file), to_transfer); 5.340 - 5.341 - /* Update position details. */ 5.342 - 5.343 - file->data_current += to_transfer; 5.344 -} 5.345 - 5.346 -/* Copy data from the given buffer to the current data position, updating the 5.347 - position and the extent of populated data if this was exceeded. */ 5.348 - 5.349 -void file_data_write(file_t *file, char *buf, size_t to_transfer) 5.350 -{ 5.351 - memcpy(file_data_current(file), buf, to_transfer); 5.352 - 5.353 - /* Update position details. */ 5.354 - 5.355 - file->data_current += to_transfer; 5.356 - 5.357 - if (file->data_current > file->data_end) 5.358 - file->data_end = file->data_current; 5.359 -} 5.360 - 5.361 - 5.362 - 5.363 -/* Open two pipe endpoints using the given pipe server. */ 5.364 - 5.365 -long pipe_open(offset_t size, file_t *reader, file_t *writer, l4_cap_idx_t server) 5.366 -{ 5.367 - if (l4_is_invalid_cap(server)) 5.368 - return -L4_EINVAL; 5.369 - 5.370 - client_PipeOpener opener(server); 5.371 - 5.372 - file_init(reader); 5.373 - file_init(writer); 5.374 - 5.375 - /* Pipes can usually only be accessed via region navigation. */ 5.376 - 5.377 - reader->can_mmap = 0; 5.378 - writer->can_mmap = 0; 5.379 - 5.380 - long err = opener.pipe(size, &reader->ref, &writer->ref); 5.381 - if (err) 5.382 - return err; 5.383 - 5.384 - err = pipe_next(writer) || pipe_next(reader); 5.385 - 5.386 - if (err) 5.387 - { 5.388 - file_close(reader); 5.389 - file_close(writer); 5.390 - } 5.391 - 5.392 - return err; 5.393 -} 5.394 - 5.395 -/* Access the current region for a pipe endpoint. */ 5.396 - 5.397 -long pipe_current(file_t *pipe) 5.398 -{ 5.399 - client_Pipe _pipe(pipe->ref); 5.400 - long err = _pipe.current_region(&pipe->data_end, &pipe->size); 5.401 - char *memory = pipe->memory; 5.402 - 5.403 - if (err) 5.404 - return err; 5.405 - 5.406 - pipe->end_pos = pipe->size; 5.407 - 5.408 - err = ipc_attach_dataspace(pipe->ref, file_span(pipe), (void **) &pipe->memory); 5.409 - if (err) 5.410 - return err; 5.411 - 5.412 - if (memory != NULL) 5.413 - ipc_detach_dataspace(memory); 5.414 - 5.415 - return L4_EOK; 5.416 -} 5.417 - 5.418 -/* Access the next region for a pipe endpoint, updating the eventual size of 5.419 - the current region. */ 5.420 - 5.421 -long pipe_next(file_t *pipe) 5.422 -{ 5.423 - client_Pipe _pipe(pipe->ref); 5.424 - long err = _pipe.next_region(&pipe->data_end, &pipe->size); 5.425 - char *memory = pipe->memory; 5.426 - 5.427 - if (err) 5.428 - return err; 5.429 - 5.430 - pipe->end_pos = pipe->size; 5.431 - 5.432 - err = ipc_attach_dataspace(pipe->ref, file_span(pipe), (void **) &pipe->memory); 5.433 - if (err) 5.434 - return err; 5.435 - 5.436 - if (memory != NULL) 5.437 - ipc_detach_dataspace(memory); 5.438 - 5.439 - return L4_EOK; 5.440 -} 5.441 - 5.442 -/* Set the size of the written region. */ 5.443 - 5.444 -long pipe_written(file_t *pipe, offset_t size) 5.445 -{ 5.446 - if (size <= pipe->size) 5.447 - { 5.448 - pipe->data_end = size; 5.449 - return L4_EOK; 5.450 - } 5.451 - else 5.452 - return -L4_EINVAL; 5.453 -} 5.454 - 5.455 -// vim: tabstop=2 expandtab shiftwidth=2
6.1 --- a/client/file.h Tue Apr 13 00:03:18 2021 +0200 6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 6.3 @@ -1,114 +0,0 @@ 6.4 -/* 6.5 - * File access convenience functions and types. 6.6 - * 6.7 - * Copyright (C) 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/sys/types.h> 6.26 - 6.27 -#include <systypes/base.h> 6.28 - 6.29 - 6.30 - 6.31 -EXTERN_C_BEGIN 6.32 - 6.33 -/* File access abstraction. */ 6.34 - 6.35 -typedef struct 6.36 -{ 6.37 - /* File object reference. */ 6.38 - 6.39 - l4_cap_idx_t ref; 6.40 - 6.41 - /* Mapped memory accessing a file region. */ 6.42 - 6.43 - char *memory; 6.44 - 6.45 - /* File region parameters. */ 6.46 - 6.47 - offset_t start_pos, end_pos; /* start and end positions of region */ 6.48 - offset_t data_end; /* amount/extent of data in the region */ 6.49 - offset_t data_current; /* client access offset */ 6.50 - 6.51 - /* Total size of file. */ 6.52 - 6.53 - offset_t size; 6.54 - 6.55 - /* Arbitrary memory mapping support. */ 6.56 - 6.57 - int can_mmap; 6.58 - 6.59 -} file_t; 6.60 - 6.61 - 6.62 - 6.63 -/* File operations. */ 6.64 - 6.65 -void file_close(file_t *file); 6.66 -long file_open(file_t *file, const char *filename, flags_t flags, l4_cap_idx_t server); 6.67 - 6.68 -/* File lifecycle operations. */ 6.69 - 6.70 -long file_context(file_t *file, l4_cap_idx_t server); 6.71 -long file_context_open(file_t *file, flags_t flags, file_t *context); 6.72 -void file_init(file_t *file); 6.73 - 6.74 -/* File and region operations. */ 6.75 - 6.76 -long file_flush(file_t *file); 6.77 -long file_mmap(file_t *file, offset_t position, offset_t length); 6.78 -long file_resize(file_t *file, offset_t size); 6.79 - 6.80 -/* File and region properties. */ 6.81 - 6.82 -offset_t file_populated_span(file_t *file); 6.83 -offset_t file_span(file_t *file); 6.84 - 6.85 -/* Convenience functions. */ 6.86 - 6.87 -char *file_string_get(file_t *file, offset_t offset); 6.88 -int file_string_set(file_t *file, const char *data, offset_t offset, offset_t *written); 6.89 - 6.90 -/* Client data functions. */ 6.91 - 6.92 -offset_t file_data_available(file_t *file); 6.93 -char *file_data_current(file_t *file); 6.94 -offset_t file_data_current_position(file_t *file); 6.95 -offset_t file_data_end_position(file_t *file); 6.96 -offset_t file_data_space(file_t *file); 6.97 - 6.98 -/* Client data transfer functions. */ 6.99 - 6.100 -void file_data_read(file_t *file, char *buf, size_t to_transfer); 6.101 -void file_data_write(file_t *file, char *buf, size_t to_transfer); 6.102 - 6.103 - 6.104 - 6.105 -/* Pipe operations. */ 6.106 - 6.107 -long pipe_open(offset_t size, file_t *reader, file_t *writer, l4_cap_idx_t server); 6.108 - 6.109 -/* Pipe region operations. */ 6.110 - 6.111 -long pipe_current(file_t *pipe); 6.112 -long pipe_next(file_t *pipe); 6.113 -long pipe_written(file_t *pipe, offset_t size); 6.114 - 6.115 -EXTERN_C_END 6.116 - 6.117 -// vim: tabstop=2 expandtab shiftwidth=2
7.1 --- a/files/block_file_accessor.cc Tue Apr 13 00:03:18 2021 +0200 7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 7.3 @@ -1,127 +0,0 @@ 7.4 -/* 7.5 - * A file accessor employing a rewritable memory area. 7.6 - * 7.7 - * Copyright (C) 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 <stdio.h> 7.26 -#include <string.h> 7.27 -#include <sys/types.h> 7.28 -#include <sys/stat.h> 7.29 - 7.30 -#include <algorithm> 7.31 - 7.32 -#include "block_file_accessor.h" 7.33 - 7.34 - 7.35 - 7.36 -BlockFileAccessor::BlockFileAccessor(const char *path, fileid_t fileid) 7.37 -: Accessor(fileid) 7.38 -{ 7.39 - /* Obtain the size of the file. */ 7.40 - 7.41 - struct stat buf; 7.42 - 7.43 - if (stat(path, &buf)) 7.44 - { 7.45 - _size = 0; 7.46 - return; 7.47 - } 7.48 - 7.49 - /* Allocate memory. */ 7.50 - 7.51 - _size = buf.st_size; 7.52 - _data = (char *) malloc(_size); 7.53 - 7.54 - if (_data == NULL) 7.55 - return; 7.56 - 7.57 - /* Load the file into memory and initialise the size. */ 7.58 - 7.59 - FILE *fp = fopen(path, "r"); 7.60 - 7.61 - if (fp == NULL) 7.62 - { 7.63 - free(_data); 7.64 - return; 7.65 - } 7.66 - 7.67 - _size = fread(_data, sizeof(char), _size, fp); 7.68 - 7.69 - fclose(fp); 7.70 -} 7.71 - 7.72 -/* Update the size of the file. */ 7.73 - 7.74 -void BlockFileAccessor::set_size(offset_t size) 7.75 -{ 7.76 - void *new_data = realloc(_data, size); 7.77 - 7.78 - if (new_data != NULL) 7.79 - { 7.80 - _data = (char *) new_data; 7.81 - 7.82 - if (size > _size) 7.83 - memset(_data + _size, 0, size - _size); 7.84 - 7.85 - Accessor::set_size(size); 7.86 - } 7.87 -} 7.88 - 7.89 -/* Data transfer helper methods. */ 7.90 - 7.91 -/* Fill the populated portion of a flexpage. */ 7.92 - 7.93 -void BlockFileAccessor::fill_populated(Flexpage *flexpage) 7.94 -{ 7.95 - offset_t filepos = flexpage->base_offset; 7.96 - offset_t addr = flexpage->base_addr; 7.97 - offset_t populated_size = std::min(flexpage->size, _size - filepos); 7.98 - 7.99 - /* Tag the region with file state. */ 7.100 - 7.101 - flexpage->region->fill(fileid, filepos); 7.102 - 7.103 - /* Fill the region with file content. */ 7.104 - 7.105 - memcpy((void *) addr, _data + filepos, populated_size); 7.106 - 7.107 - /* Pad the flexpage with zero. */ 7.108 - 7.109 - if (populated_size < flexpage->size) 7.110 - memset((void *) (addr + populated_size), 0, flexpage->size - populated_size); 7.111 -} 7.112 - 7.113 -/* Flush the populated portion of a flexpage. */ 7.114 - 7.115 -void BlockFileAccessor::flush_populated(Flexpage *flexpage) 7.116 -{ 7.117 - offset_t filepos = flexpage->base_offset; 7.118 - offset_t addr = flexpage->base_addr; 7.119 - offset_t populated_size = std::min(flexpage->size, _size - filepos); 7.120 - 7.121 - /* Remove the file state tag from the region. */ 7.122 - 7.123 - flexpage->region->flush(); 7.124 - 7.125 - /* Copy the populated region to the block memory. */ 7.126 - 7.127 - memcpy((void *) (_data + filepos), (const void *) addr, populated_size); 7.128 -} 7.129 - 7.130 -// vim: tabstop=4 expandtab shiftwidth=4
8.1 --- a/files/block_file_accessor.h Tue Apr 13 00:03:18 2021 +0200 8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 8.3 @@ -1,48 +0,0 @@ 8.4 -/* 8.5 - * A file accessor employing a rewritable memory area. 8.6 - * 8.7 - * Copyright (C) 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 -#pragma once 8.26 - 8.27 -#include "accessor.h" 8.28 - 8.29 - 8.30 - 8.31 -/* A block file accessor, providing flexpages corresponding to the regions of 8.32 - loaded files. */ 8.33 - 8.34 -class BlockFileAccessor : public Accessor 8.35 -{ 8.36 -protected: 8.37 - char *_data; 8.38 - 8.39 - /* Data transfer helper methods. */ 8.40 - 8.41 - virtual void fill_populated(Flexpage *flexpage); 8.42 - 8.43 - virtual void flush_populated(Flexpage *flexpage); 8.44 - 8.45 -public: 8.46 - explicit BlockFileAccessor(const char *path, fileid_t fileid); 8.47 - 8.48 - virtual void set_size(offset_t size); 8.49 -}; 8.50 - 8.51 -// vim: tabstop=4 expandtab shiftwidth=4
9.1 --- a/files/block_file_opener.cc Tue Apr 13 00:03:18 2021 +0200 9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 9.3 @@ -1,37 +0,0 @@ 9.4 -/* 9.5 - * An opener for a file employing a rewritable memory area. 9.6 - * 9.7 - * Copyright (C) 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 "block_file_accessor.h" 9.26 -#include "block_file_opener.h" 9.27 - 9.28 -/* Return a new accessor for 'fileid'. */ 9.29 - 9.30 -Accessor *BlockFileOpener::make_accessor(fileid_t fileid) 9.31 -{ 9.32 - FilePaths::iterator found = _paths.find(fileid); 9.33 - 9.34 - if (found != _paths.end()) 9.35 - return new BlockFileAccessor(found->second, fileid); 9.36 - else 9.37 - return NULL; 9.38 -} 9.39 - 9.40 -// vim: tabstop=4 expandtab shiftwidth=4
10.1 --- a/files/block_file_opener.h Tue Apr 13 00:03:18 2021 +0200 10.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 10.3 @@ -1,44 +0,0 @@ 10.4 -/* 10.5 - * An opener for a file employing a rewritable memory area. 10.6 - * 10.7 - * Copyright (C) 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 -#pragma once 10.26 - 10.27 -#include "host_file_opener.h" 10.28 - 10.29 - 10.30 - 10.31 -/* Support for providing access to files. */ 10.32 - 10.33 -class BlockFileOpener : public HostFileOpener 10.34 -{ 10.35 -protected: 10.36 - /* Configurable methods. */ 10.37 - 10.38 - virtual Accessor *make_accessor(fileid_t fileid); 10.39 - 10.40 -public: 10.41 - explicit BlockFileOpener(Pages *pages) 10.42 - : HostFileOpener(pages) 10.43 - { 10.44 - } 10.45 -}; 10.46 - 10.47 -// vim: tabstop=4 expandtab shiftwidth=4
11.1 --- a/files/file_pager.cc Tue Apr 13 00:03:18 2021 +0200 11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 11.3 @@ -1,87 +0,0 @@ 11.4 -/* 11.5 - * File-specific pager functionality. 11.6 - * 11.7 - * Copyright (C) 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 "file_pager.h" 11.26 -#include "mapped_file_object_server.h" 11.27 - 11.28 - 11.29 - 11.30 -/* Initialise a pager for a file with a unique file identifier and shared page 11.31 - mapper for moderating access to loaded pages. */ 11.32 - 11.33 -FilePager::FilePager(fileid_t fileid, PageMapper *mapper, flags_t flags, 11.34 - FilePaging *paging) 11.35 -: Pager(mapper, flags), _paging(paging), fileid(fileid) 11.36 -{ 11.37 -} 11.38 - 11.39 -int FilePager::expected_items() 11.40 -{ 11.41 - return MappedFileObject_expected_items; 11.42 -} 11.43 - 11.44 -ipc_server_handler_type FilePager::handler() 11.45 -{ 11.46 - return (ipc_server_handler_type) handle_MappedFileObject; 11.47 -} 11.48 - 11.49 - 11.50 - 11.51 -/* Close the pager, removing the mapper from the paging registry if 11.52 - appropriate. */ 11.53 - 11.54 -void FilePager::close() 11.55 -{ 11.56 - _paging->detach_pager(fileid, _mapper); 11.57 -} 11.58 - 11.59 - 11.60 - 11.61 -/* File-specific operations. */ 11.62 - 11.63 -long FilePager::flush(offset_t populated_size, offset_t *size) 11.64 -{ 11.65 - return Pager::flush(populated_size, size); 11.66 -} 11.67 - 11.68 -long FilePager::resize(offset_t *size) 11.69 -{ 11.70 - return Pager::resize(size); 11.71 -} 11.72 - 11.73 -long FilePager::mmap(offset_t position, offset_t length, offset_t *start_pos, 11.74 - offset_t *end_pos, offset_t *size) 11.75 -{ 11.76 - /* Set the limits of the paged region. */ 11.77 - 11.78 - return Pager::mmap(position, length, start_pos, end_pos, size); 11.79 -} 11.80 - 11.81 - 11.82 - 11.83 -/* Generic pager operations. */ 11.84 - 11.85 -long FilePager::map(offset_t offset, address_t hot_spot, flags_t flags, l4_snd_fpage_t *region) 11.86 -{ 11.87 - return Pager::map(offset, hot_spot, flags, region); 11.88 -} 11.89 - 11.90 -// vim: tabstop=4 expandtab shiftwidth=4
12.1 --- a/files/file_pager.h Tue Apr 13 00:03:18 2021 +0200 12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 12.3 @@ -1,69 +0,0 @@ 12.4 -/* 12.5 - * File-specific pager functionality. 12.6 - * 12.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 12.8 - * 12.9 - * This program is free software; you can redistribute it and/or 12.10 - * modify it under the terms of the GNU General Public License as 12.11 - * published by the Free Software Foundation; either version 2 of 12.12 - * the License, or (at your option) any later version. 12.13 - * 12.14 - * This program is distributed in the hope that it will be useful, 12.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 12.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12.17 - * GNU General Public License for more details. 12.18 - * 12.19 - * You should have received a copy of the GNU General Public License 12.20 - * along with this program; if not, write to the Free Software 12.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 12.22 - * Boston, MA 02110-1301, USA 12.23 - */ 12.24 - 12.25 -#pragma once 12.26 - 12.27 -#include "mapped_file_object_interface.h" 12.28 -#include "pager.h" 12.29 -#include "file_paging.h" 12.30 - 12.31 - 12.32 - 12.33 -/* A pager abstraction for a file. */ 12.34 - 12.35 -class FilePager : public Pager, public MappedFileObject 12.36 -{ 12.37 -protected: 12.38 - FilePaging *_paging; 12.39 - 12.40 -public: 12.41 - fileid_t fileid; 12.42 - 12.43 - explicit FilePager(fileid_t fileid, PageMapper *mapper, flags_t flags, 12.44 - FilePaging *paging); 12.45 - 12.46 - virtual void close(); 12.47 - 12.48 - /* Server details. */ 12.49 - 12.50 - int expected_items(); 12.51 - 12.52 - ipc_server_handler_type handler(); 12.53 - 12.54 - void *interface() 12.55 - { return static_cast<MappedFileObject *>(this); } 12.56 - 12.57 - /* File methods. */ 12.58 - 12.59 - virtual long flush(offset_t populated_size, offset_t *size); 12.60 - 12.61 - virtual long resize(offset_t *size); 12.62 - 12.63 - /* Pager and mapped file methods. */ 12.64 - 12.65 - virtual long map(offset_t offset, address_t hot_spot, flags_t flags, 12.66 - l4_snd_fpage_t *region); 12.67 - 12.68 - virtual long mmap(offset_t position, offset_t length, offset_t *start_pos, 12.69 - offset_t *end_pos, offset_t *size); 12.70 -}; 12.71 - 12.72 -// vim: tabstop=4 expandtab shiftwidth=4
13.1 --- a/files/file_paging.cc Tue Apr 13 00:03:18 2021 +0200 13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 13.3 @@ -1,124 +0,0 @@ 13.4 -/* 13.5 - * General functionality supporting file paging. 13.6 - * 13.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 13.8 - * 13.9 - * This program is free software; you can redistribute it and/or 13.10 - * modify it under the terms of the GNU General Public License as 13.11 - * published by the Free Software Foundation; either version 2 of 13.12 - * the License, or (at your option) any later version. 13.13 - * 13.14 - * This program is distributed in the hope that it will be useful, 13.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13.17 - * GNU General Public License for more details. 13.18 - * 13.19 - * You should have received a copy of the GNU General Public License 13.20 - * along with this program; if not, write to the Free Software 13.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 13.22 - * Boston, MA 02110-1301, USA 13.23 - */ 13.24 - 13.25 -#include "file_pager.h" 13.26 -#include "file_paging.h" 13.27 - 13.28 -#include <systypes/fcntl.h> 13.29 - 13.30 - 13.31 - 13.32 -FilePaging::FilePaging(Pages *pages) 13.33 -: _pages(pages) 13.34 -{ 13.35 -} 13.36 - 13.37 - 13.38 - 13.39 -/* Return any registered page mapper for the given 'fileid' or NULL if no such 13.40 - mapper is registered. */ 13.41 - 13.42 -PageMapper *FilePaging::get(fileid_t fileid) 13.43 -{ 13.44 - FileMapping::iterator entry = _mappers.find(fileid); 13.45 - PageMapper *mapper; 13.46 - 13.47 - if (entry == _mappers.end()) 13.48 - mapper = NULL; 13.49 - else 13.50 - mapper = entry->second; 13.51 - 13.52 - return mapper; 13.53 -} 13.54 - 13.55 -/* Register a page 'mapper' for the given 'fileid'. */ 13.56 - 13.57 -void FilePaging::set(fileid_t fileid, PageMapper *mapper) 13.58 -{ 13.59 - FileMapping::iterator entry = _mappers.find(fileid); 13.60 - 13.61 - if (entry == _mappers.end()) 13.62 - _mappers[fileid] = mapper; 13.63 -} 13.64 - 13.65 - 13.66 - 13.67 -/* Convert opening flags to map-compatible paging flags. */ 13.68 - 13.69 -flags_t FilePaging::get_flags(flags_t flags) 13.70 -{ 13.71 - return flags & (O_WRONLY | O_RDWR) ? L4RE_DS_MAP_FLAG_RW : L4RE_DS_MAP_FLAG_RO; 13.72 -} 13.73 - 13.74 - 13.75 - 13.76 -/* Obtain a page mapper for the 'fileid' or register a new one in the 13.77 - paging object. */ 13.78 - 13.79 -PageMapper *FilePaging::get_mapper(fileid_t fileid) 13.80 -{ 13.81 - /* Obtain any registered page mapper. */ 13.82 - 13.83 - PageMapper *mapper = get(fileid); 13.84 - 13.85 - if (mapper != NULL) 13.86 - return mapper; 13.87 - 13.88 - /* Make an accessor and page mapper, registering the mapper. */ 13.89 - 13.90 - Accessor *accessor = make_accessor(fileid); 13.91 - mapper = new PageMapper(accessor, _pages); 13.92 - 13.93 - set(fileid, mapper); 13.94 - 13.95 - return mapper; 13.96 -} 13.97 - 13.98 - 13.99 - 13.100 -/* Return a pager initialised with a page mapper. */ 13.101 - 13.102 -Pager *FilePaging::get_pager(fileid_t fileid, flags_t flags) 13.103 -{ 13.104 - std::lock_guard<std::mutex> guard(_lock); 13.105 - 13.106 - /* Initialise the pager with the mapper and a reference to this object for 13.107 - closing the mapper and accessor. */ 13.108 - 13.109 - PageMapper *mapper = get_mapper(fileid); 13.110 - return new FilePager(fileid, mapper, flags, this); 13.111 -} 13.112 - 13.113 -/* Detach a pager, potentially removing its resources. */ 13.114 - 13.115 -void FilePaging::detach_pager(fileid_t fileid, PageMapper *mapper) 13.116 -{ 13.117 - std::lock_guard<std::mutex> guard(_lock); 13.118 - 13.119 - if (!mapper->detach()) 13.120 - { 13.121 - _mappers.erase(fileid); 13.122 - delete mapper->accessor(); 13.123 - delete mapper; 13.124 - } 13.125 -} 13.126 - 13.127 -// vim: tabstop=4 expandtab shiftwidth=4
14.1 --- a/files/file_paging.h Tue Apr 13 00:03:18 2021 +0200 14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 14.3 @@ -1,82 +0,0 @@ 14.4 -/* 14.5 - * General functionality supporting file paging. 14.6 - * 14.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 14.8 - * 14.9 - * This program is free software; you can redistribute it and/or 14.10 - * modify it under the terms of the GNU General Public License as 14.11 - * published by the Free Software Foundation; either version 2 of 14.12 - * the License, or (at your option) any later version. 14.13 - * 14.14 - * This program is distributed in the hope that it will be useful, 14.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 14.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14.17 - * GNU General Public License for more details. 14.18 - * 14.19 - * You should have received a copy of the GNU General Public License 14.20 - * along with this program; if not, write to the Free Software 14.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 14.22 - * Boston, MA 02110-1301, USA 14.23 - */ 14.24 - 14.25 -#pragma once 14.26 - 14.27 -#include <map> 14.28 -#include <mutex> 14.29 - 14.30 -#include "accessor.h" 14.31 -#include "pager.h" 14.32 -#include "page_mapper.h" 14.33 - 14.34 - 14.35 - 14.36 -/* Mapping type from accessors to page mappers. */ 14.37 - 14.38 -typedef std::map<fileid_t, PageMapper *> FileMapping; 14.39 -typedef std::pair<fileid_t, PageMapper *> FileMappingEntry; 14.40 - 14.41 - 14.42 - 14.43 -/* A registry of mappers for accessors. */ 14.44 - 14.45 -class FilePaging 14.46 -{ 14.47 -protected: 14.48 - Pages *_pages; 14.49 - 14.50 - FileMapping _mappers; 14.51 - std::mutex _lock; 14.52 - 14.53 - /* Pager initialisation methods. */ 14.54 - 14.55 - PageMapper *get_mapper(fileid_t fileid); 14.56 - 14.57 - Pager *get_pager(fileid_t fileid, flags_t flags); 14.58 - 14.59 - /* Configurable methods. */ 14.60 - 14.61 - virtual fileid_t get_fileid(const char *path) = 0; 14.62 - 14.63 - virtual flags_t get_flags(flags_t flags); 14.64 - 14.65 - virtual Accessor *make_accessor(fileid_t fileid) = 0; 14.66 - 14.67 - /* Mapper registry access. */ 14.68 - 14.69 - PageMapper *get(fileid_t fileid); 14.70 - 14.71 - void set(fileid_t fileid, PageMapper *mapper); 14.72 - 14.73 -public: 14.74 - explicit FilePaging(Pages *pages); 14.75 - 14.76 - virtual ~FilePaging() 14.77 - { 14.78 - } 14.79 - 14.80 - /* Methods for the pager. */ 14.81 - 14.82 - void detach_pager(fileid_t fileid, PageMapper *mapper); 14.83 -}; 14.84 - 14.85 -// vim: tabstop=4 expandtab shiftwidth=4
15.1 --- a/files/host_file_accessor.cc Tue Apr 13 00:03:18 2021 +0200 15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 15.3 @@ -1,85 +0,0 @@ 15.4 -/* 15.5 - * A file accessor employing a "host" file provided via the C library. 15.6 - * 15.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 15.8 - * 15.9 - * This program is free software; you can redistribute it and/or 15.10 - * modify it under the terms of the GNU General Public License as 15.11 - * published by the Free Software Foundation; either version 2 of 15.12 - * the License, or (at your option) any later version. 15.13 - * 15.14 - * This program is distributed in the hope that it will be useful, 15.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 15.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15.17 - * GNU General Public License for more details. 15.18 - * 15.19 - * You should have received a copy of the GNU General Public License 15.20 - * along with this program; if not, write to the Free Software 15.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 15.22 - * Boston, MA 02110-1301, USA 15.23 - */ 15.24 - 15.25 -#include <stdio.h> 15.26 -#include <string.h> 15.27 -#include <sys/types.h> 15.28 -#include <sys/stat.h> 15.29 - 15.30 -#include "host_file_accessor.h" 15.31 - 15.32 -HostFileAccessor::HostFileAccessor(const char *path, fileid_t fileid) 15.33 -: Accessor(fileid), _path(path) 15.34 -{ 15.35 - /* Initialise the size of the file. */ 15.36 - 15.37 - struct stat buf; 15.38 - 15.39 - if (!stat(_path, &buf)) 15.40 - _size = buf.st_size; 15.41 - else 15.42 - _size = 0; 15.43 -} 15.44 - 15.45 -/* Perform any closing operation on the file. */ 15.46 - 15.47 -void HostFileAccessor::close() 15.48 -{ 15.49 - fclose(_fp); 15.50 -} 15.51 - 15.52 -/* Perform any opening operation on the file. */ 15.53 - 15.54 -void HostFileAccessor::open() 15.55 -{ 15.56 - _fp = fopen(_path, "r"); 15.57 -} 15.58 - 15.59 -/* Data transfer helper methods. */ 15.60 - 15.61 -void HostFileAccessor::fill_populated(Flexpage *flexpage) 15.62 -{ 15.63 - offset_t filepos = flexpage->base_offset; 15.64 - offset_t addr = flexpage->base_addr; 15.65 - 15.66 - /* Seek to the offset in the file. */ 15.67 - 15.68 - fseek(_fp, filepos, SEEK_SET); 15.69 - 15.70 - /* Tag the region with file state. */ 15.71 - 15.72 - flexpage->region->fill(fileid, filepos); 15.73 - 15.74 - /* Fill the region with file content. */ 15.75 - 15.76 - size_t nread = fread((void *) addr, sizeof(char), flexpage->size, _fp); 15.77 - 15.78 - /* Pad the flexpage with zero. */ 15.79 - 15.80 - memset((void *) (addr + nread), 0, flexpage->size - nread); 15.81 -} 15.82 - 15.83 -void HostFileAccessor::flush_populated(Flexpage *flexpage) 15.84 -{ 15.85 - flexpage->region->flush(); 15.86 -} 15.87 - 15.88 -// vim: tabstop=4 expandtab shiftwidth=4
16.1 --- a/files/host_file_accessor.h Tue Apr 13 00:03:18 2021 +0200 16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 16.3 @@ -1,53 +0,0 @@ 16.4 -/* 16.5 - * A file accessor employing a "host" file provided via the C library. 16.6 - * 16.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 16.8 - * 16.9 - * This program is free software; you can redistribute it and/or 16.10 - * modify it under the terms of the GNU General Public License as 16.11 - * published by the Free Software Foundation; either version 2 of 16.12 - * the License, or (at your option) any later version. 16.13 - * 16.14 - * This program is distributed in the hope that it will be useful, 16.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 16.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16.17 - * GNU General Public License for more details. 16.18 - * 16.19 - * You should have received a copy of the GNU General Public License 16.20 - * along with this program; if not, write to the Free Software 16.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 16.22 - * Boston, MA 02110-1301, USA 16.23 - */ 16.24 - 16.25 -#pragma once 16.26 - 16.27 -#include <stdio.h> 16.28 - 16.29 -#include "accessor.h" 16.30 - 16.31 - 16.32 - 16.33 -/* A host filesystem file accessor, providing flexpages corresponding to file 16.34 - regions. */ 16.35 - 16.36 -class HostFileAccessor : public Accessor 16.37 -{ 16.38 -protected: 16.39 - const char *_path; 16.40 - FILE *_fp; 16.41 - 16.42 - /* Data transfer helper methods. */ 16.43 - 16.44 - virtual void fill_populated(Flexpage *flexpage); 16.45 - 16.46 - virtual void flush_populated(Flexpage *flexpage); 16.47 - 16.48 -public: 16.49 - explicit HostFileAccessor(const char *path, fileid_t fileid); 16.50 - 16.51 - virtual void close(); 16.52 - 16.53 - virtual void open(); 16.54 -}; 16.55 - 16.56 -// vim: tabstop=4 expandtab shiftwidth=4
17.1 --- a/files/host_file_opener.cc Tue Apr 13 00:03:18 2021 +0200 17.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 17.3 @@ -1,55 +0,0 @@ 17.4 -/* 17.5 - * An opener for a "host" file provided via the C library. 17.6 - * 17.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 17.8 - * 17.9 - * This program is free software; you can redistribute it and/or 17.10 - * modify it under the terms of the GNU General Public License as 17.11 - * published by the Free Software Foundation; either version 2 of 17.12 - * the License, or (at your option) any later version. 17.13 - * 17.14 - * This program is distributed in the hope that it will be useful, 17.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 17.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17.17 - * GNU General Public License for more details. 17.18 - * 17.19 - * You should have received a copy of the GNU General Public License 17.20 - * along with this program; if not, write to the Free Software 17.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17.22 - * Boston, MA 02110-1301, USA 17.23 - */ 17.24 - 17.25 -#include <sys/stat.h> 17.26 - 17.27 -#include "host_file_accessor.h" 17.28 -#include "host_file_opener.h" 17.29 - 17.30 -/* Return a file identifier for the given 'path'. */ 17.31 - 17.32 -fileid_t HostFileOpener::get_fileid(const char *path) 17.33 -{ 17.34 - struct stat statbuf; 17.35 - 17.36 - /* Obtain the inode number. 17.37 - NOTE: This does not handle errors! */ 17.38 - 17.39 - stat(path, &statbuf); 17.40 - 17.41 - _paths.insert(FilePathEntry(statbuf.st_ino, path)); 17.42 - 17.43 - return statbuf.st_ino; 17.44 -} 17.45 - 17.46 -/* Return a new accessor for 'fileid'. */ 17.47 - 17.48 -Accessor *HostFileOpener::make_accessor(fileid_t fileid) 17.49 -{ 17.50 - FilePaths::iterator found = _paths.find(fileid); 17.51 - 17.52 - if (found != _paths.end()) 17.53 - return new HostFileAccessor(found->second, fileid); 17.54 - else 17.55 - return NULL; 17.56 -} 17.57 - 17.58 -// vim: tabstop=4 expandtab shiftwidth=4
18.1 --- a/files/host_file_opener.h Tue Apr 13 00:03:18 2021 +0200 18.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 18.3 @@ -1,57 +0,0 @@ 18.4 -/* 18.5 - * An opener for a "host" file provided via the C library. 18.6 - * 18.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 18.8 - * 18.9 - * This program is free software; you can redistribute it and/or 18.10 - * modify it under the terms of the GNU General Public License as 18.11 - * published by the Free Software Foundation; either version 2 of 18.12 - * the License, or (at your option) any later version. 18.13 - * 18.14 - * This program is distributed in the hope that it will be useful, 18.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 18.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18.17 - * GNU General Public License for more details. 18.18 - * 18.19 - * You should have received a copy of the GNU General Public License 18.20 - * along with this program; if not, write to the Free Software 18.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 18.22 - * Boston, MA 02110-1301, USA 18.23 - */ 18.24 - 18.25 -#pragma once 18.26 - 18.27 -#include <map> 18.28 - 18.29 -#include "opener_resource.h" 18.30 - 18.31 - 18.32 - 18.33 -/* Collection types. */ 18.34 - 18.35 -typedef std::map<fileid_t, const char *> FilePaths; 18.36 -typedef std::pair<fileid_t, const char *> FilePathEntry; 18.37 - 18.38 - 18.39 - 18.40 -/* Support for providing access to files. */ 18.41 - 18.42 -class HostFileOpener : public OpenerResource 18.43 -{ 18.44 -protected: 18.45 - FilePaths _paths; 18.46 - 18.47 - /* Configurable methods. */ 18.48 - 18.49 - virtual fileid_t get_fileid(const char *path); 18.50 - 18.51 - virtual Accessor *make_accessor(fileid_t fileid); 18.52 - 18.53 -public: 18.54 - explicit HostFileOpener(Pages *pages) 18.55 - : OpenerResource(pages) 18.56 - { 18.57 - } 18.58 -}; 18.59 - 18.60 -// vim: tabstop=4 expandtab shiftwidth=4
19.1 --- a/files/opener_context_resource.cc Tue Apr 13 00:03:18 2021 +0200 19.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 19.3 @@ -1,96 +0,0 @@ 19.4 -/* 19.5 - * A context resource offering support for opening files. 19.6 - * 19.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 19.8 - * 19.9 - * This program is free software; you can redistribute it and/or 19.10 - * modify it under the terms of the GNU General Public License as 19.11 - * published by the Free Software Foundation; either version 2 of 19.12 - * the License, or (at your option) any later version. 19.13 - * 19.14 - * This program is distributed in the hope that it will be useful, 19.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 19.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19.17 - * GNU General Public License for more details. 19.18 - * 19.19 - * You should have received a copy of the GNU General Public License 19.20 - * along with this program; if not, write to the Free Software 19.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19.22 - * Boston, MA 02110-1301, USA 19.23 - */ 19.24 - 19.25 -#include "opener_context_resource.h" 19.26 -#include "opener_context_object_server.h" 19.27 -#include "opener_resource.h" 19.28 -#include "resource_server.h" 19.29 - 19.30 -#include <string.h> 19.31 - 19.32 - 19.33 - 19.34 -/* Support for providing access to files. */ 19.35 - 19.36 -OpenerContextResource::OpenerContextResource(OpenerResource *opener, Memory *memory) 19.37 -: SimplePager(memory), _opener(opener) 19.38 -{ 19.39 -} 19.40 - 19.41 -int OpenerContextResource::expected_items() 19.42 -{ 19.43 - return OpenerContextObject_expected_items; 19.44 -} 19.45 - 19.46 -ipc_server_handler_type OpenerContextResource::handler() 19.47 -{ 19.48 - return (ipc_server_handler_type) handle_OpenerContextObject; 19.49 -} 19.50 - 19.51 - 19.52 - 19.53 -/* Data access methods. */ 19.54 - 19.55 -char *OpenerContextResource::get_path() 19.56 -{ 19.57 - char *buffer = _region->read(); 19.58 - offset_t size = _region->size(); 19.59 - 19.60 - /* Confine the path to the limit of the buffer. */ 19.61 - 19.62 - if ((buffer != NULL) && (strnlen(buffer, size) < size)) 19.63 - return buffer; 19.64 - else 19.65 - return NULL; 19.66 -} 19.67 - 19.68 - 19.69 - 19.70 -/* Opener context interface methods. */ 19.71 - 19.72 -long OpenerContextResource::open(flags_t flags, offset_t *size, l4_cap_idx_t *file) 19.73 -{ 19.74 - char *path = get_path(); 19.75 - 19.76 - if (path == NULL) 19.77 - return -L4_EINVAL; 19.78 - 19.79 - Pager *pager = _opener->open(path, flags); 19.80 - 19.81 - /* Complete the initialisation and start a server in a new thread. 19.82 - If the thread does not start, the resource should be finalised. */ 19.83 - 19.84 - ResourceServer server(pager); 19.85 - long err = server.start_thread(); 19.86 - 19.87 - if (!err) 19.88 - { 19.89 - /* Return the file size. */ 19.90 - /* Return the server capability to the caller. */ 19.91 - 19.92 - *size = pager->get_data_size(); 19.93 - *file = server.config()->server; 19.94 - } 19.95 - 19.96 - return err; 19.97 -} 19.98 - 19.99 -// vim: tabstop=4 expandtab shiftwidth=4
20.1 --- a/files/opener_context_resource.h Tue Apr 13 00:03:18 2021 +0200 20.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 20.3 @@ -1,72 +0,0 @@ 20.4 -/* 20.5 - * A context resource offering support for opening files. 20.6 - * 20.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 20.8 - * 20.9 - * This program is free software; you can redistribute it and/or 20.10 - * modify it under the terms of the GNU General Public License as 20.11 - * published by the Free Software Foundation; either version 2 of 20.12 - * the License, or (at your option) any later version. 20.13 - * 20.14 - * This program is distributed in the hope that it will be useful, 20.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 20.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20.17 - * GNU General Public License for more details. 20.18 - * 20.19 - * You should have received a copy of the GNU General Public License 20.20 - * along with this program; if not, write to the Free Software 20.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 20.22 - * Boston, MA 02110-1301, USA 20.23 - */ 20.24 - 20.25 -#pragma once 20.26 - 20.27 -#include "opener_context_object_interface.h" 20.28 -#include "simple_pager.h" 20.29 - 20.30 - 20.31 - 20.32 -/* Forward declaration. */ 20.33 - 20.34 -class OpenerResource; 20.35 - 20.36 - 20.37 - 20.38 -/* Support for indicating files to be opened. */ 20.39 - 20.40 -class OpenerContextResource : public SimplePager, public OpenerContextObject 20.41 -{ 20.42 -protected: 20.43 - OpenerResource *_opener; 20.44 - 20.45 -public: 20.46 - explicit OpenerContextResource(OpenerResource *opener, Memory *memory=NULL); 20.47 - 20.48 - /* Server details. */ 20.49 - 20.50 - int expected_items(); 20.51 - 20.52 - ipc_server_handler_type handler(); 20.53 - 20.54 - void *interface() 20.55 - { return static_cast<OpenerContextObject *>(this); } 20.56 - 20.57 - /* Data access methods. */ 20.58 - 20.59 - char *get_path(); 20.60 - 20.61 - /* Opener context interface methods. */ 20.62 - 20.63 - long open(flags_t flags, offset_t *size, l4_cap_idx_t *file); 20.64 - 20.65 - /* Pager/dataspace methods. */ 20.66 - 20.67 - long map(unsigned long offset, address_t hot_spot, flags_t flags, 20.68 - l4_snd_fpage_t *region) 20.69 - { return SimplePager::map(offset, hot_spot, flags, region); } 20.70 - 20.71 - long info(unsigned long *size, unsigned long *flags) 20.72 - { return SimplePager::info(size, flags); } 20.73 -}; 20.74 - 20.75 -// vim: tabstop=4 expandtab shiftwidth=4
21.1 --- a/files/opener_resource.cc Tue Apr 13 00:03:18 2021 +0200 21.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 21.3 @@ -1,79 +0,0 @@ 21.4 -/* 21.5 - * A resource offering support for creating contexts and opening files. 21.6 - * 21.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 21.8 - * 21.9 - * This program is free software; you can redistribute it and/or 21.10 - * modify it under the terms of the GNU General Public License as 21.11 - * published by the Free Software Foundation; either version 2 of 21.12 - * the License, or (at your option) any later version. 21.13 - * 21.14 - * This program is distributed in the hope that it will be useful, 21.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 21.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21.17 - * GNU General Public License for more details. 21.18 - * 21.19 - * You should have received a copy of the GNU General Public License 21.20 - * along with this program; if not, write to the Free Software 21.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 21.22 - * Boston, MA 02110-1301, USA 21.23 - */ 21.24 - 21.25 -#include "opener_server.h" 21.26 -#include "opener_resource.h" 21.27 -#include "resource_server.h" 21.28 - 21.29 -/* Support for providing access to files. */ 21.30 - 21.31 -OpenerResource::OpenerResource(Pages *pages) 21.32 -: FilePaging(pages) 21.33 -{ 21.34 -} 21.35 - 21.36 -int OpenerResource::expected_items() 21.37 -{ 21.38 - return Opener_expected_items; 21.39 -} 21.40 - 21.41 -ipc_server_handler_type OpenerResource::handler() 21.42 -{ 21.43 - return (ipc_server_handler_type) handle_Opener; 21.44 -} 21.45 - 21.46 - 21.47 - 21.48 -/* Return a pager object for the given path and flags. */ 21.49 - 21.50 -Pager *OpenerResource::open(const char *path, flags_t flags) 21.51 -{ 21.52 - fileid_t fileid = get_fileid(path); 21.53 - 21.54 - if (fileid == FILEID_INVALID) 21.55 - return NULL; 21.56 - 21.57 - return get_pager(fileid, get_flags(flags)); 21.58 -} 21.59 - 21.60 - 21.61 - 21.62 -/* Opener interface methods. */ 21.63 - 21.64 -long OpenerResource::context(l4_cap_idx_t *context) 21.65 -{ 21.66 - OpenerContextResource *resource = new OpenerContextResource(this); 21.67 - 21.68 - /* Complete the initialisation and start a server in a new thread. 21.69 - If the thread does not start, the resource should be finalised. */ 21.70 - 21.71 - ResourceServer server(resource); 21.72 - long err = server.start_thread(); 21.73 - 21.74 - /* Return the server capability to the caller. */ 21.75 - 21.76 - if (!err) 21.77 - *context = server.config()->server; 21.78 - 21.79 - return err; 21.80 -} 21.81 - 21.82 -// vim: tabstop=4 expandtab shiftwidth=4
22.1 --- a/files/opener_resource.h Tue Apr 13 00:03:18 2021 +0200 22.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 22.3 @@ -1,59 +0,0 @@ 22.4 -/* 22.5 - * A resource offering support for creating contexts and opening files. 22.6 - * 22.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 22.8 - * 22.9 - * This program is free software; you can redistribute it and/or 22.10 - * modify it under the terms of the GNU General Public License as 22.11 - * published by the Free Software Foundation; either version 2 of 22.12 - * the License, or (at your option) any later version. 22.13 - * 22.14 - * This program is distributed in the hope that it will be useful, 22.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 22.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22.17 - * GNU General Public License for more details. 22.18 - * 22.19 - * You should have received a copy of the GNU General Public License 22.20 - * along with this program; if not, write to the Free Software 22.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 22.22 - * Boston, MA 02110-1301, USA 22.23 - */ 22.24 - 22.25 -#pragma once 22.26 - 22.27 -#include <l4/sys/ipc.h> 22.28 - 22.29 -#include "file_paging.h" 22.30 -#include "opener_context_resource.h" 22.31 -#include "opener_interface.h" 22.32 -#include "pages.h" 22.33 -#include "resource.h" 22.34 - 22.35 - 22.36 - 22.37 -/* Support for providing access to files. */ 22.38 - 22.39 -class OpenerResource : public Resource, public FilePaging, public Opener 22.40 -{ 22.41 -public: 22.42 - explicit OpenerResource(Pages *pages); 22.43 - 22.44 - /* Server details. */ 22.45 - 22.46 - int expected_items(); 22.47 - 22.48 - ipc_server_handler_type handler(); 22.49 - 22.50 - void *interface() 22.51 - { return static_cast<Opener *>(this); } 22.52 - 22.53 - /* Direct access methods. */ 22.54 - 22.55 - Pager *open(const char *path, flags_t flags); 22.56 - 22.57 - /* Opener interface methods. */ 22.58 - 22.59 - long context(l4_cap_idx_t *context); 22.60 -}; 22.61 - 22.62 -// vim: tabstop=4 expandtab shiftwidth=4
23.1 --- a/files/test_file_accessor.cc Tue Apr 13 00:03:18 2021 +0200 23.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 23.3 @@ -1,72 +0,0 @@ 23.4 -/* 23.5 - * A test accessor producing generated content. 23.6 - * 23.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 23.8 - * 23.9 - * This program is free software; you can redistribute it and/or 23.10 - * modify it under the terms of the GNU General Public License as 23.11 - * published by the Free Software Foundation; either version 2 of 23.12 - * the License, or (at your option) any later version. 23.13 - * 23.14 - * This program is distributed in the hope that it will be useful, 23.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 23.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23.17 - * GNU General Public License for more details. 23.18 - * 23.19 - * You should have received a copy of the GNU General Public License 23.20 - * along with this program; if not, write to the Free Software 23.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 23.22 - * Boston, MA 02110-1301, USA 23.23 - */ 23.24 - 23.25 -#include <stdio.h> 23.26 -#include <string.h> 23.27 - 23.28 -#include "test_file_accessor.h" 23.29 - 23.30 -TestFileAccessor::TestFileAccessor(fileid_t fileid, offset_t size) 23.31 -: Accessor(fileid, size) 23.32 -{ 23.33 -} 23.34 - 23.35 -/* Data transfer helper methods. */ 23.36 - 23.37 -void TestFileAccessor::fill_populated(Flexpage *flexpage) 23.38 -{ 23.39 - Region *region = flexpage->region; 23.40 - offset_t filepos = flexpage->base_offset; 23.41 - 23.42 - /* Tag the region with file state. */ 23.43 - 23.44 - region->fill(fileid, filepos); 23.45 - 23.46 - /* Write some data to each page of the flexpage in each region. This 23.47 - allows each page to be tested regardless of how large each flexpage 23.48 - or region is. */ 23.49 - 23.50 - offset_t addr = flexpage->base_addr; 23.51 - offset_t limit = addr + flexpage->size; 23.52 - 23.53 - while (addr < limit) 23.54 - { 23.55 - /* Overwrite enough of any previous data to make the new data 23.56 - readable. */ 23.57 - 23.58 - char tag[32]; 23.59 - 23.60 - sprintf(tag, "%ld:%ld", fileid, filepos); 23.61 - 23.62 - memset((void *) addr, 0, strlen(tag) + 1); 23.63 - strcpy((char *) addr, tag); 23.64 - 23.65 - filepos += PAGE_SIZE; 23.66 - addr += PAGE_SIZE; 23.67 - } 23.68 -} 23.69 - 23.70 -void TestFileAccessor::flush_populated(Flexpage *flexpage) 23.71 -{ 23.72 - flexpage->region->flush(); 23.73 -} 23.74 - 23.75 -// vim: tabstop=4 expandtab shiftwidth=4
24.1 --- a/files/test_file_accessor.h Tue Apr 13 00:03:18 2021 +0200 24.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 24.3 @@ -1,44 +0,0 @@ 24.4 -/* 24.5 - * A test accessor producing generated content. 24.6 - * 24.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 24.8 - * 24.9 - * This program is free software; you can redistribute it and/or 24.10 - * modify it under the terms of the GNU General Public License as 24.11 - * published by the Free Software Foundation; either version 2 of 24.12 - * the License, or (at your option) any later version. 24.13 - * 24.14 - * This program is distributed in the hope that it will be useful, 24.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 24.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24.17 - * GNU General Public License for more details. 24.18 - * 24.19 - * You should have received a copy of the GNU General Public License 24.20 - * along with this program; if not, write to the Free Software 24.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 24.22 - * Boston, MA 02110-1301, USA 24.23 - */ 24.24 - 24.25 -#pragma once 24.26 - 24.27 -#include "accessor.h" 24.28 - 24.29 - 24.30 - 24.31 -/* A file accessor, providing flexpages corresponding to file regions. */ 24.32 - 24.33 -class TestFileAccessor : public Accessor 24.34 -{ 24.35 -protected: 24.36 - 24.37 - /* Data transfer helper methods. */ 24.38 - 24.39 - virtual void fill_populated(Flexpage *flexpage); 24.40 - 24.41 - virtual void flush_populated(Flexpage *flexpage); 24.42 - 24.43 -public: 24.44 - explicit TestFileAccessor(fileid_t fileid, offset_t size=0); 24.45 -}; 24.46 - 24.47 -// vim: tabstop=4 expandtab shiftwidth=4
25.1 --- a/files/test_file_opener.cc Tue Apr 13 00:03:18 2021 +0200 25.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 25.3 @@ -1,50 +0,0 @@ 25.4 -/* 25.5 - * An opener for a test file containing generated content. 25.6 - * 25.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 25.8 - * 25.9 - * This program is free software; you can redistribute it and/or 25.10 - * modify it under the terms of the GNU General Public License as 25.11 - * published by the Free Software Foundation; either version 2 of 25.12 - * the License, or (at your option) any later version. 25.13 - * 25.14 - * This program is distributed in the hope that it will be useful, 25.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 25.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25.17 - * GNU General Public License for more details. 25.18 - * 25.19 - * You should have received a copy of the GNU General Public License 25.20 - * along with this program; if not, write to the Free Software 25.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 25.22 - * Boston, MA 02110-1301, USA 25.23 - */ 25.24 - 25.25 -#include "test_file_accessor.h" 25.26 -#include "test_file_opener.h" 25.27 - 25.28 -#include <stdlib.h> 25.29 - 25.30 -/* Support for providing access to files. */ 25.31 - 25.32 -TestFileOpener::TestFileOpener(Pages *pages, offset_t file_size) 25.33 -: OpenerResource(pages), _file_size(file_size) 25.34 -{ 25.35 -} 25.36 - 25.37 -/* Return a file identifier for the given 'path'. */ 25.38 - 25.39 -fileid_t TestFileOpener::get_fileid(const char *path) 25.40 -{ 25.41 - /* NOTE: Just convert the path to a number. */ 25.42 - 25.43 - return atol(path); 25.44 -} 25.45 - 25.46 -/* Return a new accessor for 'fileid'. */ 25.47 - 25.48 -Accessor *TestFileOpener::make_accessor(fileid_t fileid) 25.49 -{ 25.50 - return new TestFileAccessor(fileid, _file_size); 25.51 -} 25.52 - 25.53 -// vim: tabstop=4 expandtab shiftwidth=4
26.1 --- a/files/test_file_opener.h Tue Apr 13 00:03:18 2021 +0200 26.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 26.3 @@ -1,45 +0,0 @@ 26.4 -/* 26.5 - * An opener for a test file containing generated content. 26.6 - * 26.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 26.8 - * 26.9 - * This program is free software; you can redistribute it and/or 26.10 - * modify it under the terms of the GNU General Public License as 26.11 - * published by the Free Software Foundation; either version 2 of 26.12 - * the License, or (at your option) any later version. 26.13 - * 26.14 - * This program is distributed in the hope that it will be useful, 26.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 26.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26.17 - * GNU General Public License for more details. 26.18 - * 26.19 - * You should have received a copy of the GNU General Public License 26.20 - * along with this program; if not, write to the Free Software 26.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 26.22 - * Boston, MA 02110-1301, USA 26.23 - */ 26.24 - 26.25 -#pragma once 26.26 - 26.27 -#include "opener_resource.h" 26.28 - 26.29 - 26.30 - 26.31 -/* Support for providing access to files. */ 26.32 - 26.33 -class TestFileOpener : public OpenerResource 26.34 -{ 26.35 -protected: 26.36 - offset_t _file_size; 26.37 - 26.38 - /* Configurable methods. */ 26.39 - 26.40 - virtual fileid_t get_fileid(const char *path); 26.41 - 26.42 - virtual Accessor *make_accessor(fileid_t fileid); 26.43 - 26.44 -public: 26.45 - explicit TestFileOpener(Pages *pages, offset_t file_size=0); 26.46 -}; 26.47 - 26.48 -// vim: tabstop=4 expandtab shiftwidth=4
27.1 --- a/generic/accessor.cc Tue Apr 13 00:03:18 2021 +0200 27.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 27.3 @@ -1,94 +0,0 @@ 27.4 -/* 27.5 - * Generic accessor functionality. 27.6 - * 27.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 27.8 - * 27.9 - * This program is free software; you can redistribute it and/or 27.10 - * modify it under the terms of the GNU General Public License as 27.11 - * published by the Free Software Foundation; either version 2 of 27.12 - * the License, or (at your option) any later version. 27.13 - * 27.14 - * This program is distributed in the hope that it will be useful, 27.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 27.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27.17 - * GNU General Public License for more details. 27.18 - * 27.19 - * You should have received a copy of the GNU General Public License 27.20 - * along with this program; if not, write to the Free Software 27.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 27.22 - * Boston, MA 02110-1301, USA 27.23 - */ 27.24 - 27.25 -#include "accessor.h" 27.26 - 27.27 -#include <string.h> 27.28 - 27.29 - 27.30 - 27.31 -Accessor::Accessor(fileid_t fileid, offset_t size) 27.32 -: _size(size), fileid(fileid) 27.33 -{ 27.34 -} 27.35 - 27.36 -/* Return the size of the file. */ 27.37 - 27.38 -offset_t Accessor::get_size() 27.39 -{ 27.40 - return _size; 27.41 -} 27.42 - 27.43 -/* Update the size of the file. */ 27.44 - 27.45 -void Accessor::set_size(offset_t size) 27.46 -{ 27.47 - _size = size; 27.48 -} 27.49 - 27.50 -/* Perform any closing operation on the file. */ 27.51 - 27.52 -void Accessor::close() 27.53 -{ 27.54 -} 27.55 - 27.56 -/* Perform any opening operation on the file. */ 27.57 - 27.58 -void Accessor::open() 27.59 -{ 27.60 -} 27.61 - 27.62 -/* Data transfer methods. */ 27.63 - 27.64 -void Accessor::fill(Flexpage *flexpage) 27.65 -{ 27.66 - /* Filling completely beyond the end of file should produce an empty 27.67 - flexpage. This could potentially be a shared read-only flexpage that 27.68 - would be replaced by an independent writable flexpage if ever written. */ 27.69 - 27.70 - if (flexpage->base_offset < _size) 27.71 - fill_populated(flexpage); 27.72 - else 27.73 - memset((void *) flexpage->base_addr, 0, flexpage->size); 27.74 -} 27.75 - 27.76 -void Accessor::flush(Flexpage *flexpage) 27.77 -{ 27.78 - /* Flushing completely beyond the end of file should discard the 27.79 - flexpage. */ 27.80 - 27.81 - if (flexpage->base_offset < _size) 27.82 - flush_populated(flexpage); 27.83 -} 27.84 - 27.85 -/* Data transfer helper methods. */ 27.86 - 27.87 -void Accessor::fill_populated(Flexpage *flexpage) 27.88 -{ 27.89 - (void) flexpage; 27.90 -} 27.91 - 27.92 -void Accessor::flush_populated(Flexpage *flexpage) 27.93 -{ 27.94 - (void) flexpage; 27.95 -} 27.96 - 27.97 -// vim: tabstop=4 expandtab shiftwidth=4
28.1 --- a/generic/accessor.h Tue Apr 13 00:03:18 2021 +0200 28.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 28.3 @@ -1,65 +0,0 @@ 28.4 -/* 28.5 - * Generic accessor functionality. 28.6 - * 28.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 28.8 - * 28.9 - * This program is free software; you can redistribute it and/or 28.10 - * modify it under the terms of the GNU General Public License as 28.11 - * published by the Free Software Foundation; either version 2 of 28.12 - * the License, or (at your option) any later version. 28.13 - * 28.14 - * This program is distributed in the hope that it will be useful, 28.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 28.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28.17 - * GNU General Public License for more details. 28.18 - * 28.19 - * You should have received a copy of the GNU General Public License 28.20 - * along with this program; if not, write to the Free Software 28.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 28.22 - * Boston, MA 02110-1301, USA 28.23 - */ 28.24 - 28.25 -#pragma once 28.26 - 28.27 -#include "flexpage.h" 28.28 - 28.29 - 28.30 - 28.31 -/* A file accessor, providing flexpages corresponding to file regions. */ 28.32 - 28.33 -class Accessor 28.34 -{ 28.35 -protected: 28.36 - offset_t _size; 28.37 - 28.38 - /* Data transfer helper methods. */ 28.39 - 28.40 - virtual void fill_populated(Flexpage *flexpage); 28.41 - 28.42 - virtual void flush_populated(Flexpage *flexpage); 28.43 - 28.44 -public: 28.45 - fileid_t fileid; 28.46 - 28.47 - explicit Accessor(fileid_t fileid, offset_t size=0); 28.48 - 28.49 - virtual ~Accessor() 28.50 - { 28.51 - } 28.52 - 28.53 - virtual offset_t get_size(); 28.54 - 28.55 - virtual void set_size(offset_t size); 28.56 - 28.57 - virtual void close(); 28.58 - 28.59 - virtual void open(); 28.60 - 28.61 - /* Data transfer methods. */ 28.62 - 28.63 - virtual void fill(Flexpage *flexpage); 28.64 - 28.65 - virtual void flush(Flexpage *flexpage); 28.66 -}; 28.67 - 28.68 -// vim: tabstop=4 expandtab shiftwidth=4
29.1 --- a/generic/pager.cc Tue Apr 13 00:03:18 2021 +0200 29.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 29.3 @@ -1,128 +0,0 @@ 29.4 -/* 29.5 - * Generic pager functionality. 29.6 - * 29.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 29.8 - * 29.9 - * This program is free software; you can redistribute it and/or 29.10 - * modify it under the terms of the GNU General Public License as 29.11 - * published by the Free Software Foundation; either version 2 of 29.12 - * the License, or (at your option) any later version. 29.13 - * 29.14 - * This program is distributed in the hope that it will be useful, 29.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 29.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 29.17 - * GNU General Public License for more details. 29.18 - * 29.19 - * You should have received a copy of the GNU General Public License 29.20 - * along with this program; if not, write to the Free Software 29.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 29.22 - * Boston, MA 02110-1301, USA 29.23 - */ 29.24 - 29.25 -#include "dataspace_server.h" 29.26 -#include "ipc.h" 29.27 -#include "pager.h" 29.28 - 29.29 - 29.30 - 29.31 -/* Initialise the pager with a page mapper and the given flags controlling 29.32 - access to a file. */ 29.33 - 29.34 -Pager::Pager(PageMapper *mapper, flags_t flags) 29.35 -: _start(0), _size(0), _mapper(mapper), _flags(flags) 29.36 -{ 29.37 - /* Some pagers may not be initialised with a mapper. */ 29.38 - 29.39 - if (_mapper != NULL) 29.40 - _mapper->attach(); 29.41 -} 29.42 - 29.43 -/* Close the pager. */ 29.44 - 29.45 -void Pager::close() 29.46 -{ 29.47 - if (_mapper != NULL) 29.48 - _mapper->detach(); 29.49 -} 29.50 - 29.51 -/* Flush data to the file. */ 29.52 - 29.53 -long Pager::flush(offset_t populated_size, offset_t *size) 29.54 -{ 29.55 - _mapper->flush_all(_start, populated_size); 29.56 - 29.57 - *size = _mapper->get_data_size(); 29.58 - return L4_EOK; 29.59 -} 29.60 - 29.61 -/* Resize the underlying file. */ 29.62 - 29.63 -long Pager::resize(offset_t *size) 29.64 -{ 29.65 - _mapper->set_data_size(*size); 29.66 - 29.67 - *size = _mapper->get_data_size(); 29.68 - return L4_EOK; 29.69 -} 29.70 - 29.71 -/* Expose a region of the file. */ 29.72 - 29.73 -long Pager::mmap(offset_t position, offset_t length, offset_t *start_pos, 29.74 - offset_t *end_pos, offset_t *size) 29.75 -{ 29.76 - /* Define region characteristics. */ 29.77 - 29.78 - _start = trunc(position, PAGE_SIZE); 29.79 - _size = round(position + length, PAGE_SIZE) - _start; 29.80 - 29.81 - /* Return the start and end positions plus populated extent. */ 29.82 - 29.83 - *start_pos = _start; 29.84 - *end_pos = _start + _size; 29.85 - *size = _mapper->get_data_size(); 29.86 - 29.87 - return L4_EOK; 29.88 -} 29.89 - 29.90 -/* Map a flexpage corresponding to the dataspace 'offset' involving a 'hot_spot' 29.91 - (flexpage offset). */ 29.92 - 29.93 -long Pager::map(offset_t offset, address_t hot_spot, flags_t flags, 29.94 - l4_snd_fpage_t *region) 29.95 -{ 29.96 - offset_t file_offset = _start + offset; 29.97 - offset_t max_offset = _start + _size; 29.98 - 29.99 - /* Prevent access beyond that defined by the pager. */ 29.100 - 29.101 - if (flags & ~_flags) 29.102 - return -L4_EACCESS; 29.103 - 29.104 - Flexpage *flexpage = _mapper->get(file_offset, flags); 29.105 - 29.106 - /* Issue the flexpage via the IPC system. */ 29.107 - 29.108 - long err = ipc_prepare_flexpage(flexpage, file_offset, max_offset, hot_spot, 29.109 - flags, region); 29.110 - 29.111 - if (!err) 29.112 - err = complete_Dataspace_map(*region); 29.113 - 29.114 - /* After the flexpage is issued, it is queued for future reuse. */ 29.115 - 29.116 - _mapper->queue(flexpage); 29.117 - 29.118 - if (err) 29.119 - return err; 29.120 - 29.121 - return IPC_MESSAGE_SENT; 29.122 -} 29.123 - 29.124 -/* Return the total size of the data. */ 29.125 - 29.126 -offset_t Pager::get_data_size() 29.127 -{ 29.128 - return _mapper->get_data_size(); 29.129 -} 29.130 - 29.131 -// vim: tabstop=4 expandtab shiftwidth=4
30.1 --- a/generic/pager.h Tue Apr 13 00:03:18 2021 +0200 30.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 30.3 @@ -1,66 +0,0 @@ 30.4 -/* 30.5 - * Generic pager functionality. 30.6 - * 30.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 30.8 - * 30.9 - * This program is free software; you can redistribute it and/or 30.10 - * modify it under the terms of the GNU General Public License as 30.11 - * published by the Free Software Foundation; either version 2 of 30.12 - * the License, or (at your option) any later version. 30.13 - * 30.14 - * This program is distributed in the hope that it will be useful, 30.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 30.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 30.17 - * GNU General Public License for more details. 30.18 - * 30.19 - * You should have received a copy of the GNU General Public License 30.20 - * along with this program; if not, write to the Free Software 30.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 30.22 - * Boston, MA 02110-1301, USA 30.23 - */ 30.24 - 30.25 -#pragma once 30.26 - 30.27 -#include <systypes/base.h> 30.28 - 30.29 -#include "page_mapper.h" 30.30 -#include "resource.h" 30.31 - 30.32 - 30.33 - 30.34 -/* A pager exposing a dataspace. */ 30.35 - 30.36 -class Pager : public Resource 30.37 -{ 30.38 -protected: 30.39 - offset_t _start, _size; 30.40 - PageMapper *_mapper; 30.41 - flags_t _flags; 30.42 - 30.43 -public: 30.44 - explicit Pager(PageMapper *mapper, flags_t flags); 30.45 - 30.46 - virtual void close(); 30.47 - 30.48 - /* Paging methods. */ 30.49 - 30.50 - virtual long map(offset_t offset, address_t hot_spot, flags_t flags, 30.51 - l4_snd_fpage_t *region); 30.52 - 30.53 - /* Limit methods. */ 30.54 - 30.55 - offset_t get_data_size(); 30.56 - 30.57 - /* File methods. */ 30.58 - 30.59 - virtual long flush(offset_t populated_size, offset_t *size); 30.60 - 30.61 - virtual long resize(offset_t *size); 30.62 - 30.63 - /* Mapped file methods. */ 30.64 - 30.65 - virtual long mmap(offset_t position, offset_t length, offset_t *start_pos, 30.66 - offset_t *end_pos, offset_t *size); 30.67 -}; 30.68 - 30.69 -// vim: tabstop=4 expandtab shiftwidth=4
31.1 --- a/generic/resource.h Tue Apr 13 00:03:18 2021 +0200 31.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 31.3 @@ -1,56 +0,0 @@ 31.4 -/* 31.5 - * Common resource classes and functions. 31.6 - * 31.7 - * Copyright (C) 2018, 2019, 2020 Paul Boddie <paul@boddie.org.uk> 31.8 - * 31.9 - * This program is free software; you can redistribute it and/or 31.10 - * modify it under the terms of the GNU General Public License as 31.11 - * published by the Free Software Foundation; either version 2 of 31.12 - * the License, or (at your option) any later version. 31.13 - * 31.14 - * This program is distributed in the hope that it will be useful, 31.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 31.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 31.17 - * GNU General Public License for more details. 31.18 - * 31.19 - * You should have received a copy of the GNU General Public License 31.20 - * along with this program; if not, write to the Free Software 31.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 31.22 - * Boston, MA 02110-1301, USA 31.23 - */ 31.24 - 31.25 -#pragma once 31.26 - 31.27 -#include <ipc/server.h> 31.28 - 31.29 - 31.30 - 31.31 -/* A generic class for an object potentially needing to be closed after use. */ 31.32 - 31.33 -class Resource 31.34 -{ 31.35 -public: 31.36 - virtual ~Resource() 31.37 - { 31.38 - } 31.39 - 31.40 - /* Server details. */ 31.41 - 31.42 - virtual int expected_items() = 0; 31.43 - 31.44 - virtual ipc_server_handler_type handler() = 0; 31.45 - 31.46 - virtual void *interface() = 0; 31.47 - 31.48 - /* Deallocation of resources. */ 31.49 - 31.50 - virtual void close() 31.51 - { 31.52 - } 31.53 - 31.54 - /* Activation. */ 31.55 - 31.56 - virtual void activate() 31.57 - { 31.58 - } 31.59 -};
32.1 --- a/generic/resource_server.cc Tue Apr 13 00:03:18 2021 +0200 32.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 32.3 @@ -1,131 +0,0 @@ 32.4 -/* 32.5 - * Resource server functionality. 32.6 - * 32.7 - * Copyright (C) 2018, 2019, 2020, 2021 Paul Boddie <paul@boddie.org.uk> 32.8 - * 32.9 - * This program is free software; you can redistribute it and/or 32.10 - * modify it under the terms of the GNU General Public License as 32.11 - * published by the Free Software Foundation; either version 2 of 32.12 - * the License, or (at your option) any later version. 32.13 - * 32.14 - * This program is distributed in the hope that it will be useful, 32.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 32.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 32.17 - * GNU General Public License for more details. 32.18 - * 32.19 - * You should have received a copy of the GNU General Public License 32.20 - * along with this program; if not, write to the Free Software 32.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 32.22 - * Boston, MA 02110-1301, USA 32.23 - */ 32.24 - 32.25 -#include <l4/sys/types.h> 32.26 - 32.27 -#include <pthread-l4.h> 32.28 -#include <pthread.h> 32.29 - 32.30 -#include "resource_server.h" 32.31 - 32.32 - 32.33 - 32.34 -/* Convenience server methods. */ 32.35 - 32.36 -/* Bind to a named IPC gate capability. */ 32.37 - 32.38 -long ResourceServer::bind(const char *name) 32.39 -{ 32.40 - return ipc_server_bind(name, (l4_umword_t) _resource, &_config->server); 32.41 -} 32.42 - 32.43 -/* Start in the same thread with no deletion notifications or finalisation. */ 32.44 - 32.45 -long ResourceServer::start() 32.46 -{ 32.47 - resource_init_config(_config, _resource); 32.48 - _config->thread = pthread_l4_cap(pthread_self()); 32.49 - return resource_start_config(_config, _resource); 32.50 -} 32.51 - 32.52 -/* Start a new thread with deletion notifications and finalisation. */ 32.53 - 32.54 -long ResourceServer::start_thread() 32.55 -{ 32.56 - pthread_t thread; 32.57 - pthread_attr_t attr; 32.58 - long err; 32.59 - 32.60 - pthread_attr_init(&attr); 32.61 - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 32.62 - 32.63 - resource_init_config(_config, _resource); 32.64 - 32.65 - err = pthread_create(&thread, &attr, ipc_server_start_mainloop, _config); 32.66 - if (err) 32.67 - return err; 32.68 - 32.69 - resource_set_config_threaded(_config, pthread_l4_cap(thread), 1); 32.70 - 32.71 - return resource_start_config(_config, _resource); 32.72 -} 32.73 - 32.74 - 32.75 - 32.76 -/* Initialise a server configuration for a resource. */ 32.77 - 32.78 -void resource_init_config(ipc_server_config_type *config, Resource *resource) 32.79 -{ 32.80 - config->handler_obj = resource->interface(); 32.81 - config->finaliser_obj = resource; 32.82 - config->expected_items = resource->expected_items(); 32.83 - config->handler = resource->handler(); 32.84 -} 32.85 - 32.86 -/* Set a configuration to be threaded. */ 32.87 - 32.88 -void resource_set_config_threaded(ipc_server_config_type *config, 32.89 - l4_cap_idx_t thread, int new_thread) 32.90 -{ 32.91 - config->finaliser = resource_thread_finaliser; 32.92 - config->new_thread = new_thread; 32.93 - config->thread = thread; 32.94 - config->notifications = 1; 32.95 -} 32.96 - 32.97 -/* Activate a resource and start a server for it. */ 32.98 - 32.99 -long resource_start_config(ipc_server_config_type *config, Resource *resource) 32.100 -{ 32.101 - resource->activate(); 32.102 - long err = ipc_server_start_config(config); 32.103 - 32.104 - /* Discard any server resources if starting it failed. */ 32.105 - 32.106 - if (err) 32.107 - { 32.108 - ipc_server_finalise_config(config); 32.109 - ipc_server_discard_thread(config); 32.110 - } 32.111 - 32.112 - return err; 32.113 -} 32.114 - 32.115 - 32.116 - 32.117 -/* A finaliser for exposed resources. */ 32.118 - 32.119 -void resource_thread_finaliser(ipc_server_config_type *config) 32.120 -{ 32.121 - Resource *resource = reinterpret_cast<Resource *>(config->finaliser_obj); 32.122 - 32.123 - /* Close and delete the resource. */ 32.124 - 32.125 - resource->close(); 32.126 - delete resource; 32.127 - 32.128 - /* Release the capabilities. */ 32.129 - 32.130 - ipc_server_finalise_config(config); 32.131 - delete config; 32.132 -} 32.133 - 32.134 -// vim: tabstop=2 expandtab shiftwidth=2
33.1 --- a/generic/resource_server.h Tue Apr 13 00:03:18 2021 +0200 33.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 33.3 @@ -1,76 +0,0 @@ 33.4 -/* 33.5 - * Common resource server functions. 33.6 - * 33.7 - * Copyright (C) 2018, 2019, 2020 Paul Boddie <paul@boddie.org.uk> 33.8 - * 33.9 - * This program is free software; you can redistribute it and/or 33.10 - * modify it under the terms of the GNU General Public License as 33.11 - * published by the Free Software Foundation; either version 2 of 33.12 - * the License, or (at your option) any later version. 33.13 - * 33.14 - * This program is distributed in the hope that it will be useful, 33.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 33.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33.17 - * GNU General Public License for more details. 33.18 - * 33.19 - * You should have received a copy of the GNU General Public License 33.20 - * along with this program; if not, write to the Free Software 33.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 33.22 - * Boston, MA 02110-1301, USA 33.23 - */ 33.24 - 33.25 -#pragma once 33.26 - 33.27 -#include "resource.h" 33.28 -#include <ipc/server.h> 33.29 - 33.30 - 33.31 - 33.32 -/* Convenience abstraction for blocking servers. */ 33.33 - 33.34 -class ResourceServer 33.35 -{ 33.36 -protected: 33.37 - Resource *_resource; 33.38 - ipc_server_config_type *_config; 33.39 - 33.40 -public: 33.41 - explicit ResourceServer(Resource *resource) 33.42 - : _resource(resource) 33.43 - { 33.44 - _config = new ipc_server_config_type; 33.45 - ipc_server_init_config(_config); 33.46 - } 33.47 - 33.48 - /* Access to configuration. */ 33.49 - 33.50 - ipc_server_config_type *config() 33.51 - { return _config; } 33.52 - 33.53 - /* Server IPC gate allocation. */ 33.54 - 33.55 - long bind(const char *name); 33.56 - 33.57 - /* Server initiation. */ 33.58 - 33.59 - long start(); 33.60 - 33.61 - long start_thread(); 33.62 -}; 33.63 - 33.64 - 33.65 - 33.66 -/* Server initialisation. */ 33.67 - 33.68 -void resource_init_config(ipc_server_config_type *config, Resource *resource); 33.69 - 33.70 -void resource_set_config_threaded(ipc_server_config_type *config, 33.71 - l4_cap_idx_t thread, int new_thread); 33.72 - 33.73 -/* Server initiation. */ 33.74 - 33.75 -long resource_start_config(ipc_server_config_type *config, Resource *resource); 33.76 - 33.77 -/* Server finalisation. */ 33.78 - 33.79 -void resource_thread_finaliser(ipc_server_config_type *config);
34.1 --- a/generic/simple_pager.cc Tue Apr 13 00:03:18 2021 +0200 34.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 34.3 @@ -1,84 +0,0 @@ 34.4 -/* 34.5 - * A simple pager exposing a single memory region. 34.6 - * 34.7 - * Copyright (C) 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/c/dataspace.h> 34.26 - 34.27 -#include "dataspace_server.h" 34.28 -#include "memory_incremental.h" 34.29 -#include "ipc.h" 34.30 -#include "simple_pager.h" 34.31 - 34.32 - 34.33 - 34.34 -SimplePager::SimplePager(Memory *memory) 34.35 -{ 34.36 - if (memory == NULL) 34.37 - _memory = new MemoryIncremental(); 34.38 - else 34.39 - _memory = memory; 34.40 - 34.41 - _region = _memory->region(); 34.42 -} 34.43 - 34.44 -void SimplePager::close() 34.45 -{ 34.46 - if (_region != NULL) 34.47 - { 34.48 - _memory->release(_region); 34.49 - _region = NULL; 34.50 - } 34.51 -} 34.52 - 34.53 -/* Map a flexpage corresponding to the dataspace 'offset' involving a 'hot_spot' 34.54 - (flexpage offset). */ 34.55 - 34.56 -long SimplePager::map(offset_t offset, address_t hot_spot, flags_t flags, l4_snd_fpage_t *region) 34.57 -{ 34.58 - Flexpage flexpage(_region); 34.59 - 34.60 - flexpage.reset(offset); 34.61 - flexpage.upgrade(flags); 34.62 - 34.63 - /* Send the flexpage explicitly. */ 34.64 - 34.65 - long err = ipc_prepare_flexpage(&flexpage, offset, _region->size(), 34.66 - hot_spot, flags, region); 34.67 - 34.68 - if (err) 34.69 - return err; 34.70 - 34.71 - err = complete_Dataspace_map(*region); 34.72 - 34.73 - if (err) 34.74 - return err; 34.75 - 34.76 - return IPC_MESSAGE_SENT; 34.77 -} 34.78 - 34.79 -long SimplePager::info(offset_t *size, flags_t *flags) 34.80 -{ 34.81 - *size = _region->size(); 34.82 - *flags = L4_FPAGE_RW; 34.83 - 34.84 - return L4_EOK; 34.85 -} 34.86 - 34.87 -// vim: tabstop=4 expandtab shiftwidth=4
35.1 --- a/generic/simple_pager.h Tue Apr 13 00:03:18 2021 +0200 35.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 35.3 @@ -1,51 +0,0 @@ 35.4 -/* 35.5 - * A simple pager exposing a single memory region. 35.6 - * 35.7 - * Copyright (C) 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 -#pragma once 35.26 - 35.27 -#include "dataspace_interface.h" 35.28 -#include "flexpage.h" 35.29 -#include "memory.h" 35.30 -#include "resource.h" 35.31 - 35.32 - 35.33 - 35.34 -/* A simple pager exposing a single memory region as a dataspace. */ 35.35 - 35.36 -class SimplePager : public Dataspace, public Resource 35.37 -{ 35.38 -protected: 35.39 - Memory *_memory; 35.40 - Region *_region; 35.41 - 35.42 -public: 35.43 - explicit SimplePager(Memory *memory=NULL); 35.44 - 35.45 - void close(); 35.46 - 35.47 - /* Paging methods. */ 35.48 - 35.49 - long map(offset_t offset, address_t hot_spot, flags_t flags, l4_snd_fpage_t *region); 35.50 - 35.51 - long info(offset_t *size, flags_t *flags); 35.52 -}; 35.53 - 35.54 -// vim: tabstop=4 expandtab shiftwidth=4
36.1 --- a/generic/types.h Tue Apr 13 00:03:18 2021 +0200 36.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 36.3 @@ -1,32 +0,0 @@ 36.4 -/* 36.5 - * Miscellaneous types. 36.6 - * 36.7 - * Copyright (C) 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 -#pragma once 36.26 - 36.27 - 36.28 - 36.29 -/* File identification. */ 36.30 - 36.31 -typedef unsigned long fileid_t; 36.32 - 36.33 -#define FILEID_INVALID (~0UL) 36.34 - 36.35 -// vim: tabstop=4 expandtab shiftwidth=4
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/libfsclient/Control Thu Apr 15 23:15:17 2021 +0200 37.3 @@ -0,0 +1,3 @@ 37.4 +requires: libstdc++ libc libipc 37.5 +provides: libfsclient 37.6 +maintainer: paul@boddie.org.uk
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/libfsclient/Makefile Thu Apr 15 23:15:17 2021 +0200 38.3 @@ -0,0 +1,4 @@ 38.4 +PKGDIR ?= . 38.5 +L4DIR ?= $(PKGDIR)/../../.. 38.6 + 38.7 +include $(L4DIR)/mk/subdir.mk
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/libfsclient/include/Makefile Thu Apr 15 23:15:17 2021 +0200 39.3 @@ -0,0 +1,7 @@ 39.4 +PKGDIR ?= .. 39.5 +L4DIR ?= $(PKGDIR)/../../.. 39.6 + 39.7 +PKGNAME = libfsclient 39.8 +CONTRIB_HEADERS = 1 39.9 + 39.10 +include $(L4DIR)/mk/include.mk
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2 +++ b/libfsclient/include/fsclient/client.h Thu Apr 15 23:15:17 2021 +0200 40.3 @@ -0,0 +1,56 @@ 40.4 +/* 40.5 + * Filesystem client functions. 40.6 + * 40.7 + * Copyright (C) 2018, 2019, 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 +#pragma once 40.26 + 40.27 +#include "file.h" 40.28 + 40.29 +EXTERN_C_BEGIN 40.30 + 40.31 +/* File operations. */ 40.32 + 40.33 +void client_close(file_t *file); 40.34 +file_t *client_open(const char *name, flags_t flags); 40.35 +long client_pipe(file_t **reader, file_t **writer); 40.36 + 40.37 +/* File and region operations. */ 40.38 + 40.39 +long client_flush(file_t *file); 40.40 +void *client_mmap(file_t *file, offset_t position, offset_t length); 40.41 + 40.42 +/* Pipe region operations. */ 40.43 + 40.44 +void *client_current_region(file_t *file); 40.45 +void *client_next_region(file_t *file); 40.46 + 40.47 +/* File data operations. */ 40.48 + 40.49 +offset_t client_read(file_t *file, void *buf, offset_t count); 40.50 +offset_t client_write(file_t *file, const void *buf, offset_t count); 40.51 + 40.52 +/* File navigation operations. */ 40.53 + 40.54 +offset_t client_seek(file_t *file, offset_t offset, int whence); 40.55 +long client_tell(file_t *file); 40.56 + 40.57 +EXTERN_C_END 40.58 + 40.59 +// vim: tabstop=2 expandtab shiftwidth=2
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/libfsclient/include/fsclient/file.h Thu Apr 15 23:15:17 2021 +0200 41.3 @@ -0,0 +1,114 @@ 41.4 +/* 41.5 + * File access convenience functions and types. 41.6 + * 41.7 + * Copyright (C) 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/sys/types.h> 41.26 + 41.27 +#include <systypes/base.h> 41.28 + 41.29 + 41.30 + 41.31 +EXTERN_C_BEGIN 41.32 + 41.33 +/* File access abstraction. */ 41.34 + 41.35 +typedef struct 41.36 +{ 41.37 + /* File object reference. */ 41.38 + 41.39 + l4_cap_idx_t ref; 41.40 + 41.41 + /* Mapped memory accessing a file region. */ 41.42 + 41.43 + char *memory; 41.44 + 41.45 + /* File region parameters. */ 41.46 + 41.47 + offset_t start_pos, end_pos; /* start and end positions of region */ 41.48 + offset_t data_end; /* amount/extent of data in the region */ 41.49 + offset_t data_current; /* client access offset */ 41.50 + 41.51 + /* Total size of file. */ 41.52 + 41.53 + offset_t size; 41.54 + 41.55 + /* Arbitrary memory mapping support. */ 41.56 + 41.57 + int can_mmap; 41.58 + 41.59 +} file_t; 41.60 + 41.61 + 41.62 + 41.63 +/* File operations. */ 41.64 + 41.65 +void file_close(file_t *file); 41.66 +long file_open(file_t *file, const char *filename, flags_t flags, l4_cap_idx_t server); 41.67 + 41.68 +/* File lifecycle operations. */ 41.69 + 41.70 +long file_context(file_t *file, l4_cap_idx_t server); 41.71 +long file_context_open(file_t *file, flags_t flags, file_t *context); 41.72 +void file_init(file_t *file); 41.73 + 41.74 +/* File and region operations. */ 41.75 + 41.76 +long file_flush(file_t *file); 41.77 +long file_mmap(file_t *file, offset_t position, offset_t length); 41.78 +long file_resize(file_t *file, offset_t size); 41.79 + 41.80 +/* File and region properties. */ 41.81 + 41.82 +offset_t file_populated_span(file_t *file); 41.83 +offset_t file_span(file_t *file); 41.84 + 41.85 +/* Convenience functions. */ 41.86 + 41.87 +char *file_string_get(file_t *file, offset_t offset); 41.88 +int file_string_set(file_t *file, const char *data, offset_t offset, offset_t *written); 41.89 + 41.90 +/* Client data functions. */ 41.91 + 41.92 +offset_t file_data_available(file_t *file); 41.93 +char *file_data_current(file_t *file); 41.94 +offset_t file_data_current_position(file_t *file); 41.95 +offset_t file_data_end_position(file_t *file); 41.96 +offset_t file_data_space(file_t *file); 41.97 + 41.98 +/* Client data transfer functions. */ 41.99 + 41.100 +void file_data_read(file_t *file, char *buf, size_t to_transfer); 41.101 +void file_data_write(file_t *file, char *buf, size_t to_transfer); 41.102 + 41.103 + 41.104 + 41.105 +/* Pipe operations. */ 41.106 + 41.107 +long pipe_open(offset_t size, file_t *reader, file_t *writer, l4_cap_idx_t server); 41.108 + 41.109 +/* Pipe region operations. */ 41.110 + 41.111 +long pipe_current(file_t *pipe); 41.112 +long pipe_next(file_t *pipe); 41.113 +long pipe_written(file_t *pipe, offset_t size); 41.114 + 41.115 +EXTERN_C_END 41.116 + 41.117 +// vim: tabstop=2 expandtab shiftwidth=2
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/libfsclient/lib/Makefile Thu Apr 15 23:15:17 2021 +0200 42.3 @@ -0,0 +1,4 @@ 42.4 +PKGDIR ?= .. 42.5 +L4DIR ?= $(PKGDIR)/../../.. 42.6 + 42.7 +include $(L4DIR)/mk/subdir.mk
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 43.2 +++ b/libfsclient/lib/src/Makefile Thu Apr 15 23:15:17 2021 +0200 43.3 @@ -0,0 +1,40 @@ 43.4 +PKGDIR ?= ../.. 43.5 +L4DIR ?= $(PKGDIR)/../../.. 43.6 + 43.7 +TARGET = libfsclient.so libfsclient.a 43.8 +PC_FILENAME = libfsclient 43.9 + 43.10 +# Locations for interface input and generated output. 43.11 + 43.12 +IDL_DIR = $(L4DIR)/pkg/libsystypes/idl 43.13 +IDL_MK_DIR = $(L4DIR)/idl4re/mk 43.14 +IDL_BUILD_DIR = . 43.15 +IDL_EXPORT_DIR = . 43.16 + 43.17 +include $(IDL_MK_DIR)/idl.mk 43.18 + 43.19 +# Individual interfaces. 43.20 + 43.21 +CLIENT_INTERFACES_CC = dataspace file mapped_file opener opener_context pipe pipe_opener 43.22 + 43.23 +# Generated and plain source files. 43.24 + 43.25 +CLIENT_INTERFACES_SRC_CC = $(call interfaces_to_client_cc,$(CLIENT_INTERFACES_CC)) 43.26 + 43.27 +PLAIN_SRC_CC = client.cc file.cc 43.28 + 43.29 +# Normal definitions. 43.30 + 43.31 +SRC_CC = \ 43.32 + $(CLIENT_INTERFACES_SRC_CC) \ 43.33 + $(PLAIN_SRC_CC) 43.34 + 43.35 +REQUIRES_LIBS = l4re_c-util libipc libstdc++ libsystypes 43.36 + 43.37 +PRIVATE_INCDIR = $(PKGDIR)/include/fsclient $(IDL_BUILD_DIR) $(IDL_EXPORT_DIR) 43.38 +CONTRIB_INCDIR = libfsclient 43.39 + 43.40 +include $(L4DIR)/mk/lib.mk 43.41 +include $(IDL_MK_DIR)/interface_rules.mk 43.42 + 43.43 +$(PLAIN_SRC_CC): $(CLIENT_INTERFACES_SRC_CC)
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 44.2 +++ b/libfsclient/lib/src/client.cc Thu Apr 15 23:15:17 2021 +0200 44.3 @@ -0,0 +1,390 @@ 44.4 +/* 44.5 + * Filesystem client functions. 44.6 + * 44.7 + * Copyright (C) 2018, 2019, 2020, 2021 Paul Boddie <paul@boddie.org.uk> 44.8 + * 44.9 + * This program is free software; you can redistribute it and/or 44.10 + * modify it under the terms of the GNU General Public License as 44.11 + * published by the Free Software Foundation; either version 2 of 44.12 + * the License, or (at your option) any later version. 44.13 + * 44.14 + * This program is distributed in the hope that it will be useful, 44.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 44.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 44.17 + * GNU General Public License for more details. 44.18 + * 44.19 + * You should have received a copy of the GNU General Public License 44.20 + * along with this program; if not, write to the Free Software 44.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 44.22 + * Boston, MA 02110-1301, USA 44.23 + */ 44.24 + 44.25 +#include <l4/re/env.h> 44.26 + 44.27 +#include <stdio.h> 44.28 +#include <stdlib.h> 44.29 + 44.30 +#include "client.h" 44.31 + 44.32 + 44.33 + 44.34 +/* Default size of pipe regions. */ 44.35 + 44.36 +const offset_t DEFAULT_PIPE_SIZE = 4096; 44.37 + 44.38 + 44.39 + 44.40 +/* Close a filesystem object. */ 44.41 + 44.42 +void client_close(file_t *file) 44.43 +{ 44.44 + if (file == NULL) 44.45 + return; 44.46 + 44.47 + file_close(file); 44.48 + free(file); 44.49 +} 44.50 + 44.51 + 44.52 + 44.53 +/* Open a filesystem object. */ 44.54 + 44.55 +file_t *client_open(const char *name, flags_t flags) 44.56 +{ 44.57 + file_t *file = (file_t *) malloc(sizeof(file_t)); 44.58 + 44.59 + if (file == NULL) 44.60 + return NULL; 44.61 + 44.62 + l4_cap_idx_t server = l4re_env_get_cap("server"); 44.63 + 44.64 + if (file_open(file, name, flags, server)) 44.65 + { 44.66 + free(file); 44.67 + return NULL; 44.68 + } 44.69 + 44.70 + return file; 44.71 +} 44.72 + 44.73 + 44.74 + 44.75 +/* Open a pipe object. */ 44.76 + 44.77 +long client_pipe(file_t **reader, file_t **writer) 44.78 +{ 44.79 + *reader = (file_t *) malloc(sizeof(file_t)); 44.80 + 44.81 + if (*reader == NULL) 44.82 + return -L4_ENOMEM; 44.83 + 44.84 + *writer = (file_t *) malloc(sizeof(file_t)); 44.85 + 44.86 + if (*writer == NULL) 44.87 + { 44.88 + free(*reader); 44.89 + return -L4_ENOMEM; 44.90 + } 44.91 + 44.92 + l4_cap_idx_t server = l4re_env_get_cap("pipes"); 44.93 + 44.94 + long err = pipe_open(DEFAULT_PIPE_SIZE, *reader, *writer, server); 44.95 + 44.96 + if (err) 44.97 + { 44.98 + free(*reader); 44.99 + free(*writer); 44.100 + } 44.101 + 44.102 + return err; 44.103 +} 44.104 + 44.105 + 44.106 + 44.107 +/* Flush data conditionally to the filesystem object. */ 44.108 + 44.109 +static long _flush(file_t *file, offset_t position) 44.110 +{ 44.111 + long err; 44.112 + 44.113 + /* Where the position is outside the current region, re-map. */ 44.114 + 44.115 + if ((position < file->start_pos) || (position >= file->end_pos)) 44.116 + { 44.117 + if (file->can_mmap) 44.118 + { 44.119 + if (file_mmap(file, position, file_span(file))) 44.120 + return -L4_EIO; 44.121 + } 44.122 + 44.123 + /* Strict conditions for region navigation in pipes. */ 44.124 + 44.125 + else if ((position != file->end_pos) || 44.126 + (client_next_region(file) == NULL)) 44.127 + return -L4_EIO; 44.128 + } 44.129 + 44.130 + /* Otherwise, flush any written data in the current region and update the 44.131 + file size details. */ 44.132 + 44.133 + else 44.134 + { 44.135 + err = client_flush(file); 44.136 + 44.137 + if (err) 44.138 + return err; 44.139 + } 44.140 + 44.141 + /* Update the current data offset. */ 44.142 + 44.143 + file->data_current = position - file->start_pos; 44.144 + return L4_EOK; 44.145 +} 44.146 + 44.147 + 44.148 + 44.149 +/* Flush data explicitly to the filesystem object. */ 44.150 + 44.151 +long client_flush(file_t *file) 44.152 +{ 44.153 + if (file == NULL) 44.154 + return -L4_EINVAL; 44.155 + 44.156 + /* Flush and retain most buffer settings. */ 44.157 + 44.158 + return file_flush(file); 44.159 +} 44.160 + 44.161 + 44.162 + 44.163 +/* Map a memory region to a file. */ 44.164 + 44.165 +void *client_mmap(file_t *file, offset_t position, offset_t length) 44.166 +{ 44.167 + if ((file == NULL) || (file_mmap(file, position, length))) 44.168 + return NULL; 44.169 + 44.170 + return file->memory; 44.171 +} 44.172 + 44.173 + 44.174 + 44.175 +/* Obtain the current region of a pipe. */ 44.176 + 44.177 +void *client_current_region(file_t *file) 44.178 +{ 44.179 + if ((file == NULL) || (pipe_current(file))) 44.180 + return NULL; 44.181 + 44.182 + return file->memory; 44.183 +} 44.184 + 44.185 + 44.186 + 44.187 +/* Obtain the next region of a pipe. */ 44.188 + 44.189 +void *client_next_region(file_t *file) 44.190 +{ 44.191 + if ((file == NULL) || (pipe_next(file))) 44.192 + return NULL; 44.193 + 44.194 + return file->memory; 44.195 +} 44.196 + 44.197 + 44.198 + 44.199 +/* Read from the filesystem object into the buffer provided. */ 44.200 + 44.201 +offset_t client_read(file_t *file, void *buf, offset_t count) 44.202 +{ 44.203 + if (file == NULL) 44.204 + return 0; 44.205 + 44.206 + /* Amount available in the descriptor buffer already. */ 44.207 + 44.208 + offset_t available = file_data_available(file); 44.209 + offset_t to_transfer, total = 0; 44.210 + 44.211 + while (count > 0) 44.212 + { 44.213 + /* If there is no data, try and obtain more data. */ 44.214 + 44.215 + if (!available) 44.216 + { 44.217 + /* Flush any unwritten data, preparing to read from the file position at 44.218 + the end of the data, and returning if no new data is available. */ 44.219 + 44.220 + if (_flush(file, file_data_end_position(file))) 44.221 + break; 44.222 + 44.223 + available = file_data_available(file); 44.224 + 44.225 + if (!available) 44.226 + break; 44.227 + } 44.228 + 44.229 + /* Transfer data into the supplied buffer. */ 44.230 + 44.231 + to_transfer = available <= count ? available : count; 44.232 + 44.233 + file_data_read(file, (char *) buf, to_transfer); 44.234 + 44.235 + /* Update counters. */ 44.236 + 44.237 + available -= to_transfer; 44.238 + 44.239 + count -= to_transfer; 44.240 + total += to_transfer; 44.241 + 44.242 + buf = ((char *) buf + to_transfer); 44.243 + } 44.244 + 44.245 + return total; 44.246 +} 44.247 + 44.248 + 44.249 + 44.250 +/* Ensure that the buffer can provide the needed data. */ 44.251 + 44.252 +offset_t client_seek(file_t *file, offset_t offset, int whence) 44.253 +{ 44.254 + if (file == NULL) 44.255 + return 0; 44.256 + 44.257 + offset_t position, current = file_data_current_position(file), change; 44.258 + 44.259 + switch (whence) 44.260 + { 44.261 + case SEEK_SET: 44.262 + position = offset; 44.263 + break; 44.264 + 44.265 + case SEEK_CUR: 44.266 + position = current + offset; 44.267 + break; 44.268 + 44.269 + case SEEK_END: 44.270 + position = file->size + offset; 44.271 + break; 44.272 + 44.273 + default: 44.274 + /* NOTE: Set errno to EINVAL. */ 44.275 + return -1; 44.276 + } 44.277 + 44.278 + /* Retain the current position if unchanged. */ 44.279 + 44.280 + if (position == current) 44.281 + return position; 44.282 + 44.283 + /* Move forward in the file. */ 44.284 + 44.285 + if (position > current) 44.286 + { 44.287 + change = position - current; 44.288 + 44.289 + /* Move towards the end of available data. 44.290 + Request new data if not enough is available. */ 44.291 + 44.292 + if (change <= file_data_available(file)) 44.293 + { 44.294 + file->data_current += change; 44.295 + return position; 44.296 + } 44.297 + } 44.298 + 44.299 + /* Move backward in the file. */ 44.300 + 44.301 + else 44.302 + { 44.303 + change = current - position; 44.304 + 44.305 + /* Move towards the start of available data. 44.306 + Request new data if moving beyond the start of the data. */ 44.307 + 44.308 + if (change <= file->data_current) 44.309 + { 44.310 + file->data_current -= change; 44.311 + return position; 44.312 + } 44.313 + } 44.314 + 44.315 + /* Handle unwritten data and reset the buffer for reading. */ 44.316 + 44.317 + _flush(file, position); 44.318 + return position; 44.319 +} 44.320 + 44.321 + 44.322 + 44.323 +long client_tell(file_t *file) 44.324 +{ 44.325 + if (file == NULL) 44.326 + return -L4_EINVAL; 44.327 + 44.328 + return file_data_current_position(file); 44.329 +} 44.330 + 44.331 + 44.332 + 44.333 +/* Write to the filesystem object from the buffer provided. */ 44.334 + 44.335 +offset_t client_write(file_t *file, const void *buf, offset_t count) 44.336 +{ 44.337 + if (file == NULL) 44.338 + return 0; 44.339 + 44.340 + /* Attempt to ensure that the file can accept the amount of data to be 44.341 + written. This may not resize to the needed amount if a file has a fixed 44.342 + size, but data will still be written to any available space. */ 44.343 + 44.344 + offset_t needed_size = file_data_current_position(file) + count; 44.345 + 44.346 + if (file->size < needed_size) 44.347 + { 44.348 + file_resize(file, needed_size); 44.349 + 44.350 + if (file->size < needed_size) 44.351 + count = file->size - file_data_current_position(file); 44.352 + } 44.353 + 44.354 + /* Space remaining in the descriptor buffer. */ 44.355 + 44.356 + offset_t space = file_data_space(file); 44.357 + offset_t to_transfer, total = 0; 44.358 + 44.359 + while (count > 0) 44.360 + { 44.361 + /* If no space is available, try and send data, reset the buffer. */ 44.362 + 44.363 + if (!space) 44.364 + { 44.365 + /* Flush any unwritten data and continue writing from the current data 44.366 + position. */ 44.367 + 44.368 + if (_flush(file, file_data_current_position(file))) 44.369 + break; 44.370 + 44.371 + space = file_data_space(file); 44.372 + } 44.373 + 44.374 + /* Transfer data into the supplied buffer. */ 44.375 + 44.376 + to_transfer = space <= count ? space : count; 44.377 + 44.378 + file_data_write(file, (char *) buf, to_transfer); 44.379 + 44.380 + /* Update counters. */ 44.381 + 44.382 + space -= to_transfer; 44.383 + 44.384 + count -= to_transfer; 44.385 + total += to_transfer; 44.386 + 44.387 + buf = ((char *) buf + to_transfer); 44.388 + } 44.389 + 44.390 + return total; 44.391 +} 44.392 + 44.393 +// vim: tabstop=2 expandtab shiftwidth=2
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 45.2 +++ b/libfsclient/lib/src/file.cc Thu Apr 15 23:15:17 2021 +0200 45.3 @@ -0,0 +1,452 @@ 45.4 +/* 45.5 + * File access convenience functions. 45.6 + * 45.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 45.8 + * 45.9 + * This program is free software; you can redistribute it and/or 45.10 + * modify it under the terms of the GNU General Public License as 45.11 + * published by the Free Software Foundation; either version 2 of 45.12 + * the License, or (at your option) any later version. 45.13 + * 45.14 + * This program is distributed in the hope that it will be useful, 45.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 45.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 45.17 + * GNU General Public License for more details. 45.18 + * 45.19 + * You should have received a copy of the GNU General Public License 45.20 + * along with this program; if not, write to the Free Software 45.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 45.22 + * Boston, MA 02110-1301, USA 45.23 + */ 45.24 + 45.25 +#include <ipc/cap_alloc.h> 45.26 +#include <ipc/mem_ipc.h> 45.27 + 45.28 +#include <string.h> 45.29 + 45.30 +#include "dataspace_client.h" 45.31 +#include "file_client.h" 45.32 +#include "opener_client.h" 45.33 +#include "opener_context_client.h" 45.34 +#include "pipe_client.h" 45.35 +#include "pipe_opener_client.h" 45.36 +#include "mapped_file_client.h" 45.37 + 45.38 +#include "file.h" 45.39 + 45.40 + 45.41 + 45.42 +/* Update the extent of the file in a region using the region start and end 45.43 + positions and the file size. */ 45.44 + 45.45 +static void _update_extent(file_t *file) 45.46 +{ 45.47 + /* Handle files ending after or within the region. */ 45.48 + 45.49 + if (file->size > file->start_pos) 45.50 + { 45.51 + if (file->size > file->end_pos) 45.52 + file->data_end = file->end_pos - file->start_pos; 45.53 + else 45.54 + file->data_end = file->size - file->start_pos; 45.55 + } 45.56 + 45.57 + /* Handle files ending before the region. */ 45.58 + 45.59 + else 45.60 + file->data_end = 0; 45.61 +} 45.62 + 45.63 + 45.64 + 45.65 +/* Initialise the given file structure. */ 45.66 + 45.67 +void file_init(file_t *file) 45.68 +{ 45.69 + file->memory = NULL; 45.70 + file->ref = L4_INVALID_CAP; 45.71 + file->start_pos = 0; 45.72 + file->end_pos = 0; 45.73 + file->data_end = 0; 45.74 + file->data_current = 0; 45.75 + file->can_mmap = 1; 45.76 +} 45.77 + 45.78 + 45.79 + 45.80 +/* Release resources for the given file. */ 45.81 + 45.82 +void file_close(file_t *file) 45.83 +{ 45.84 + if (l4_is_valid_cap(file->ref)) 45.85 + ipc_cap_free_um(file->ref); 45.86 + 45.87 + if (file->memory != NULL) 45.88 + ipc_detach_dataspace(file->memory); 45.89 + 45.90 + file_init(file); 45.91 +} 45.92 + 45.93 +/* Open a file using the given structure, indicating the filename and 45.94 + filesystem server. The file_mmap function should be used to obtain access to 45.95 + memory providing file data. This is a convenience function invoking 45.96 + file_context and file_context_open. */ 45.97 + 45.98 +long file_open(file_t *file, const char *filename, flags_t flags, l4_cap_idx_t server) 45.99 +{ 45.100 + file_t context; 45.101 + long err; 45.102 + 45.103 + err = file_context(&context, server); 45.104 + if (err) 45.105 + return err; 45.106 + 45.107 + if (!file_string_set(&context, filename, 0, NULL)) 45.108 + return -L4_ENOMEM; 45.109 + 45.110 + err = file_context_open(file, flags, &context); 45.111 + 45.112 + /* Close the context, although a separate mechanism could permit contexts to 45.113 + open several files. */ 45.114 + 45.115 + file_close(&context); 45.116 + return err; 45.117 +} 45.118 + 45.119 + 45.120 + 45.121 +/* Initialise a file structure for a context obtained from the given server 45.122 + attaching memory to communicate filename information. */ 45.123 + 45.124 +long file_context(file_t *file, l4_cap_idx_t server) 45.125 +{ 45.126 + if (l4_is_invalid_cap(server)) 45.127 + return -L4_EINVAL; 45.128 + 45.129 + client_Opener opener(server); 45.130 + offset_t size; 45.131 + flags_t flags; 45.132 + long err; 45.133 + 45.134 + file_init(file); 45.135 + 45.136 + err = opener.context(&file->ref); 45.137 + if (err) 45.138 + return err; 45.139 + 45.140 + client_Dataspace context_ds(file->ref); 45.141 + 45.142 + err = context_ds.info(&size, &flags); 45.143 + if (err) 45.144 + return err; 45.145 + 45.146 + file->start_pos = 0; 45.147 + file->end_pos = size; 45.148 + 45.149 + return ipc_attach_dataspace(file->ref, size, (void **) &file->memory); 45.150 +} 45.151 + 45.152 +/* Open a file using the given structure and context. */ 45.153 + 45.154 +long file_context_open(file_t *file, flags_t flags, file_t *context) 45.155 +{ 45.156 + client_OpenerContext openercontext(context->ref); 45.157 + file_init(file); 45.158 + return openercontext.open(flags, &file->size, &file->ref); 45.159 +} 45.160 + 45.161 + 45.162 + 45.163 +/* Flush populated data and obtain an updated file size and populated data 45.164 + details. */ 45.165 + 45.166 +long file_flush(file_t *file) 45.167 +{ 45.168 + client_File _file(file->ref); 45.169 + long err = _file.flush(file->data_current, &file->size); 45.170 + 45.171 + if (err) 45.172 + return err; 45.173 + 45.174 + _update_extent(file); 45.175 + 45.176 + return L4_EOK; 45.177 +} 45.178 + 45.179 +/* Map a region of the given file to a memory region, obtaining an updated file 45.180 + size and populated data details. Unmap any previously mapped region. */ 45.181 + 45.182 +long file_mmap(file_t *file, offset_t position, offset_t length) 45.183 +{ 45.184 + char *memory = file->memory; 45.185 + client_MappedFile mapped_file(file->ref); 45.186 + long err = mapped_file.mmap(position, length, &file->start_pos, 45.187 + &file->end_pos, &file->size); 45.188 + 45.189 + if (err) 45.190 + return err; 45.191 + 45.192 + _update_extent(file); 45.193 + 45.194 + err = ipc_attach_dataspace(file->ref, file_span(file), (void **) &file->memory); 45.195 + if (err) 45.196 + return err; 45.197 + 45.198 + if (memory != NULL) 45.199 + ipc_detach_dataspace(memory); 45.200 + 45.201 + return L4_EOK; 45.202 +} 45.203 + 45.204 +/* Resize a file, obtaining updated file size and populated data details. */ 45.205 + 45.206 +long file_resize(file_t *file, offset_t size) 45.207 +{ 45.208 + client_File _file(file->ref); 45.209 + offset_t file_size = size; 45.210 + long err = _file.resize(&file_size); 45.211 + 45.212 + if (err) 45.213 + return err; 45.214 + 45.215 + file->size = file_size; 45.216 + _update_extent(file); 45.217 + return L4_EOK; 45.218 +} 45.219 + 45.220 + 45.221 + 45.222 +/* Return the amount of data in the mapped region for the given file. */ 45.223 + 45.224 +offset_t file_populated_span(file_t *file) 45.225 +{ 45.226 + offset_t size = file_span(file); 45.227 + return (file->data_end < size) ? file->data_end : size; 45.228 +} 45.229 + 45.230 +/* Return the size of the mapped region for the given file. */ 45.231 + 45.232 +offset_t file_span(file_t *file) 45.233 +{ 45.234 + return file->end_pos - file->start_pos; 45.235 +} 45.236 + 45.237 + 45.238 + 45.239 +/* Get a pointer to any terminated string at the given offset or NULL if the 45.240 + data from offset is not terminated. */ 45.241 + 45.242 +char *file_string_get(file_t *file, offset_t offset) 45.243 +{ 45.244 + offset_t limit = file_span(file) - offset; 45.245 + 45.246 + if (strnlen(file->memory + offset, limit) < limit) 45.247 + return file->memory + offset; 45.248 + else 45.249 + return NULL; 45.250 +} 45.251 + 45.252 +/* Copy a string to the mapped region at the given offset, returning 1 (true) 45.253 + where all characters were copied, 0 (false) otherwise. The precise number of 45.254 + characters copied, excluding the zero terminator is provided via the written 45.255 + parameter if it is not specified as NULL. */ 45.256 + 45.257 +int file_string_set(file_t *file, const char *data, offset_t offset, 45.258 + offset_t *written) 45.259 +{ 45.260 + offset_t i, pos, limit = file_span(file); 45.261 + 45.262 + /* Do not attempt to copy data with an invalid offset. */ 45.263 + 45.264 + if (offset >= limit) 45.265 + { 45.266 + if (written != NULL) 45.267 + *written = 0; 45.268 + return 0; 45.269 + } 45.270 + 45.271 + /* Copy the data to the given offset, stopping at the end of the region. */ 45.272 + 45.273 + for (i = 0, pos = offset; pos < limit; i++, pos++) 45.274 + { 45.275 + file->memory[pos] = data[i]; 45.276 + 45.277 + /* Terminator written, can return immediately. */ 45.278 + 45.279 + if (!data[i]) 45.280 + { 45.281 + if (written != NULL) 45.282 + *written = pos - offset; 45.283 + return 1; 45.284 + } 45.285 + } 45.286 + 45.287 + /* Terminate the incomplete string at the end of the region. */ 45.288 + 45.289 + file->memory[limit - 1] = '\0'; 45.290 + if (written != NULL) 45.291 + *written = limit - 1 - offset; 45.292 + return 0; 45.293 +} 45.294 + 45.295 + 45.296 + 45.297 +/* Return the number of remaining populated bytes in the region. */ 45.298 + 45.299 +offset_t file_data_available(file_t *file) 45.300 +{ 45.301 + return file_populated_span(file) - file->data_current; 45.302 +} 45.303 + 45.304 +/* Return the current data offset in the region. */ 45.305 + 45.306 +char *file_data_current(file_t *file) 45.307 +{ 45.308 + return file->memory + file->data_current; 45.309 +} 45.310 + 45.311 +/* Return the current access position in the file. */ 45.312 + 45.313 +offset_t file_data_current_position(file_t *file) 45.314 +{ 45.315 + return file->start_pos + file->data_current; 45.316 +} 45.317 + 45.318 +/* Return the position of the end of the populated bytes in the region. */ 45.319 + 45.320 +offset_t file_data_end_position(file_t *file) 45.321 +{ 45.322 + return file->start_pos + file->data_end; 45.323 +} 45.324 + 45.325 +/* Return the amount of remaining space in the region. */ 45.326 + 45.327 +offset_t file_data_space(file_t *file) 45.328 +{ 45.329 + return file_span(file) - file->data_current; 45.330 +} 45.331 + 45.332 + 45.333 + 45.334 +/* Copy data to the given buffer from the current data position, updating the 45.335 + position. */ 45.336 + 45.337 +void file_data_read(file_t *file, char *buf, size_t to_transfer) 45.338 +{ 45.339 + memcpy(buf, file_data_current(file), to_transfer); 45.340 + 45.341 + /* Update position details. */ 45.342 + 45.343 + file->data_current += to_transfer; 45.344 +} 45.345 + 45.346 +/* Copy data from the given buffer to the current data position, updating the 45.347 + position and the extent of populated data if this was exceeded. */ 45.348 + 45.349 +void file_data_write(file_t *file, char *buf, size_t to_transfer) 45.350 +{ 45.351 + memcpy(file_data_current(file), buf, to_transfer); 45.352 + 45.353 + /* Update position details. */ 45.354 + 45.355 + file->data_current += to_transfer; 45.356 + 45.357 + if (file->data_current > file->data_end) 45.358 + file->data_end = file->data_current; 45.359 +} 45.360 + 45.361 + 45.362 + 45.363 +/* Open two pipe endpoints using the given pipe server. */ 45.364 + 45.365 +long pipe_open(offset_t size, file_t *reader, file_t *writer, l4_cap_idx_t server) 45.366 +{ 45.367 + if (l4_is_invalid_cap(server)) 45.368 + return -L4_EINVAL; 45.369 + 45.370 + client_PipeOpener opener(server); 45.371 + 45.372 + file_init(reader); 45.373 + file_init(writer); 45.374 + 45.375 + /* Pipes can usually only be accessed via region navigation. */ 45.376 + 45.377 + reader->can_mmap = 0; 45.378 + writer->can_mmap = 0; 45.379 + 45.380 + long err = opener.pipe(size, &reader->ref, &writer->ref); 45.381 + if (err) 45.382 + return err; 45.383 + 45.384 + err = pipe_next(writer) || pipe_next(reader); 45.385 + 45.386 + if (err) 45.387 + { 45.388 + file_close(reader); 45.389 + file_close(writer); 45.390 + } 45.391 + 45.392 + return err; 45.393 +} 45.394 + 45.395 +/* Access the current region for a pipe endpoint. */ 45.396 + 45.397 +long pipe_current(file_t *pipe) 45.398 +{ 45.399 + client_Pipe _pipe(pipe->ref); 45.400 + long err = _pipe.current_region(&pipe->data_end, &pipe->size); 45.401 + char *memory = pipe->memory; 45.402 + 45.403 + if (err) 45.404 + return err; 45.405 + 45.406 + pipe->end_pos = pipe->size; 45.407 + 45.408 + err = ipc_attach_dataspace(pipe->ref, file_span(pipe), (void **) &pipe->memory); 45.409 + if (err) 45.410 + return err; 45.411 + 45.412 + if (memory != NULL) 45.413 + ipc_detach_dataspace(memory); 45.414 + 45.415 + return L4_EOK; 45.416 +} 45.417 + 45.418 +/* Access the next region for a pipe endpoint, updating the eventual size of 45.419 + the current region. */ 45.420 + 45.421 +long pipe_next(file_t *pipe) 45.422 +{ 45.423 + client_Pipe _pipe(pipe->ref); 45.424 + long err = _pipe.next_region(&pipe->data_end, &pipe->size); 45.425 + char *memory = pipe->memory; 45.426 + 45.427 + if (err) 45.428 + return err; 45.429 + 45.430 + pipe->end_pos = pipe->size; 45.431 + 45.432 + err = ipc_attach_dataspace(pipe->ref, file_span(pipe), (void **) &pipe->memory); 45.433 + if (err) 45.434 + return err; 45.435 + 45.436 + if (memory != NULL) 45.437 + ipc_detach_dataspace(memory); 45.438 + 45.439 + return L4_EOK; 45.440 +} 45.441 + 45.442 +/* Set the size of the written region. */ 45.443 + 45.444 +long pipe_written(file_t *pipe, offset_t size) 45.445 +{ 45.446 + if (size <= pipe->size) 45.447 + { 45.448 + pipe->data_end = size; 45.449 + return L4_EOK; 45.450 + } 45.451 + else 45.452 + return -L4_EINVAL; 45.453 +} 45.454 + 45.455 +// vim: tabstop=2 expandtab shiftwidth=2
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 46.2 +++ b/libfsserver/Control Thu Apr 15 23:15:17 2021 +0200 46.3 @@ -0,0 +1,3 @@ 46.4 +requires: libstdc++ libc libipc libmem 46.5 +provides: libfsserver 46.6 +maintainer: paul@boddie.org.uk
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 47.2 +++ b/libfsserver/Makefile Thu Apr 15 23:15:17 2021 +0200 47.3 @@ -0,0 +1,4 @@ 47.4 +PKGDIR ?= . 47.5 +L4DIR ?= $(PKGDIR)/../../.. 47.6 + 47.7 +include $(L4DIR)/mk/subdir.mk
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 48.2 +++ b/libfsserver/include/Makefile Thu Apr 15 23:15:17 2021 +0200 48.3 @@ -0,0 +1,7 @@ 48.4 +PKGDIR ?= .. 48.5 +L4DIR ?= $(PKGDIR)/../../.. 48.6 + 48.7 +PKGNAME = libfsserver 48.8 +CONTRIB_HEADERS = 1 48.9 + 48.10 +include $(L4DIR)/mk/include.mk
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 49.2 +++ b/libfsserver/include/fsserver/access_map.h Thu Apr 15 23:15:17 2021 +0200 49.3 @@ -0,0 +1,60 @@ 49.4 +/* 49.5 + * An access map providing memory corresponding to file regions. 49.6 + * 49.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 49.8 + * 49.9 + * This program is free software; you can redistribute it and/or 49.10 + * modify it under the terms of the GNU General Public License as 49.11 + * published by the Free Software Foundation; either version 2 of 49.12 + * the License, or (at your option) any later version. 49.13 + * 49.14 + * This program is distributed in the hope that it will be useful, 49.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 49.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 49.17 + * GNU General Public License for more details. 49.18 + * 49.19 + * You should have received a copy of the GNU General Public License 49.20 + * along with this program; if not, write to the Free Software 49.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 49.22 + * Boston, MA 02110-1301, USA 49.23 + */ 49.24 + 49.25 +#pragma once 49.26 + 49.27 +#include <mem/flexpage.h> 49.28 +#include <fsserver/page_owner.h> 49.29 +#include <fsserver/pages.h> 49.30 + 49.31 +#include <map> 49.32 +#include <mutex> 49.33 + 49.34 + 49.35 + 49.36 +/* Collection types. */ 49.37 + 49.38 +typedef std::map<offset_t, Flexpage *> _AccessMap; 49.39 +typedef std::pair<offset_t, Flexpage *> _AccessMapEntry; 49.40 + 49.41 + 49.42 + 49.43 +/* A mapping from file positions to flexpages. */ 49.44 + 49.45 +class AccessMap 49.46 +{ 49.47 +protected: 49.48 + _AccessMap _flexpages; 49.49 + std::mutex _lock; 49.50 + 49.51 +public: 49.52 + Flexpage *find(offset_t position); 49.53 + 49.54 + void insert(Flexpage *flexpage); 49.55 + 49.56 + bool remove(PageOwner *owner, Flexpage *flexpage); 49.57 + 49.58 + void purge(PageOwner *owner, Pages *pages); 49.59 + 49.60 + void flush_all(offset_t start, offset_t size, PageOwner *owner, Pages *pages); 49.61 +}; 49.62 + 49.63 +// vim: tabstop=4 expandtab shiftwidth=4
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 50.2 +++ b/libfsserver/include/fsserver/accessor.h Thu Apr 15 23:15:17 2021 +0200 50.3 @@ -0,0 +1,63 @@ 50.4 +/* 50.5 + * Generic accessor functionality. 50.6 + * 50.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 50.8 + * 50.9 + * This program is free software; you can redistribute it and/or 50.10 + * modify it under the terms of the GNU General Public License as 50.11 + * published by the Free Software Foundation; either version 2 of 50.12 + * the License, or (at your option) any later version. 50.13 + * 50.14 + * This program is distributed in the hope that it will be useful, 50.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 50.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 50.17 + * GNU General Public License for more details. 50.18 + * 50.19 + * You should have received a copy of the GNU General Public License 50.20 + * along with this program; if not, write to the Free Software 50.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 50.22 + * Boston, MA 02110-1301, USA 50.23 + */ 50.24 + 50.25 +#pragma once 50.26 + 50.27 +#include <mem/flexpage.h> 50.28 + 50.29 + 50.30 + 50.31 +/* A file accessor, providing flexpages corresponding to file regions. */ 50.32 + 50.33 +class Accessor 50.34 +{ 50.35 +protected: 50.36 + offset_t _size; 50.37 + 50.38 + /* Data transfer helper methods. */ 50.39 + 50.40 + virtual void fill_populated(Flexpage *flexpage); 50.41 + 50.42 + virtual void flush_populated(Flexpage *flexpage); 50.43 + 50.44 +public: 50.45 + fileid_t fileid; 50.46 + 50.47 + explicit Accessor(fileid_t fileid, offset_t size=0); 50.48 + 50.49 + virtual ~Accessor(); 50.50 + 50.51 + virtual offset_t get_size(); 50.52 + 50.53 + virtual void set_size(offset_t size); 50.54 + 50.55 + virtual void close(); 50.56 + 50.57 + virtual void open(); 50.58 + 50.59 + /* Data transfer methods. */ 50.60 + 50.61 + virtual void fill(Flexpage *flexpage); 50.62 + 50.63 + virtual void flush(Flexpage *flexpage); 50.64 +}; 50.65 + 50.66 +// vim: tabstop=4 expandtab shiftwidth=4
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 51.2 +++ b/libfsserver/include/fsserver/block_file_accessor.h Thu Apr 15 23:15:17 2021 +0200 51.3 @@ -0,0 +1,48 @@ 51.4 +/* 51.5 + * A file accessor employing a rewritable memory area. 51.6 + * 51.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 51.8 + * 51.9 + * This program is free software; you can redistribute it and/or 51.10 + * modify it under the terms of the GNU General Public License as 51.11 + * published by the Free Software Foundation; either version 2 of 51.12 + * the License, or (at your option) any later version. 51.13 + * 51.14 + * This program is distributed in the hope that it will be useful, 51.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 51.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 51.17 + * GNU General Public License for more details. 51.18 + * 51.19 + * You should have received a copy of the GNU General Public License 51.20 + * along with this program; if not, write to the Free Software 51.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 51.22 + * Boston, MA 02110-1301, USA 51.23 + */ 51.24 + 51.25 +#pragma once 51.26 + 51.27 +#include <fsserver/accessor.h> 51.28 + 51.29 + 51.30 + 51.31 +/* A block file accessor, providing flexpages corresponding to the regions of 51.32 + loaded files. */ 51.33 + 51.34 +class BlockFileAccessor : public Accessor 51.35 +{ 51.36 +protected: 51.37 + char *_data; 51.38 + 51.39 + /* Data transfer helper methods. */ 51.40 + 51.41 + virtual void fill_populated(Flexpage *flexpage); 51.42 + 51.43 + virtual void flush_populated(Flexpage *flexpage); 51.44 + 51.45 +public: 51.46 + explicit BlockFileAccessor(const char *path, fileid_t fileid); 51.47 + 51.48 + virtual void set_size(offset_t size); 51.49 +}; 51.50 + 51.51 +// vim: tabstop=4 expandtab shiftwidth=4
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 52.2 +++ b/libfsserver/include/fsserver/block_file_opener.h Thu Apr 15 23:15:17 2021 +0200 52.3 @@ -0,0 +1,44 @@ 52.4 +/* 52.5 + * An opener for a file employing a rewritable memory area. 52.6 + * 52.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 52.8 + * 52.9 + * This program is free software; you can redistribute it and/or 52.10 + * modify it under the terms of the GNU General Public License as 52.11 + * published by the Free Software Foundation; either version 2 of 52.12 + * the License, or (at your option) any later version. 52.13 + * 52.14 + * This program is distributed in the hope that it will be useful, 52.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 52.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 52.17 + * GNU General Public License for more details. 52.18 + * 52.19 + * You should have received a copy of the GNU General Public License 52.20 + * along with this program; if not, write to the Free Software 52.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 52.22 + * Boston, MA 02110-1301, USA 52.23 + */ 52.24 + 52.25 +#pragma once 52.26 + 52.27 +#include <fsserver/host_file_opener.h> 52.28 + 52.29 + 52.30 + 52.31 +/* Support for providing access to files. */ 52.32 + 52.33 +class BlockFileOpener : public HostFileOpener 52.34 +{ 52.35 +protected: 52.36 + /* Configurable methods. */ 52.37 + 52.38 + virtual Accessor *make_accessor(fileid_t fileid); 52.39 + 52.40 +public: 52.41 + explicit BlockFileOpener(Pages *pages) 52.42 + : HostFileOpener(pages) 52.43 + { 52.44 + } 52.45 +}; 52.46 + 52.47 +// vim: tabstop=4 expandtab shiftwidth=4
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 53.2 +++ b/libfsserver/include/fsserver/file_pager.h Thu Apr 15 23:15:17 2021 +0200 53.3 @@ -0,0 +1,69 @@ 53.4 +/* 53.5 + * File-specific pager functionality. 53.6 + * 53.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 53.8 + * 53.9 + * This program is free software; you can redistribute it and/or 53.10 + * modify it under the terms of the GNU General Public License as 53.11 + * published by the Free Software Foundation; either version 2 of 53.12 + * the License, or (at your option) any later version. 53.13 + * 53.14 + * This program is distributed in the hope that it will be useful, 53.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 53.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 53.17 + * GNU General Public License for more details. 53.18 + * 53.19 + * You should have received a copy of the GNU General Public License 53.20 + * along with this program; if not, write to the Free Software 53.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 53.22 + * Boston, MA 02110-1301, USA 53.23 + */ 53.24 + 53.25 +#pragma once 53.26 + 53.27 +#include <fsserver/mapped_file_object_interface.h> 53.28 +#include <fsserver/pager.h> 53.29 +#include <fsserver/file_paging.h> 53.30 + 53.31 + 53.32 + 53.33 +/* A pager abstraction for a file. */ 53.34 + 53.35 +class FilePager : public Pager, public MappedFileObject 53.36 +{ 53.37 +protected: 53.38 + FilePaging *_paging; 53.39 + 53.40 +public: 53.41 + fileid_t fileid; 53.42 + 53.43 + explicit FilePager(fileid_t fileid, PageMapper *mapper, flags_t flags, 53.44 + FilePaging *paging); 53.45 + 53.46 + virtual void close(); 53.47 + 53.48 + /* Server details. */ 53.49 + 53.50 + int expected_items(); 53.51 + 53.52 + ipc_server_handler_type handler(); 53.53 + 53.54 + void *interface() 53.55 + { return static_cast<MappedFileObject *>(this); } 53.56 + 53.57 + /* File methods. */ 53.58 + 53.59 + virtual long flush(offset_t populated_size, offset_t *size); 53.60 + 53.61 + virtual long resize(offset_t *size); 53.62 + 53.63 + /* Pager and mapped file methods. */ 53.64 + 53.65 + virtual long map(offset_t offset, address_t hot_spot, flags_t flags, 53.66 + l4_snd_fpage_t *region); 53.67 + 53.68 + virtual long mmap(offset_t position, offset_t length, offset_t *start_pos, 53.69 + offset_t *end_pos, offset_t *size); 53.70 +}; 53.71 + 53.72 +// vim: tabstop=4 expandtab shiftwidth=4
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 54.2 +++ b/libfsserver/include/fsserver/file_paging.h Thu Apr 15 23:15:17 2021 +0200 54.3 @@ -0,0 +1,80 @@ 54.4 +/* 54.5 + * General functionality supporting file paging. 54.6 + * 54.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 54.8 + * 54.9 + * This program is free software; you can redistribute it and/or 54.10 + * modify it under the terms of the GNU General Public License as 54.11 + * published by the Free Software Foundation; either version 2 of 54.12 + * the License, or (at your option) any later version. 54.13 + * 54.14 + * This program is distributed in the hope that it will be useful, 54.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 54.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 54.17 + * GNU General Public License for more details. 54.18 + * 54.19 + * You should have received a copy of the GNU General Public License 54.20 + * along with this program; if not, write to the Free Software 54.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 54.22 + * Boston, MA 02110-1301, USA 54.23 + */ 54.24 + 54.25 +#pragma once 54.26 + 54.27 +#include <map> 54.28 +#include <mutex> 54.29 + 54.30 +#include <fsserver/accessor.h> 54.31 +#include <fsserver/pager.h> 54.32 +#include <fsserver/page_mapper.h> 54.33 + 54.34 + 54.35 + 54.36 +/* Mapping type from accessors to page mappers. */ 54.37 + 54.38 +typedef std::map<fileid_t, PageMapper *> FileMapping; 54.39 +typedef std::pair<fileid_t, PageMapper *> FileMappingEntry; 54.40 + 54.41 + 54.42 + 54.43 +/* A registry of mappers for accessors. */ 54.44 + 54.45 +class FilePaging 54.46 +{ 54.47 +protected: 54.48 + Pages *_pages; 54.49 + 54.50 + FileMapping _mappers; 54.51 + std::mutex _lock; 54.52 + 54.53 + /* Pager initialisation methods. */ 54.54 + 54.55 + PageMapper *get_mapper(fileid_t fileid); 54.56 + 54.57 + Pager *get_pager(fileid_t fileid, flags_t flags); 54.58 + 54.59 + /* Configurable methods. */ 54.60 + 54.61 + virtual fileid_t get_fileid(const char *path) = 0; 54.62 + 54.63 + virtual flags_t get_flags(flags_t flags); 54.64 + 54.65 + virtual Accessor *make_accessor(fileid_t fileid) = 0; 54.66 + 54.67 + /* Mapper registry access. */ 54.68 + 54.69 + PageMapper *get(fileid_t fileid); 54.70 + 54.71 + void set(fileid_t fileid, PageMapper *mapper); 54.72 + 54.73 +public: 54.74 + explicit FilePaging(Pages *pages); 54.75 + 54.76 + virtual ~FilePaging(); 54.77 + 54.78 + /* Methods for the pager. */ 54.79 + 54.80 + void detach_pager(fileid_t fileid, PageMapper *mapper); 54.81 +}; 54.82 + 54.83 +// vim: tabstop=4 expandtab shiftwidth=4
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 55.2 +++ b/libfsserver/include/fsserver/host_file_accessor.h Thu Apr 15 23:15:17 2021 +0200 55.3 @@ -0,0 +1,53 @@ 55.4 +/* 55.5 + * A file accessor employing a "host" file provided via the C library. 55.6 + * 55.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 55.8 + * 55.9 + * This program is free software; you can redistribute it and/or 55.10 + * modify it under the terms of the GNU General Public License as 55.11 + * published by the Free Software Foundation; either version 2 of 55.12 + * the License, or (at your option) any later version. 55.13 + * 55.14 + * This program is distributed in the hope that it will be useful, 55.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 55.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 55.17 + * GNU General Public License for more details. 55.18 + * 55.19 + * You should have received a copy of the GNU General Public License 55.20 + * along with this program; if not, write to the Free Software 55.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 55.22 + * Boston, MA 02110-1301, USA 55.23 + */ 55.24 + 55.25 +#pragma once 55.26 + 55.27 +#include <stdio.h> 55.28 + 55.29 +#include <fsserver/accessor.h> 55.30 + 55.31 + 55.32 + 55.33 +/* A host filesystem file accessor, providing flexpages corresponding to file 55.34 + regions. */ 55.35 + 55.36 +class HostFileAccessor : public Accessor 55.37 +{ 55.38 +protected: 55.39 + const char *_path; 55.40 + FILE *_fp; 55.41 + 55.42 + /* Data transfer helper methods. */ 55.43 + 55.44 + virtual void fill_populated(Flexpage *flexpage); 55.45 + 55.46 + virtual void flush_populated(Flexpage *flexpage); 55.47 + 55.48 +public: 55.49 + explicit HostFileAccessor(const char *path, fileid_t fileid); 55.50 + 55.51 + virtual void close(); 55.52 + 55.53 + virtual void open(); 55.54 +}; 55.55 + 55.56 +// vim: tabstop=4 expandtab shiftwidth=4
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 56.2 +++ b/libfsserver/include/fsserver/host_file_opener.h Thu Apr 15 23:15:17 2021 +0200 56.3 @@ -0,0 +1,57 @@ 56.4 +/* 56.5 + * An opener for a "host" file provided via the C library. 56.6 + * 56.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 56.8 + * 56.9 + * This program is free software; you can redistribute it and/or 56.10 + * modify it under the terms of the GNU General Public License as 56.11 + * published by the Free Software Foundation; either version 2 of 56.12 + * the License, or (at your option) any later version. 56.13 + * 56.14 + * This program is distributed in the hope that it will be useful, 56.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 56.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 56.17 + * GNU General Public License for more details. 56.18 + * 56.19 + * You should have received a copy of the GNU General Public License 56.20 + * along with this program; if not, write to the Free Software 56.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 56.22 + * Boston, MA 02110-1301, USA 56.23 + */ 56.24 + 56.25 +#pragma once 56.26 + 56.27 +#include <map> 56.28 + 56.29 +#include <fsserver/opener_resource.h> 56.30 + 56.31 + 56.32 + 56.33 +/* Collection types. */ 56.34 + 56.35 +typedef std::map<fileid_t, const char *> FilePaths; 56.36 +typedef std::pair<fileid_t, const char *> FilePathEntry; 56.37 + 56.38 + 56.39 + 56.40 +/* Support for providing access to files. */ 56.41 + 56.42 +class HostFileOpener : public OpenerResource 56.43 +{ 56.44 +protected: 56.45 + FilePaths _paths; 56.46 + 56.47 + /* Configurable methods. */ 56.48 + 56.49 + virtual fileid_t get_fileid(const char *path); 56.50 + 56.51 + virtual Accessor *make_accessor(fileid_t fileid); 56.52 + 56.53 +public: 56.54 + explicit HostFileOpener(Pages *pages) 56.55 + : OpenerResource(pages) 56.56 + { 56.57 + } 56.58 +}; 56.59 + 56.60 +// vim: tabstop=4 expandtab shiftwidth=4
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 57.2 +++ b/libfsserver/include/fsserver/ipc.h Thu Apr 15 23:15:17 2021 +0200 57.3 @@ -0,0 +1,36 @@ 57.4 +/* 57.5 + * Interprocess communication utilities. 57.6 + * 57.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 57.8 + * 57.9 + * This program is free software; you can redistribute it and/or 57.10 + * modify it under the terms of the GNU General Public License as 57.11 + * published by the Free Software Foundation; either version 2 of 57.12 + * the License, or (at your option) any later version. 57.13 + * 57.14 + * This program is distributed in the hope that it will be useful, 57.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 57.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 57.17 + * GNU General Public License for more details. 57.18 + * 57.19 + * You should have received a copy of the GNU General Public License 57.20 + * along with this program; if not, write to the Free Software 57.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 57.22 + * Boston, MA 02110-1301, USA 57.23 + */ 57.24 + 57.25 +#pragma once 57.26 + 57.27 +#include <l4/sys/ipc.h> 57.28 + 57.29 +#include <mem/flexpage.h> 57.30 + 57.31 + 57.32 + 57.33 +long ipc_prepare_flexpage(Flexpage *flexpage, offset_t offset, 57.34 + offset_t max_offset, address_t hot_spot, 57.35 + flags_t flags, l4_snd_fpage_t *region); 57.36 + 57.37 +void ipc_unmap_flexpage(Flexpage *flexpage); 57.38 + 57.39 +// vim: tabstop=4 expandtab shiftwidth=4
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 58.2 +++ b/libfsserver/include/fsserver/opener_context_resource.h Thu Apr 15 23:15:17 2021 +0200 58.3 @@ -0,0 +1,72 @@ 58.4 +/* 58.5 + * A context resource offering support for opening files. 58.6 + * 58.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 58.8 + * 58.9 + * This program is free software; you can redistribute it and/or 58.10 + * modify it under the terms of the GNU General Public License as 58.11 + * published by the Free Software Foundation; either version 2 of 58.12 + * the License, or (at your option) any later version. 58.13 + * 58.14 + * This program is distributed in the hope that it will be useful, 58.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 58.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 58.17 + * GNU General Public License for more details. 58.18 + * 58.19 + * You should have received a copy of the GNU General Public License 58.20 + * along with this program; if not, write to the Free Software 58.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 58.22 + * Boston, MA 02110-1301, USA 58.23 + */ 58.24 + 58.25 +#pragma once 58.26 + 58.27 +#include <fsserver/opener_context_object_interface.h> 58.28 +#include <fsserver/simple_pager.h> 58.29 + 58.30 + 58.31 + 58.32 +/* Forward declaration. */ 58.33 + 58.34 +class OpenerResource; 58.35 + 58.36 + 58.37 + 58.38 +/* Support for indicating files to be opened. */ 58.39 + 58.40 +class OpenerContextResource : public SimplePager, public OpenerContextObject 58.41 +{ 58.42 +protected: 58.43 + OpenerResource *_opener; 58.44 + 58.45 +public: 58.46 + explicit OpenerContextResource(OpenerResource *opener, Memory *memory=NULL); 58.47 + 58.48 + /* Server details. */ 58.49 + 58.50 + int expected_items(); 58.51 + 58.52 + ipc_server_handler_type handler(); 58.53 + 58.54 + void *interface() 58.55 + { return static_cast<OpenerContextObject *>(this); } 58.56 + 58.57 + /* Data access methods. */ 58.58 + 58.59 + char *get_path(); 58.60 + 58.61 + /* Opener context interface methods. */ 58.62 + 58.63 + long open(flags_t flags, offset_t *size, l4_cap_idx_t *file); 58.64 + 58.65 + /* Pager/dataspace methods. */ 58.66 + 58.67 + long map(unsigned long offset, address_t hot_spot, flags_t flags, 58.68 + l4_snd_fpage_t *region) 58.69 + { return SimplePager::map(offset, hot_spot, flags, region); } 58.70 + 58.71 + long info(unsigned long *size, unsigned long *flags) 58.72 + { return SimplePager::info(size, flags); } 58.73 +}; 58.74 + 58.75 +// vim: tabstop=4 expandtab shiftwidth=4
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 59.2 +++ b/libfsserver/include/fsserver/opener_resource.h Thu Apr 15 23:15:17 2021 +0200 59.3 @@ -0,0 +1,59 @@ 59.4 +/* 59.5 + * A resource offering support for creating contexts and opening files. 59.6 + * 59.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 59.8 + * 59.9 + * This program is free software; you can redistribute it and/or 59.10 + * modify it under the terms of the GNU General Public License as 59.11 + * published by the Free Software Foundation; either version 2 of 59.12 + * the License, or (at your option) any later version. 59.13 + * 59.14 + * This program is distributed in the hope that it will be useful, 59.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 59.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 59.17 + * GNU General Public License for more details. 59.18 + * 59.19 + * You should have received a copy of the GNU General Public License 59.20 + * along with this program; if not, write to the Free Software 59.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 59.22 + * Boston, MA 02110-1301, USA 59.23 + */ 59.24 + 59.25 +#pragma once 59.26 + 59.27 +#include <l4/sys/ipc.h> 59.28 + 59.29 +#include <fsserver/file_paging.h> 59.30 +#include <fsserver/opener_context_resource.h> 59.31 +#include <fsserver/opener_interface.h> 59.32 +#include <fsserver/pages.h> 59.33 +#include <fsserver/resource.h> 59.34 + 59.35 + 59.36 + 59.37 +/* Support for providing access to files. */ 59.38 + 59.39 +class OpenerResource : public Resource, public FilePaging, public Opener 59.40 +{ 59.41 +public: 59.42 + explicit OpenerResource(Pages *pages); 59.43 + 59.44 + /* Server details. */ 59.45 + 59.46 + int expected_items(); 59.47 + 59.48 + ipc_server_handler_type handler(); 59.49 + 59.50 + void *interface() 59.51 + { return static_cast<Opener *>(this); } 59.52 + 59.53 + /* Direct access methods. */ 59.54 + 59.55 + Pager *open(const char *path, flags_t flags); 59.56 + 59.57 + /* Opener interface methods. */ 59.58 + 59.59 + long context(l4_cap_idx_t *context); 59.60 +}; 59.61 + 59.62 +// vim: tabstop=4 expandtab shiftwidth=4
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 60.2 +++ b/libfsserver/include/fsserver/page_mapper.h Thu Apr 15 23:15:17 2021 +0200 60.3 @@ -0,0 +1,87 @@ 60.4 +/* 60.5 + * A page mapper providing memory pages to satisfy file accesses. 60.6 + * 60.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 60.8 + * 60.9 + * This program is free software; you can redistribute it and/or 60.10 + * modify it under the terms of the GNU General Public License as 60.11 + * published by the Free Software Foundation; either version 2 of 60.12 + * the License, or (at your option) any later version. 60.13 + * 60.14 + * This program is distributed in the hope that it will be useful, 60.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 60.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 60.17 + * GNU General Public License for more details. 60.18 + * 60.19 + * You should have received a copy of the GNU General Public License 60.20 + * along with this program; if not, write to the Free Software 60.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 60.22 + * Boston, MA 02110-1301, USA 60.23 + */ 60.24 + 60.25 +#pragma once 60.26 + 60.27 +#include <fsserver/access_map.h> 60.28 +#include <fsserver/accessor.h> 60.29 +#include <fsserver/page_owner.h> 60.30 + 60.31 +#include <mutex> 60.32 + 60.33 + 60.34 + 60.35 +/* A file mapper, associating flexpages with file regions. */ 60.36 + 60.37 +class PageMapper : public PageOwner 60.38 +{ 60.39 +protected: 60.40 + AccessMap _map; 60.41 + Accessor *_accessor; 60.42 + Pages *_pages; 60.43 + unsigned int _attached; 60.44 + 60.45 + /* Serialisation of accesses. */ 60.46 + 60.47 + std::mutex _lock; 60.48 + 60.49 + /* Internal flexpage retrieval methods. */ 60.50 + 60.51 + Flexpage *find(offset_t offset); 60.52 + 60.53 + Flexpage *flexpage(offset_t offset); 60.54 + 60.55 +public: 60.56 + explicit PageMapper(Accessor *accessor, Pages *pages); 60.57 + 60.58 + /* Accounting methods. */ 60.59 + 60.60 + void attach(); 60.61 + 60.62 + unsigned int detach(); 60.63 + 60.64 + Accessor *accessor() 60.65 + { return _accessor; } 60.66 + 60.67 + /* Interface for the pager. */ 60.68 + 60.69 + Flexpage *get(offset_t offset, flags_t flags); 60.70 + 60.71 + void queue(Flexpage *flexpage); 60.72 + 60.73 + void flush_all(offset_t start, offset_t size); 60.74 + 60.75 + offset_t get_data_size(); 60.76 + 60.77 + void set_data_size(offset_t size); 60.78 + 60.79 + /* Data transfer methods, implementing PageOwner. */ 60.80 + 60.81 + void fill(Flexpage *flexpage); 60.82 + 60.83 + void flush(Flexpage *flexpage, bool purge); 60.84 + 60.85 + /* Interface for the page collection, implementing PageOwner. */ 60.86 + 60.87 + void remove(Flexpage *flexpage); 60.88 +}; 60.89 + 60.90 +// vim: tabstop=4 expandtab shiftwidth=4
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 61.2 +++ b/libfsserver/include/fsserver/page_owner.h Thu Apr 15 23:15:17 2021 +0200 61.3 @@ -0,0 +1,53 @@ 61.4 +/* 61.5 + * A page owner abstraction, indicating the current user of a memory region. 61.6 + * 61.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 61.8 + * 61.9 + * This program is free software; you can redistribute it and/or 61.10 + * modify it under the terms of the GNU General Public License as 61.11 + * published by the Free Software Foundation; either version 2 of 61.12 + * the License, or (at your option) any later version. 61.13 + * 61.14 + * This program is distributed in the hope that it will be useful, 61.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 61.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 61.17 + * GNU General Public License for more details. 61.18 + * 61.19 + * You should have received a copy of the GNU General Public License 61.20 + * along with this program; if not, write to the Free Software 61.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 61.22 + * Boston, MA 02110-1301, USA 61.23 + */ 61.24 + 61.25 +#pragma once 61.26 + 61.27 +#include <mem/flexpage.h> 61.28 + 61.29 + 61.30 + 61.31 +/* The owner of a flexpage. */ 61.32 + 61.33 +class PageOwner 61.34 +{ 61.35 +public: 61.36 + virtual ~PageOwner() 61.37 + { 61.38 + } 61.39 + 61.40 + virtual void fill(Flexpage *flexpage) 61.41 + { 61.42 + (void) flexpage; 61.43 + } 61.44 + 61.45 + virtual void flush(Flexpage *flexpage, bool purge) 61.46 + { 61.47 + (void) flexpage; (void) purge; 61.48 + } 61.49 + 61.50 + virtual void remove(Flexpage *flexpage) 61.51 + { 61.52 + (void) flexpage; 61.53 + } 61.54 +}; 61.55 + 61.56 +// vim: tabstop=4 expandtab shiftwidth=4
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 62.2 +++ b/libfsserver/include/fsserver/page_queue.h Thu Apr 15 23:15:17 2021 +0200 62.3 @@ -0,0 +1,69 @@ 62.4 +/* 62.5 + * A page queue abstraction. 62.6 + * 62.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 62.8 + * 62.9 + * This program is free software; you can redistribute it and/or 62.10 + * modify it under the terms of the GNU General Public License as 62.11 + * published by the Free Software Foundation; either version 2 of 62.12 + * the License, or (at your option) any later version. 62.13 + * 62.14 + * This program is distributed in the hope that it will be useful, 62.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 62.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 62.17 + * GNU General Public License for more details. 62.18 + * 62.19 + * You should have received a copy of the GNU General Public License 62.20 + * along with this program; if not, write to the Free Software 62.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 62.22 + * Boston, MA 02110-1301, USA 62.23 + */ 62.24 + 62.25 +#pragma once 62.26 + 62.27 +#include <list> 62.28 +#include <map> 62.29 + 62.30 +#include <mem/flexpage.h> 62.31 +#include <mem/memory.h> 62.32 +#include <fsserver/page_owner.h> 62.33 + 62.34 + 62.35 + 62.36 +/* Collection types. */ 62.37 + 62.38 +typedef struct { Flexpage *flexpage; PageOwner *owner; } QueueEntry; 62.39 +typedef std::list<QueueEntry> Queue; 62.40 + 62.41 +typedef std::pair<Flexpage *, Queue::iterator> Position; 62.42 +typedef std::map<Flexpage *, Queue::iterator> Positions; 62.43 + 62.44 + 62.45 + 62.46 +/* A queue of managed pages. */ 62.47 + 62.48 +class PageQueue 62.49 +{ 62.50 +protected: 62.51 + 62.52 + /* Helper methods. */ 62.53 + 62.54 + virtual void discard(Queue &queue, Memory *memory); 62.55 + 62.56 + virtual bool remove(Queue &queue, Positions &positions, PageOwner *owner, Flexpage *flexpage); 62.57 + 62.58 +public: 62.59 + virtual ~PageQueue(); 62.60 + 62.61 + virtual void close(Memory *memory) = 0; 62.62 + 62.63 + virtual void pop(PageOwner **owner, Flexpage **flexpage) = 0; 62.64 + 62.65 + virtual void push(PageOwner *owner, Flexpage *flexpage) = 0; 62.66 + 62.67 + virtual void push_front(PageOwner *owner, Flexpage *flexpage) = 0; 62.68 + 62.69 + virtual bool remove(PageOwner *owner, Flexpage *flexpage) = 0; 62.70 +}; 62.71 + 62.72 +// vim: tabstop=4 expandtab shiftwidth=4
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 63.2 +++ b/libfsserver/include/fsserver/page_queue_partitioned.h Thu Apr 15 23:15:17 2021 +0200 63.3 @@ -0,0 +1,56 @@ 63.4 +/* 63.5 + * A page queue retaining two internal collections of memory pages. 63.6 + * 63.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 63.8 + * 63.9 + * This program is free software; you can redistribute it and/or 63.10 + * modify it under the terms of the GNU General Public License as 63.11 + * published by the Free Software Foundation; either version 2 of 63.12 + * the License, or (at your option) any later version. 63.13 + * 63.14 + * This program is distributed in the hope that it will be useful, 63.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 63.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 63.17 + * GNU General Public License for more details. 63.18 + * 63.19 + * You should have received a copy of the GNU General Public License 63.20 + * along with this program; if not, write to the Free Software 63.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 63.22 + * Boston, MA 02110-1301, USA 63.23 + */ 63.24 + 63.25 +#pragma once 63.26 + 63.27 +#include <condition_variable> 63.28 +#include <mutex> 63.29 + 63.30 +#include <fsserver/page_queue.h> 63.31 + 63.32 + 63.33 + 63.34 +/* Queues of issued and available pages. */ 63.35 + 63.36 +class PageQueuePartitioned : public PageQueue 63.37 +{ 63.38 +protected: 63.39 + Queue _issued, _available; 63.40 + Positions _positions; 63.41 + 63.42 + std::mutex _lock; 63.43 + std::condition_variable _counter; 63.44 + 63.45 + virtual bool _pop(QueueEntry *entry); 63.46 + 63.47 +public: 63.48 + virtual void close(Memory *memory); 63.49 + 63.50 + virtual void pop(PageOwner **owner, Flexpage **flexpage); 63.51 + 63.52 + virtual void push(PageOwner *owner, Flexpage *flexpage); 63.53 + 63.54 + virtual void push_front(PageOwner *owner, Flexpage *flexpage); 63.55 + 63.56 + virtual bool remove(PageOwner *owner, Flexpage *flexpage); 63.57 +}; 63.58 + 63.59 +// vim: tabstop=4 expandtab shiftwidth=4
64.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 64.2 +++ b/libfsserver/include/fsserver/page_queue_shared.h Thu Apr 15 23:15:17 2021 +0200 64.3 @@ -0,0 +1,56 @@ 64.4 +/* 64.5 + * A page queue whose users take turns to access pages. 64.6 + * 64.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 64.8 + * 64.9 + * This program is free software; you can redistribute it and/or 64.10 + * modify it under the terms of the GNU General Public License as 64.11 + * published by the Free Software Foundation; either version 2 of 64.12 + * the License, or (at your option) any later version. 64.13 + * 64.14 + * This program is distributed in the hope that it will be useful, 64.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 64.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 64.17 + * GNU General Public License for more details. 64.18 + * 64.19 + * You should have received a copy of the GNU General Public License 64.20 + * along with this program; if not, write to the Free Software 64.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 64.22 + * Boston, MA 02110-1301, USA 64.23 + */ 64.24 + 64.25 +#pragma once 64.26 + 64.27 +#include <condition_variable> 64.28 +#include <mutex> 64.29 + 64.30 +#include <fsserver/page_queue.h> 64.31 + 64.32 + 64.33 + 64.34 +/* A queue of issued pages. */ 64.35 + 64.36 +class PageQueueShared : public PageQueue 64.37 +{ 64.38 +protected: 64.39 + Queue _queue; 64.40 + Positions _positions; 64.41 + 64.42 + std::mutex _lock; 64.43 + std::condition_variable _counter; 64.44 + 64.45 + virtual bool _pop(QueueEntry *entry); 64.46 + 64.47 +public: 64.48 + virtual void close(Memory *memory); 64.49 + 64.50 + virtual void pop(PageOwner **owner, Flexpage **flexpage); 64.51 + 64.52 + virtual void push(PageOwner *owner, Flexpage *flexpage); 64.53 + 64.54 + virtual void push_front(PageOwner *owner, Flexpage *flexpage); 64.55 + 64.56 + virtual bool remove(PageOwner *owner, Flexpage *flexpage); 64.57 +}; 64.58 + 64.59 +// vim: tabstop=4 expandtab shiftwidth=4
65.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 65.2 +++ b/libfsserver/include/fsserver/pager.h Thu Apr 15 23:15:17 2021 +0200 65.3 @@ -0,0 +1,66 @@ 65.4 +/* 65.5 + * Generic pager functionality. 65.6 + * 65.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 65.8 + * 65.9 + * This program is free software; you can redistribute it and/or 65.10 + * modify it under the terms of the GNU General Public License as 65.11 + * published by the Free Software Foundation; either version 2 of 65.12 + * the License, or (at your option) any later version. 65.13 + * 65.14 + * This program is distributed in the hope that it will be useful, 65.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 65.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 65.17 + * GNU General Public License for more details. 65.18 + * 65.19 + * You should have received a copy of the GNU General Public License 65.20 + * along with this program; if not, write to the Free Software 65.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 65.22 + * Boston, MA 02110-1301, USA 65.23 + */ 65.24 + 65.25 +#pragma once 65.26 + 65.27 +#include <systypes/base.h> 65.28 + 65.29 +#include <fsserver/page_mapper.h> 65.30 +#include <fsserver/resource.h> 65.31 + 65.32 + 65.33 + 65.34 +/* A pager exposing a dataspace. */ 65.35 + 65.36 +class Pager : public Resource 65.37 +{ 65.38 +protected: 65.39 + offset_t _start, _size; 65.40 + PageMapper *_mapper; 65.41 + flags_t _flags; 65.42 + 65.43 +public: 65.44 + explicit Pager(PageMapper *mapper, flags_t flags); 65.45 + 65.46 + virtual void close(); 65.47 + 65.48 + /* Paging methods. */ 65.49 + 65.50 + virtual long map(offset_t offset, address_t hot_spot, flags_t flags, 65.51 + l4_snd_fpage_t *region); 65.52 + 65.53 + /* Limit methods. */ 65.54 + 65.55 + offset_t get_data_size(); 65.56 + 65.57 + /* File methods. */ 65.58 + 65.59 + virtual long flush(offset_t populated_size, offset_t *size); 65.60 + 65.61 + virtual long resize(offset_t *size); 65.62 + 65.63 + /* Mapped file methods. */ 65.64 + 65.65 + virtual long mmap(offset_t position, offset_t length, offset_t *start_pos, 65.66 + offset_t *end_pos, offset_t *size); 65.67 +}; 65.68 + 65.69 +// vim: tabstop=4 expandtab shiftwidth=4
66.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 66.2 +++ b/libfsserver/include/fsserver/pages.h Thu Apr 15 23:15:17 2021 +0200 66.3 @@ -0,0 +1,55 @@ 66.4 +/* 66.5 + * A page collection abstraction providing pages from a queue to users. 66.6 + * 66.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 66.8 + * 66.9 + * This program is free software; you can redistribute it and/or 66.10 + * modify it under the terms of the GNU General Public License as 66.11 + * published by the Free Software Foundation; either version 2 of 66.12 + * the License, or (at your option) any later version. 66.13 + * 66.14 + * This program is distributed in the hope that it will be useful, 66.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 66.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 66.17 + * GNU General Public License for more details. 66.18 + * 66.19 + * You should have received a copy of the GNU General Public License 66.20 + * along with this program; if not, write to the Free Software 66.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 66.22 + * Boston, MA 02110-1301, USA 66.23 + */ 66.24 + 66.25 +#pragma once 66.26 + 66.27 +#include <mem/flexpage.h> 66.28 +#include <mem/memory.h> 66.29 +#include <fsserver/page_owner.h> 66.30 +#include <fsserver/page_queue.h> 66.31 + 66.32 + 66.33 + 66.34 +/* A page collection. */ 66.35 + 66.36 +class Pages 66.37 +{ 66.38 +protected: 66.39 + Memory *_memory; 66.40 + PageQueue *_queue; 66.41 + 66.42 +public: 66.43 + explicit Pages(Memory *memory, PageQueue *queue); 66.44 + 66.45 + virtual ~Pages(); 66.46 + 66.47 + virtual Flexpage *remove(); 66.48 + 66.49 + virtual bool reserve(PageOwner *owner, Flexpage *flexpage); 66.50 + 66.51 + virtual Flexpage *flexpage(); 66.52 + 66.53 + virtual void queue(PageOwner *owner, Flexpage *flexpage); 66.54 + 66.55 + virtual void release(Flexpage *flexpage); 66.56 +}; 66.57 + 66.58 +// vim: tabstop=4 expandtab shiftwidth=4
67.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 67.2 +++ b/libfsserver/include/fsserver/pipe_accessor.h Thu Apr 15 23:15:17 2021 +0200 67.3 @@ -0,0 +1,48 @@ 67.4 +/* 67.5 + * A pipe accessor merely resetting allocated memory for use. 67.6 + * 67.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 67.8 + * 67.9 + * This program is free software; you can redistribute it and/or 67.10 + * modify it under the terms of the GNU General Public License as 67.11 + * published by the Free Software Foundation; either version 2 of 67.12 + * the License, or (at your option) any later version. 67.13 + * 67.14 + * This program is distributed in the hope that it will be useful, 67.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 67.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 67.17 + * GNU General Public License for more details. 67.18 + * 67.19 + * You should have received a copy of the GNU General Public License 67.20 + * along with this program; if not, write to the Free Software 67.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 67.22 + * Boston, MA 02110-1301, USA 67.23 + */ 67.24 + 67.25 +#pragma once 67.26 + 67.27 +#include <fsserver/accessor.h> 67.28 + 67.29 + 67.30 + 67.31 +/* A pipe accessor, providing flexpages for pipe sections. */ 67.32 + 67.33 +class PipeAccessor : public Accessor 67.34 +{ 67.35 +protected: 67.36 + 67.37 + /* Data transfer helper methods. */ 67.38 + 67.39 + virtual void fill_populated(Flexpage *flexpage); 67.40 + 67.41 + virtual void flush_populated(Flexpage *flexpage); 67.42 + 67.43 +public: 67.44 + explicit PipeAccessor(); 67.45 + 67.46 + virtual void close(); 67.47 + 67.48 + virtual void open(); 67.49 +}; 67.50 + 67.51 +// vim: tabstop=4 expandtab shiftwidth=4
68.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 68.2 +++ b/libfsserver/include/fsserver/pipe_opener_resource.h Thu Apr 15 23:15:17 2021 +0200 68.3 @@ -0,0 +1,57 @@ 68.4 +/* 68.5 + * A pipe opener resource. 68.6 + * 68.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 68.8 + * 68.9 + * This program is free software; you can redistribute it and/or 68.10 + * modify it under the terms of the GNU General Public License as 68.11 + * published by the Free Software Foundation; either version 2 of 68.12 + * the License, or (at your option) any later version. 68.13 + * 68.14 + * This program is distributed in the hope that it will be useful, 68.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 68.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 68.17 + * GNU General Public License for more details. 68.18 + * 68.19 + * You should have received a copy of the GNU General Public License 68.20 + * along with this program; if not, write to the Free Software 68.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 68.22 + * Boston, MA 02110-1301, USA 68.23 + */ 68.24 + 68.25 +#pragma once 68.26 + 68.27 +#include <mem/memory.h> 68.28 +#include <fsserver/pipe_opener_interface.h> 68.29 +#include <fsserver/pipe_paging.h> 68.30 +#include <fsserver/resource.h> 68.31 + 68.32 + 68.33 + 68.34 +/* Support for providing access to pipes. */ 68.35 + 68.36 +class PipeOpenerResource : public Resource, public PipeOpener 68.37 +{ 68.38 +protected: 68.39 + Memory *_memory; 68.40 + 68.41 + long open_endpoint(PipePaging *paging, bool writing, l4_cap_idx_t *endpoint); 68.42 + 68.43 +public: 68.44 + explicit PipeOpenerResource(Memory *memory); 68.45 + 68.46 + /* Server details. */ 68.47 + 68.48 + int expected_items(); 68.49 + 68.50 + ipc_server_handler_type handler(); 68.51 + 68.52 + void *interface() 68.53 + { return static_cast<PipeOpener *>(this); } 68.54 + 68.55 + /* PipeOpener interface methods. */ 68.56 + 68.57 + long pipe(offset_t size, l4_cap_idx_t *reader, l4_cap_idx_t *writer); 68.58 +}; 68.59 + 68.60 +// vim: tabstop=4 expandtab shiftwidth=4
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 69.2 +++ b/libfsserver/include/fsserver/pipe_pager.h Thu Apr 15 23:15:17 2021 +0200 69.3 @@ -0,0 +1,70 @@ 69.4 +/* 69.5 + * A pipe pager providing access to pipe content and navigation support. 69.6 + * 69.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 69.8 + * 69.9 + * This program is free software; you can redistribute it and/or 69.10 + * modify it under the terms of the GNU General Public License as 69.11 + * published by the Free Software Foundation; either version 2 of 69.12 + * the License, or (at your option) any later version. 69.13 + * 69.14 + * This program is distributed in the hope that it will be useful, 69.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 69.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 69.17 + * GNU General Public License for more details. 69.18 + * 69.19 + * You should have received a copy of the GNU General Public License 69.20 + * along with this program; if not, write to the Free Software 69.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 69.22 + * Boston, MA 02110-1301, USA 69.23 + */ 69.24 + 69.25 +#pragma once 69.26 + 69.27 +#include <fsserver/pipe_accessor.h> 69.28 +#include <fsserver/pipe_object_interface.h> 69.29 +#include <fsserver/pipe_paging.h> 69.30 +#include <fsserver/pager.h> 69.31 + 69.32 + 69.33 + 69.34 +/* A pager abstraction for a pipe. */ 69.35 + 69.36 +class PipePager : public Pager, public PipeObject 69.37 +{ 69.38 +protected: 69.39 + PipePaging *_paging; 69.40 + bool _writing; 69.41 + 69.42 + /* Helper methods. */ 69.43 + 69.44 + virtual long next_region_for_reader(offset_t *populated_size, offset_t *size); 69.45 + 69.46 + virtual long next_region_for_writer(offset_t *populated_size, offset_t *size); 69.47 + 69.48 +public: 69.49 + explicit PipePager(PipePaging *paging, bool writer); 69.50 + 69.51 + virtual void close(); 69.52 + 69.53 + /* Server details. */ 69.54 + 69.55 + int expected_items(); 69.56 + 69.57 + ipc_server_handler_type handler(); 69.58 + 69.59 + void *interface() 69.60 + { return static_cast<PipeObject *>(this); } 69.61 + 69.62 + /* Pager methods. */ 69.63 + 69.64 + virtual long map(offset_t offset, address_t hot_spot, flags_t flags, l4_snd_fpage_t *region); 69.65 + 69.66 + /* Pipe methods. */ 69.67 + 69.68 + virtual long current_region(offset_t *populated_size, offset_t *size); 69.69 + 69.70 + virtual long next_region(offset_t *populated_size, offset_t *size); 69.71 +}; 69.72 + 69.73 +// vim: tabstop=4 expandtab shiftwidth=4
70.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 70.2 +++ b/libfsserver/include/fsserver/pipe_paging.h Thu Apr 15 23:15:17 2021 +0200 70.3 @@ -0,0 +1,74 @@ 70.4 +/* 70.5 + * A pipe paging coordinator, permitting memory sharing pipe endpoints. 70.6 + * 70.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 70.8 + * 70.9 + * This program is free software; you can redistribute it and/or 70.10 + * modify it under the terms of the GNU General Public License as 70.11 + * published by the Free Software Foundation; either version 2 of 70.12 + * the License, or (at your option) any later version. 70.13 + * 70.14 + * This program is distributed in the hope that it will be useful, 70.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 70.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 70.17 + * GNU General Public License for more details. 70.18 + * 70.19 + * You should have received a copy of the GNU General Public License 70.20 + * along with this program; if not, write to the Free Software 70.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 70.22 + * Boston, MA 02110-1301, USA 70.23 + */ 70.24 + 70.25 +#pragma once 70.26 + 70.27 +#include <fsserver/page_mapper.h> 70.28 +#include <fsserver/pages.h> 70.29 +#include <fsserver/pipe_accessor.h> 70.30 + 70.31 + 70.32 + 70.33 +/* Pipe paging support, maintaining the sequence of active regions or sections 70.34 + in a pipe. */ 70.35 + 70.36 +class PipePaging 70.37 +{ 70.38 +protected: 70.39 + Memory *_memory; 70.40 + Pages *_pages; 70.41 + PageQueue *_queue; 70.42 + 70.43 + /* Regions acting as files with their own accessors. */ 70.44 + 70.45 + PageMapper *_regions[2]; 70.46 + PipeAccessor _accessors[2]; 70.47 + 70.48 + /* The first region is initially exposed to both reader and writer. */ 70.49 + 70.50 + int _reading = 0, _writing = 0; 70.51 + 70.52 + /* Pipe section/region size. */ 70.53 + 70.54 + offset_t _size; 70.55 + 70.56 + /* Endpoint status. */ 70.57 + 70.58 + unsigned int _endpoints = 2; 70.59 + 70.60 +public: 70.61 + explicit PipePaging(Memory *memory, offset_t size); 70.62 + 70.63 + virtual void detach(); 70.64 + 70.65 + virtual offset_t region_size() 70.66 + { return _size; } 70.67 + 70.68 + /* Region management. */ 70.69 + 70.70 + virtual PageMapper *add_region(); 70.71 + 70.72 + virtual PageMapper *current_region(); 70.73 + 70.74 + virtual PageMapper *next_region(); 70.75 +}; 70.76 + 70.77 +// vim: tabstop=4 expandtab shiftwidth=4
71.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 71.2 +++ b/libfsserver/include/fsserver/resource.h Thu Apr 15 23:15:17 2021 +0200 71.3 @@ -0,0 +1,56 @@ 71.4 +/* 71.5 + * Common resource classes and functions. 71.6 + * 71.7 + * Copyright (C) 2018, 2019, 2020 Paul Boddie <paul@boddie.org.uk> 71.8 + * 71.9 + * This program is free software; you can redistribute it and/or 71.10 + * modify it under the terms of the GNU General Public License as 71.11 + * published by the Free Software Foundation; either version 2 of 71.12 + * the License, or (at your option) any later version. 71.13 + * 71.14 + * This program is distributed in the hope that it will be useful, 71.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 71.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 71.17 + * GNU General Public License for more details. 71.18 + * 71.19 + * You should have received a copy of the GNU General Public License 71.20 + * along with this program; if not, write to the Free Software 71.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 71.22 + * Boston, MA 02110-1301, USA 71.23 + */ 71.24 + 71.25 +#pragma once 71.26 + 71.27 +#include <ipc/server.h> 71.28 + 71.29 + 71.30 + 71.31 +/* A generic class for an object potentially needing to be closed after use. */ 71.32 + 71.33 +class Resource 71.34 +{ 71.35 +public: 71.36 + virtual ~Resource() 71.37 + { 71.38 + } 71.39 + 71.40 + /* Server details. */ 71.41 + 71.42 + virtual int expected_items() = 0; 71.43 + 71.44 + virtual ipc_server_handler_type handler() = 0; 71.45 + 71.46 + virtual void *interface() = 0; 71.47 + 71.48 + /* Deallocation of resources. */ 71.49 + 71.50 + virtual void close() 71.51 + { 71.52 + } 71.53 + 71.54 + /* Activation. */ 71.55 + 71.56 + virtual void activate() 71.57 + { 71.58 + } 71.59 +};
72.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 72.2 +++ b/libfsserver/include/fsserver/resource_server.h Thu Apr 15 23:15:17 2021 +0200 72.3 @@ -0,0 +1,76 @@ 72.4 +/* 72.5 + * Common resource server functions. 72.6 + * 72.7 + * Copyright (C) 2018, 2019, 2020 Paul Boddie <paul@boddie.org.uk> 72.8 + * 72.9 + * This program is free software; you can redistribute it and/or 72.10 + * modify it under the terms of the GNU General Public License as 72.11 + * published by the Free Software Foundation; either version 2 of 72.12 + * the License, or (at your option) any later version. 72.13 + * 72.14 + * This program is distributed in the hope that it will be useful, 72.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 72.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 72.17 + * GNU General Public License for more details. 72.18 + * 72.19 + * You should have received a copy of the GNU General Public License 72.20 + * along with this program; if not, write to the Free Software 72.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 72.22 + * Boston, MA 02110-1301, USA 72.23 + */ 72.24 + 72.25 +#pragma once 72.26 + 72.27 +#include <fsserver/resource.h> 72.28 +#include <ipc/server.h> 72.29 + 72.30 + 72.31 + 72.32 +/* Convenience abstraction for blocking servers. */ 72.33 + 72.34 +class ResourceServer 72.35 +{ 72.36 +protected: 72.37 + Resource *_resource; 72.38 + ipc_server_config_type *_config; 72.39 + 72.40 +public: 72.41 + explicit ResourceServer(Resource *resource) 72.42 + : _resource(resource) 72.43 + { 72.44 + _config = new ipc_server_config_type; 72.45 + ipc_server_init_config(_config); 72.46 + } 72.47 + 72.48 + /* Access to configuration. */ 72.49 + 72.50 + ipc_server_config_type *config() 72.51 + { return _config; } 72.52 + 72.53 + /* Server IPC gate allocation. */ 72.54 + 72.55 + long bind(const char *name); 72.56 + 72.57 + /* Server initiation. */ 72.58 + 72.59 + long start(); 72.60 + 72.61 + long start_thread(); 72.62 +}; 72.63 + 72.64 + 72.65 + 72.66 +/* Server initialisation. */ 72.67 + 72.68 +void resource_init_config(ipc_server_config_type *config, Resource *resource); 72.69 + 72.70 +void resource_set_config_threaded(ipc_server_config_type *config, 72.71 + l4_cap_idx_t thread, int new_thread); 72.72 + 72.73 +/* Server initiation. */ 72.74 + 72.75 +long resource_start_config(ipc_server_config_type *config, Resource *resource); 72.76 + 72.77 +/* Server finalisation. */ 72.78 + 72.79 +void resource_thread_finaliser(ipc_server_config_type *config);
73.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 73.2 +++ b/libfsserver/include/fsserver/simple_pager.h Thu Apr 15 23:15:17 2021 +0200 73.3 @@ -0,0 +1,51 @@ 73.4 +/* 73.5 + * A simple pager exposing a single memory region. 73.6 + * 73.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 73.8 + * 73.9 + * This program is free software; you can redistribute it and/or 73.10 + * modify it under the terms of the GNU General Public License as 73.11 + * published by the Free Software Foundation; either version 2 of 73.12 + * the License, or (at your option) any later version. 73.13 + * 73.14 + * This program is distributed in the hope that it will be useful, 73.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 73.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 73.17 + * GNU General Public License for more details. 73.18 + * 73.19 + * You should have received a copy of the GNU General Public License 73.20 + * along with this program; if not, write to the Free Software 73.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 73.22 + * Boston, MA 02110-1301, USA 73.23 + */ 73.24 + 73.25 +#pragma once 73.26 + 73.27 +#include <fsserver/dataspace_interface.h> 73.28 +#include <mem/flexpage.h> 73.29 +#include <mem/memory.h> 73.30 +#include <fsserver/resource.h> 73.31 + 73.32 + 73.33 + 73.34 +/* A simple pager exposing a single memory region as a dataspace. */ 73.35 + 73.36 +class SimplePager : public Dataspace, public Resource 73.37 +{ 73.38 +protected: 73.39 + Memory *_memory; 73.40 + Region *_region; 73.41 + 73.42 +public: 73.43 + explicit SimplePager(Memory *memory=NULL); 73.44 + 73.45 + void close(); 73.46 + 73.47 + /* Paging methods. */ 73.48 + 73.49 + long map(offset_t offset, address_t hot_spot, flags_t flags, l4_snd_fpage_t *region); 73.50 + 73.51 + long info(offset_t *size, flags_t *flags); 73.52 +}; 73.53 + 73.54 +// vim: tabstop=4 expandtab shiftwidth=4
74.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 74.2 +++ b/libfsserver/include/fsserver/test_file_accessor.h Thu Apr 15 23:15:17 2021 +0200 74.3 @@ -0,0 +1,44 @@ 74.4 +/* 74.5 + * A test accessor producing generated content. 74.6 + * 74.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 74.8 + * 74.9 + * This program is free software; you can redistribute it and/or 74.10 + * modify it under the terms of the GNU General Public License as 74.11 + * published by the Free Software Foundation; either version 2 of 74.12 + * the License, or (at your option) any later version. 74.13 + * 74.14 + * This program is distributed in the hope that it will be useful, 74.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 74.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 74.17 + * GNU General Public License for more details. 74.18 + * 74.19 + * You should have received a copy of the GNU General Public License 74.20 + * along with this program; if not, write to the Free Software 74.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 74.22 + * Boston, MA 02110-1301, USA 74.23 + */ 74.24 + 74.25 +#pragma once 74.26 + 74.27 +#include <fsserver/accessor.h> 74.28 + 74.29 + 74.30 + 74.31 +/* A file accessor, providing flexpages corresponding to file regions. */ 74.32 + 74.33 +class TestFileAccessor : public Accessor 74.34 +{ 74.35 +protected: 74.36 + 74.37 + /* Data transfer helper methods. */ 74.38 + 74.39 + virtual void fill_populated(Flexpage *flexpage); 74.40 + 74.41 + virtual void flush_populated(Flexpage *flexpage); 74.42 + 74.43 +public: 74.44 + explicit TestFileAccessor(fileid_t fileid, offset_t size=0); 74.45 +}; 74.46 + 74.47 +// vim: tabstop=4 expandtab shiftwidth=4
75.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 75.2 +++ b/libfsserver/include/fsserver/test_file_opener.h Thu Apr 15 23:15:17 2021 +0200 75.3 @@ -0,0 +1,45 @@ 75.4 +/* 75.5 + * An opener for a test file containing generated content. 75.6 + * 75.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 75.8 + * 75.9 + * This program is free software; you can redistribute it and/or 75.10 + * modify it under the terms of the GNU General Public License as 75.11 + * published by the Free Software Foundation; either version 2 of 75.12 + * the License, or (at your option) any later version. 75.13 + * 75.14 + * This program is distributed in the hope that it will be useful, 75.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 75.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 75.17 + * GNU General Public License for more details. 75.18 + * 75.19 + * You should have received a copy of the GNU General Public License 75.20 + * along with this program; if not, write to the Free Software 75.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 75.22 + * Boston, MA 02110-1301, USA 75.23 + */ 75.24 + 75.25 +#pragma once 75.26 + 75.27 +#include <fsserver/opener_resource.h> 75.28 + 75.29 + 75.30 + 75.31 +/* Support for providing access to files. */ 75.32 + 75.33 +class TestFileOpener : public OpenerResource 75.34 +{ 75.35 +protected: 75.36 + offset_t _file_size; 75.37 + 75.38 + /* Configurable methods. */ 75.39 + 75.40 + virtual fileid_t get_fileid(const char *path); 75.41 + 75.42 + virtual Accessor *make_accessor(fileid_t fileid); 75.43 + 75.44 +public: 75.45 + explicit TestFileOpener(Pages *pages, offset_t file_size=0); 75.46 +}; 75.47 + 75.48 +// vim: tabstop=4 expandtab shiftwidth=4
76.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 76.2 +++ b/libfsserver/lib/Makefile Thu Apr 15 23:15:17 2021 +0200 76.3 @@ -0,0 +1,80 @@ 76.4 +PKGDIR ?= .. 76.5 +L4DIR ?= $(PKGDIR)/../../.. 76.6 + 76.7 +TARGET = libfsserver.so libfsserver.a 76.8 +PC_FILENAME = libfsserver 76.9 + 76.10 +# Locations for interface input and generated output. 76.11 + 76.12 +IDL_DIR = $(L4DIR)/pkg/libsystypes/idl 76.13 +IDL_MK_DIR = $(L4DIR)/idl4re/mk 76.14 +IDL_BUILD_DIR = . 76.15 +IDL_EXPORT_DIR = $(OBJ_BASE)/include/contrib/$(CONTRIB_INCDIR)/fsserver 76.16 + 76.17 +include $(IDL_MK_DIR)/idl.mk 76.18 + 76.19 +# Compound interfaces. 76.20 + 76.21 +mapped_file_object_NAME = MappedFileObject 76.22 +mapped_file_object_INTERFACES = dataspace file mapped_file 76.23 + 76.24 +opener_context_object_NAME = OpenerContextObject 76.25 +opener_context_object_INTERFACES = dataspace opener_context 76.26 + 76.27 +pipe_object_NAME = PipeObject 76.28 +pipe_object_INTERFACES = dataspace pipe 76.29 + 76.30 +COMP_INTERFACES_CC = mapped_file_object opener_context_object pipe_object 76.31 + 76.32 +# Individual interfaces. 76.33 + 76.34 +SERVER_INTERFACES_CC = opener pipe_opener $(call common_interfaces,$(COMP_INTERFACES_CC)) 76.35 + 76.36 +# Generated and plain source files. 76.37 + 76.38 +SERVER_INTERFACES_SRC_CC = $(call interfaces_to_server_cc,$(SERVER_INTERFACES_CC) $(COMP_INTERFACES_CC)) 76.39 + 76.40 +PLAIN_SRC_CC = \ 76.41 + files/block_file_accessor.cc \ 76.42 + files/block_file_opener.cc \ 76.43 + files/file_pager.cc \ 76.44 + files/file_paging.cc \ 76.45 + files/host_file_accessor.cc \ 76.46 + files/host_file_opener.cc \ 76.47 + files/opener_context_resource.cc \ 76.48 + files/opener_resource.cc \ 76.49 + files/test_file_accessor.cc \ 76.50 + files/test_file_opener.cc \ 76.51 + generic/accessor.cc \ 76.52 + generic/pager.cc \ 76.53 + generic/resource_server.cc \ 76.54 + generic/simple_pager.cc \ 76.55 + mapping/access_map.cc \ 76.56 + mapping/ipc.cc \ 76.57 + mapping/page_mapper.cc \ 76.58 + pages/page_queue.cc \ 76.59 + pages/page_queue_partitioned.cc \ 76.60 + pages/page_queue_shared.cc \ 76.61 + pages/pages.cc \ 76.62 + pipes/pipe_accessor.cc \ 76.63 + pipes/pipe_opener_resource.cc \ 76.64 + pipes/pipe_pager.cc \ 76.65 + pipes/pipe_paging.cc 76.66 + 76.67 +# Normal definitions. 76.68 + 76.69 +SRC_CC = \ 76.70 + $(SERVER_INTERFACES_SRC_CC) \ 76.71 + $(PLAIN_SRC_CC) 76.72 + 76.73 +REQUIRES_LIBS = l4re_c-util libmem libipc libstdc++ libsystypes 76.74 + 76.75 +PRIVATE_INCDIR = $(PKGDIR)/include $(PKGDIR)/include/fsserver \ 76.76 + $(IDL_BUILD_DIR) $(IDL_EXPORT_DIR) 76.77 + 76.78 +CONTRIB_INCDIR = libfsserver 76.79 + 76.80 +include $(L4DIR)/mk/lib.mk 76.81 +include $(IDL_MK_DIR)/interface_rules.mk 76.82 + 76.83 +$(PLAIN_SRC_CC): $(SERVER_INTERFACES_SRC_CC)
77.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 77.2 +++ b/libfsserver/lib/files/block_file_accessor.cc Thu Apr 15 23:15:17 2021 +0200 77.3 @@ -0,0 +1,127 @@ 77.4 +/* 77.5 + * A file accessor employing a rewritable memory area. 77.6 + * 77.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 77.8 + * 77.9 + * This program is free software; you can redistribute it and/or 77.10 + * modify it under the terms of the GNU General Public License as 77.11 + * published by the Free Software Foundation; either version 2 of 77.12 + * the License, or (at your option) any later version. 77.13 + * 77.14 + * This program is distributed in the hope that it will be useful, 77.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 77.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 77.17 + * GNU General Public License for more details. 77.18 + * 77.19 + * You should have received a copy of the GNU General Public License 77.20 + * along with this program; if not, write to the Free Software 77.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 77.22 + * Boston, MA 02110-1301, USA 77.23 + */ 77.24 + 77.25 +#include <stdio.h> 77.26 +#include <string.h> 77.27 +#include <sys/types.h> 77.28 +#include <sys/stat.h> 77.29 + 77.30 +#include <algorithm> 77.31 + 77.32 +#include "block_file_accessor.h" 77.33 + 77.34 + 77.35 + 77.36 +BlockFileAccessor::BlockFileAccessor(const char *path, fileid_t fileid) 77.37 +: Accessor(fileid) 77.38 +{ 77.39 + /* Obtain the size of the file. */ 77.40 + 77.41 + struct stat buf; 77.42 + 77.43 + if (stat(path, &buf)) 77.44 + { 77.45 + _size = 0; 77.46 + return; 77.47 + } 77.48 + 77.49 + /* Allocate memory. */ 77.50 + 77.51 + _size = buf.st_size; 77.52 + _data = (char *) malloc(_size); 77.53 + 77.54 + if (_data == NULL) 77.55 + return; 77.56 + 77.57 + /* Load the file into memory and initialise the size. */ 77.58 + 77.59 + FILE *fp = fopen(path, "r"); 77.60 + 77.61 + if (fp == NULL) 77.62 + { 77.63 + free(_data); 77.64 + return; 77.65 + } 77.66 + 77.67 + _size = fread(_data, sizeof(char), _size, fp); 77.68 + 77.69 + fclose(fp); 77.70 +} 77.71 + 77.72 +/* Update the size of the file. */ 77.73 + 77.74 +void BlockFileAccessor::set_size(offset_t size) 77.75 +{ 77.76 + void *new_data = realloc(_data, size); 77.77 + 77.78 + if (new_data != NULL) 77.79 + { 77.80 + _data = (char *) new_data; 77.81 + 77.82 + if (size > _size) 77.83 + memset(_data + _size, 0, size - _size); 77.84 + 77.85 + Accessor::set_size(size); 77.86 + } 77.87 +} 77.88 + 77.89 +/* Data transfer helper methods. */ 77.90 + 77.91 +/* Fill the populated portion of a flexpage. */ 77.92 + 77.93 +void BlockFileAccessor::fill_populated(Flexpage *flexpage) 77.94 +{ 77.95 + offset_t filepos = flexpage->base_offset; 77.96 + offset_t addr = flexpage->base_addr; 77.97 + offset_t populated_size = std::min(flexpage->size, _size - filepos); 77.98 + 77.99 + /* Tag the region with file state. */ 77.100 + 77.101 + flexpage->region->fill(fileid, filepos); 77.102 + 77.103 + /* Fill the region with file content. */ 77.104 + 77.105 + memcpy((void *) addr, _data + filepos, populated_size); 77.106 + 77.107 + /* Pad the flexpage with zero. */ 77.108 + 77.109 + if (populated_size < flexpage->size) 77.110 + memset((void *) (addr + populated_size), 0, flexpage->size - populated_size); 77.111 +} 77.112 + 77.113 +/* Flush the populated portion of a flexpage. */ 77.114 + 77.115 +void BlockFileAccessor::flush_populated(Flexpage *flexpage) 77.116 +{ 77.117 + offset_t filepos = flexpage->base_offset; 77.118 + offset_t addr = flexpage->base_addr; 77.119 + offset_t populated_size = std::min(flexpage->size, _size - filepos); 77.120 + 77.121 + /* Remove the file state tag from the region. */ 77.122 + 77.123 + flexpage->region->flush(); 77.124 + 77.125 + /* Copy the populated region to the block memory. */ 77.126 + 77.127 + memcpy((void *) (_data + filepos), (const void *) addr, populated_size); 77.128 +} 77.129 + 77.130 +// vim: tabstop=4 expandtab shiftwidth=4
78.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 78.2 +++ b/libfsserver/lib/files/block_file_opener.cc Thu Apr 15 23:15:17 2021 +0200 78.3 @@ -0,0 +1,37 @@ 78.4 +/* 78.5 + * An opener for a file employing a rewritable memory area. 78.6 + * 78.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 78.8 + * 78.9 + * This program is free software; you can redistribute it and/or 78.10 + * modify it under the terms of the GNU General Public License as 78.11 + * published by the Free Software Foundation; either version 2 of 78.12 + * the License, or (at your option) any later version. 78.13 + * 78.14 + * This program is distributed in the hope that it will be useful, 78.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 78.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 78.17 + * GNU General Public License for more details. 78.18 + * 78.19 + * You should have received a copy of the GNU General Public License 78.20 + * along with this program; if not, write to the Free Software 78.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 78.22 + * Boston, MA 02110-1301, USA 78.23 + */ 78.24 + 78.25 +#include "block_file_accessor.h" 78.26 +#include "block_file_opener.h" 78.27 + 78.28 +/* Return a new accessor for 'fileid'. */ 78.29 + 78.30 +Accessor *BlockFileOpener::make_accessor(fileid_t fileid) 78.31 +{ 78.32 + FilePaths::iterator found = _paths.find(fileid); 78.33 + 78.34 + if (found != _paths.end()) 78.35 + return new BlockFileAccessor(found->second, fileid); 78.36 + else 78.37 + return NULL; 78.38 +} 78.39 + 78.40 +// vim: tabstop=4 expandtab shiftwidth=4
79.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 79.2 +++ b/libfsserver/lib/files/file_pager.cc Thu Apr 15 23:15:17 2021 +0200 79.3 @@ -0,0 +1,87 @@ 79.4 +/* 79.5 + * File-specific pager functionality. 79.6 + * 79.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 79.8 + * 79.9 + * This program is free software; you can redistribute it and/or 79.10 + * modify it under the terms of the GNU General Public License as 79.11 + * published by the Free Software Foundation; either version 2 of 79.12 + * the License, or (at your option) any later version. 79.13 + * 79.14 + * This program is distributed in the hope that it will be useful, 79.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 79.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 79.17 + * GNU General Public License for more details. 79.18 + * 79.19 + * You should have received a copy of the GNU General Public License 79.20 + * along with this program; if not, write to the Free Software 79.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 79.22 + * Boston, MA 02110-1301, USA 79.23 + */ 79.24 + 79.25 +#include "file_pager.h" 79.26 +#include "mapped_file_object_server.h" 79.27 + 79.28 + 79.29 + 79.30 +/* Initialise a pager for a file with a unique file identifier and shared page 79.31 + mapper for moderating access to loaded pages. */ 79.32 + 79.33 +FilePager::FilePager(fileid_t fileid, PageMapper *mapper, flags_t flags, 79.34 + FilePaging *paging) 79.35 +: Pager(mapper, flags), _paging(paging), fileid(fileid) 79.36 +{ 79.37 +} 79.38 + 79.39 +int FilePager::expected_items() 79.40 +{ 79.41 + return MappedFileObject_expected_items; 79.42 +} 79.43 + 79.44 +ipc_server_handler_type FilePager::handler() 79.45 +{ 79.46 + return (ipc_server_handler_type) handle_MappedFileObject; 79.47 +} 79.48 + 79.49 + 79.50 + 79.51 +/* Close the pager, removing the mapper from the paging registry if 79.52 + appropriate. */ 79.53 + 79.54 +void FilePager::close() 79.55 +{ 79.56 + _paging->detach_pager(fileid, _mapper); 79.57 +} 79.58 + 79.59 + 79.60 + 79.61 +/* File-specific operations. */ 79.62 + 79.63 +long FilePager::flush(offset_t populated_size, offset_t *size) 79.64 +{ 79.65 + return Pager::flush(populated_size, size); 79.66 +} 79.67 + 79.68 +long FilePager::resize(offset_t *size) 79.69 +{ 79.70 + return Pager::resize(size); 79.71 +} 79.72 + 79.73 +long FilePager::mmap(offset_t position, offset_t length, offset_t *start_pos, 79.74 + offset_t *end_pos, offset_t *size) 79.75 +{ 79.76 + /* Set the limits of the paged region. */ 79.77 + 79.78 + return Pager::mmap(position, length, start_pos, end_pos, size); 79.79 +} 79.80 + 79.81 + 79.82 + 79.83 +/* Generic pager operations. */ 79.84 + 79.85 +long FilePager::map(offset_t offset, address_t hot_spot, flags_t flags, l4_snd_fpage_t *region) 79.86 +{ 79.87 + return Pager::map(offset, hot_spot, flags, region); 79.88 +} 79.89 + 79.90 +// vim: tabstop=4 expandtab shiftwidth=4
80.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 80.2 +++ b/libfsserver/lib/files/file_paging.cc Thu Apr 15 23:15:17 2021 +0200 80.3 @@ -0,0 +1,128 @@ 80.4 +/* 80.5 + * General functionality supporting file paging. 80.6 + * 80.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 80.8 + * 80.9 + * This program is free software; you can redistribute it and/or 80.10 + * modify it under the terms of the GNU General Public License as 80.11 + * published by the Free Software Foundation; either version 2 of 80.12 + * the License, or (at your option) any later version. 80.13 + * 80.14 + * This program is distributed in the hope that it will be useful, 80.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 80.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 80.17 + * GNU General Public License for more details. 80.18 + * 80.19 + * You should have received a copy of the GNU General Public License 80.20 + * along with this program; if not, write to the Free Software 80.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 80.22 + * Boston, MA 02110-1301, USA 80.23 + */ 80.24 + 80.25 +#include "file_pager.h" 80.26 +#include "file_paging.h" 80.27 + 80.28 +#include <systypes/fcntl.h> 80.29 + 80.30 + 80.31 + 80.32 +FilePaging::FilePaging(Pages *pages) 80.33 +: _pages(pages) 80.34 +{ 80.35 +} 80.36 + 80.37 +FilePaging::~FilePaging() 80.38 +{ 80.39 +} 80.40 + 80.41 + 80.42 + 80.43 +/* Return any registered page mapper for the given 'fileid' or NULL if no such 80.44 + mapper is registered. */ 80.45 + 80.46 +PageMapper *FilePaging::get(fileid_t fileid) 80.47 +{ 80.48 + FileMapping::iterator entry = _mappers.find(fileid); 80.49 + PageMapper *mapper; 80.50 + 80.51 + if (entry == _mappers.end()) 80.52 + mapper = NULL; 80.53 + else 80.54 + mapper = entry->second; 80.55 + 80.56 + return mapper; 80.57 +} 80.58 + 80.59 +/* Register a page 'mapper' for the given 'fileid'. */ 80.60 + 80.61 +void FilePaging::set(fileid_t fileid, PageMapper *mapper) 80.62 +{ 80.63 + FileMapping::iterator entry = _mappers.find(fileid); 80.64 + 80.65 + if (entry == _mappers.end()) 80.66 + _mappers[fileid] = mapper; 80.67 +} 80.68 + 80.69 + 80.70 + 80.71 +/* Convert opening flags to map-compatible paging flags. */ 80.72 + 80.73 +flags_t FilePaging::get_flags(flags_t flags) 80.74 +{ 80.75 + return flags & (O_WRONLY | O_RDWR) ? L4RE_DS_MAP_FLAG_RW : L4RE_DS_MAP_FLAG_RO; 80.76 +} 80.77 + 80.78 + 80.79 + 80.80 +/* Obtain a page mapper for the 'fileid' or register a new one in the 80.81 + paging object. */ 80.82 + 80.83 +PageMapper *FilePaging::get_mapper(fileid_t fileid) 80.84 +{ 80.85 + /* Obtain any registered page mapper. */ 80.86 + 80.87 + PageMapper *mapper = get(fileid); 80.88 + 80.89 + if (mapper != NULL) 80.90 + return mapper; 80.91 + 80.92 + /* Make an accessor and page mapper, registering the mapper. */ 80.93 + 80.94 + Accessor *accessor = make_accessor(fileid); 80.95 + mapper = new PageMapper(accessor, _pages); 80.96 + 80.97 + set(fileid, mapper); 80.98 + 80.99 + return mapper; 80.100 +} 80.101 + 80.102 + 80.103 + 80.104 +/* Return a pager initialised with a page mapper. */ 80.105 + 80.106 +Pager *FilePaging::get_pager(fileid_t fileid, flags_t flags) 80.107 +{ 80.108 + std::lock_guard<std::mutex> guard(_lock); 80.109 + 80.110 + /* Initialise the pager with the mapper and a reference to this object for 80.111 + closing the mapper and accessor. */ 80.112 + 80.113 + PageMapper *mapper = get_mapper(fileid); 80.114 + return new FilePager(fileid, mapper, flags, this); 80.115 +} 80.116 + 80.117 +/* Detach a pager, potentially removing its resources. */ 80.118 + 80.119 +void FilePaging::detach_pager(fileid_t fileid, PageMapper *mapper) 80.120 +{ 80.121 + std::lock_guard<std::mutex> guard(_lock); 80.122 + 80.123 + if (!mapper->detach()) 80.124 + { 80.125 + _mappers.erase(fileid); 80.126 + delete mapper->accessor(); 80.127 + delete mapper; 80.128 + } 80.129 +} 80.130 + 80.131 +// vim: tabstop=4 expandtab shiftwidth=4
81.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 81.2 +++ b/libfsserver/lib/files/host_file_accessor.cc Thu Apr 15 23:15:17 2021 +0200 81.3 @@ -0,0 +1,85 @@ 81.4 +/* 81.5 + * A file accessor employing a "host" file provided via the C library. 81.6 + * 81.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 81.8 + * 81.9 + * This program is free software; you can redistribute it and/or 81.10 + * modify it under the terms of the GNU General Public License as 81.11 + * published by the Free Software Foundation; either version 2 of 81.12 + * the License, or (at your option) any later version. 81.13 + * 81.14 + * This program is distributed in the hope that it will be useful, 81.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 81.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 81.17 + * GNU General Public License for more details. 81.18 + * 81.19 + * You should have received a copy of the GNU General Public License 81.20 + * along with this program; if not, write to the Free Software 81.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 81.22 + * Boston, MA 02110-1301, USA 81.23 + */ 81.24 + 81.25 +#include <stdio.h> 81.26 +#include <string.h> 81.27 +#include <sys/types.h> 81.28 +#include <sys/stat.h> 81.29 + 81.30 +#include "host_file_accessor.h" 81.31 + 81.32 +HostFileAccessor::HostFileAccessor(const char *path, fileid_t fileid) 81.33 +: Accessor(fileid), _path(path) 81.34 +{ 81.35 + /* Initialise the size of the file. */ 81.36 + 81.37 + struct stat buf; 81.38 + 81.39 + if (!stat(_path, &buf)) 81.40 + _size = buf.st_size; 81.41 + else 81.42 + _size = 0; 81.43 +} 81.44 + 81.45 +/* Perform any closing operation on the file. */ 81.46 + 81.47 +void HostFileAccessor::close() 81.48 +{ 81.49 + fclose(_fp); 81.50 +} 81.51 + 81.52 +/* Perform any opening operation on the file. */ 81.53 + 81.54 +void HostFileAccessor::open() 81.55 +{ 81.56 + _fp = fopen(_path, "r"); 81.57 +} 81.58 + 81.59 +/* Data transfer helper methods. */ 81.60 + 81.61 +void HostFileAccessor::fill_populated(Flexpage *flexpage) 81.62 +{ 81.63 + offset_t filepos = flexpage->base_offset; 81.64 + offset_t addr = flexpage->base_addr; 81.65 + 81.66 + /* Seek to the offset in the file. */ 81.67 + 81.68 + fseek(_fp, filepos, SEEK_SET); 81.69 + 81.70 + /* Tag the region with file state. */ 81.71 + 81.72 + flexpage->region->fill(fileid, filepos); 81.73 + 81.74 + /* Fill the region with file content. */ 81.75 + 81.76 + size_t nread = fread((void *) addr, sizeof(char), flexpage->size, _fp); 81.77 + 81.78 + /* Pad the flexpage with zero. */ 81.79 + 81.80 + memset((void *) (addr + nread), 0, flexpage->size - nread); 81.81 +} 81.82 + 81.83 +void HostFileAccessor::flush_populated(Flexpage *flexpage) 81.84 +{ 81.85 + flexpage->region->flush(); 81.86 +} 81.87 + 81.88 +// vim: tabstop=4 expandtab shiftwidth=4
82.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 82.2 +++ b/libfsserver/lib/files/host_file_opener.cc Thu Apr 15 23:15:17 2021 +0200 82.3 @@ -0,0 +1,55 @@ 82.4 +/* 82.5 + * An opener for a "host" file provided via the C library. 82.6 + * 82.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 82.8 + * 82.9 + * This program is free software; you can redistribute it and/or 82.10 + * modify it under the terms of the GNU General Public License as 82.11 + * published by the Free Software Foundation; either version 2 of 82.12 + * the License, or (at your option) any later version. 82.13 + * 82.14 + * This program is distributed in the hope that it will be useful, 82.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 82.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 82.17 + * GNU General Public License for more details. 82.18 + * 82.19 + * You should have received a copy of the GNU General Public License 82.20 + * along with this program; if not, write to the Free Software 82.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 82.22 + * Boston, MA 02110-1301, USA 82.23 + */ 82.24 + 82.25 +#include <sys/stat.h> 82.26 + 82.27 +#include "host_file_accessor.h" 82.28 +#include "host_file_opener.h" 82.29 + 82.30 +/* Return a file identifier for the given 'path'. */ 82.31 + 82.32 +fileid_t HostFileOpener::get_fileid(const char *path) 82.33 +{ 82.34 + struct stat statbuf; 82.35 + 82.36 + /* Obtain the inode number. 82.37 + NOTE: This does not handle errors! */ 82.38 + 82.39 + stat(path, &statbuf); 82.40 + 82.41 + _paths.insert(FilePathEntry(statbuf.st_ino, path)); 82.42 + 82.43 + return statbuf.st_ino; 82.44 +} 82.45 + 82.46 +/* Return a new accessor for 'fileid'. */ 82.47 + 82.48 +Accessor *HostFileOpener::make_accessor(fileid_t fileid) 82.49 +{ 82.50 + FilePaths::iterator found = _paths.find(fileid); 82.51 + 82.52 + if (found != _paths.end()) 82.53 + return new HostFileAccessor(found->second, fileid); 82.54 + else 82.55 + return NULL; 82.56 +} 82.57 + 82.58 +// vim: tabstop=4 expandtab shiftwidth=4
83.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 83.2 +++ b/libfsserver/lib/files/opener_context_resource.cc Thu Apr 15 23:15:17 2021 +0200 83.3 @@ -0,0 +1,96 @@ 83.4 +/* 83.5 + * A context resource offering support for opening files. 83.6 + * 83.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 83.8 + * 83.9 + * This program is free software; you can redistribute it and/or 83.10 + * modify it under the terms of the GNU General Public License as 83.11 + * published by the Free Software Foundation; either version 2 of 83.12 + * the License, or (at your option) any later version. 83.13 + * 83.14 + * This program is distributed in the hope that it will be useful, 83.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 83.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 83.17 + * GNU General Public License for more details. 83.18 + * 83.19 + * You should have received a copy of the GNU General Public License 83.20 + * along with this program; if not, write to the Free Software 83.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 83.22 + * Boston, MA 02110-1301, USA 83.23 + */ 83.24 + 83.25 +#include "opener_context_resource.h" 83.26 +#include "opener_context_object_server.h" 83.27 +#include "opener_resource.h" 83.28 +#include "resource_server.h" 83.29 + 83.30 +#include <string.h> 83.31 + 83.32 + 83.33 + 83.34 +/* Support for providing access to files. */ 83.35 + 83.36 +OpenerContextResource::OpenerContextResource(OpenerResource *opener, Memory *memory) 83.37 +: SimplePager(memory), _opener(opener) 83.38 +{ 83.39 +} 83.40 + 83.41 +int OpenerContextResource::expected_items() 83.42 +{ 83.43 + return OpenerContextObject_expected_items; 83.44 +} 83.45 + 83.46 +ipc_server_handler_type OpenerContextResource::handler() 83.47 +{ 83.48 + return (ipc_server_handler_type) handle_OpenerContextObject; 83.49 +} 83.50 + 83.51 + 83.52 + 83.53 +/* Data access methods. */ 83.54 + 83.55 +char *OpenerContextResource::get_path() 83.56 +{ 83.57 + char *buffer = _region->read(); 83.58 + offset_t size = _region->size(); 83.59 + 83.60 + /* Confine the path to the limit of the buffer. */ 83.61 + 83.62 + if ((buffer != NULL) && (strnlen(buffer, size) < size)) 83.63 + return buffer; 83.64 + else 83.65 + return NULL; 83.66 +} 83.67 + 83.68 + 83.69 + 83.70 +/* Opener context interface methods. */ 83.71 + 83.72 +long OpenerContextResource::open(flags_t flags, offset_t *size, l4_cap_idx_t *file) 83.73 +{ 83.74 + char *path = get_path(); 83.75 + 83.76 + if (path == NULL) 83.77 + return -L4_EINVAL; 83.78 + 83.79 + Pager *pager = _opener->open(path, flags); 83.80 + 83.81 + /* Complete the initialisation and start a server in a new thread. 83.82 + If the thread does not start, the resource should be finalised. */ 83.83 + 83.84 + ResourceServer server(pager); 83.85 + long err = server.start_thread(); 83.86 + 83.87 + if (!err) 83.88 + { 83.89 + /* Return the file size. */ 83.90 + /* Return the server capability to the caller. */ 83.91 + 83.92 + *size = pager->get_data_size(); 83.93 + *file = server.config()->server; 83.94 + } 83.95 + 83.96 + return err; 83.97 +} 83.98 + 83.99 +// vim: tabstop=4 expandtab shiftwidth=4
84.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 84.2 +++ b/libfsserver/lib/files/opener_resource.cc Thu Apr 15 23:15:17 2021 +0200 84.3 @@ -0,0 +1,79 @@ 84.4 +/* 84.5 + * A resource offering support for creating contexts and opening files. 84.6 + * 84.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 84.8 + * 84.9 + * This program is free software; you can redistribute it and/or 84.10 + * modify it under the terms of the GNU General Public License as 84.11 + * published by the Free Software Foundation; either version 2 of 84.12 + * the License, or (at your option) any later version. 84.13 + * 84.14 + * This program is distributed in the hope that it will be useful, 84.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 84.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 84.17 + * GNU General Public License for more details. 84.18 + * 84.19 + * You should have received a copy of the GNU General Public License 84.20 + * along with this program; if not, write to the Free Software 84.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 84.22 + * Boston, MA 02110-1301, USA 84.23 + */ 84.24 + 84.25 +#include "opener_server.h" 84.26 +#include "opener_resource.h" 84.27 +#include "resource_server.h" 84.28 + 84.29 +/* Support for providing access to files. */ 84.30 + 84.31 +OpenerResource::OpenerResource(Pages *pages) 84.32 +: FilePaging(pages) 84.33 +{ 84.34 +} 84.35 + 84.36 +int OpenerResource::expected_items() 84.37 +{ 84.38 + return Opener_expected_items; 84.39 +} 84.40 + 84.41 +ipc_server_handler_type OpenerResource::handler() 84.42 +{ 84.43 + return (ipc_server_handler_type) handle_Opener; 84.44 +} 84.45 + 84.46 + 84.47 + 84.48 +/* Return a pager object for the given path and flags. */ 84.49 + 84.50 +Pager *OpenerResource::open(const char *path, flags_t flags) 84.51 +{ 84.52 + fileid_t fileid = get_fileid(path); 84.53 + 84.54 + if (fileid == FILEID_INVALID) 84.55 + return NULL; 84.56 + 84.57 + return get_pager(fileid, get_flags(flags)); 84.58 +} 84.59 + 84.60 + 84.61 + 84.62 +/* Opener interface methods. */ 84.63 + 84.64 +long OpenerResource::context(l4_cap_idx_t *context) 84.65 +{ 84.66 + OpenerContextResource *resource = new OpenerContextResource(this); 84.67 + 84.68 + /* Complete the initialisation and start a server in a new thread. 84.69 + If the thread does not start, the resource should be finalised. */ 84.70 + 84.71 + ResourceServer server(resource); 84.72 + long err = server.start_thread(); 84.73 + 84.74 + /* Return the server capability to the caller. */ 84.75 + 84.76 + if (!err) 84.77 + *context = server.config()->server; 84.78 + 84.79 + return err; 84.80 +} 84.81 + 84.82 +// vim: tabstop=4 expandtab shiftwidth=4
85.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 85.2 +++ b/libfsserver/lib/files/test_file_accessor.cc Thu Apr 15 23:15:17 2021 +0200 85.3 @@ -0,0 +1,72 @@ 85.4 +/* 85.5 + * A test accessor producing generated content. 85.6 + * 85.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 85.8 + * 85.9 + * This program is free software; you can redistribute it and/or 85.10 + * modify it under the terms of the GNU General Public License as 85.11 + * published by the Free Software Foundation; either version 2 of 85.12 + * the License, or (at your option) any later version. 85.13 + * 85.14 + * This program is distributed in the hope that it will be useful, 85.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 85.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 85.17 + * GNU General Public License for more details. 85.18 + * 85.19 + * You should have received a copy of the GNU General Public License 85.20 + * along with this program; if not, write to the Free Software 85.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 85.22 + * Boston, MA 02110-1301, USA 85.23 + */ 85.24 + 85.25 +#include <stdio.h> 85.26 +#include <string.h> 85.27 + 85.28 +#include "test_file_accessor.h" 85.29 + 85.30 +TestFileAccessor::TestFileAccessor(fileid_t fileid, offset_t size) 85.31 +: Accessor(fileid, size) 85.32 +{ 85.33 +} 85.34 + 85.35 +/* Data transfer helper methods. */ 85.36 + 85.37 +void TestFileAccessor::fill_populated(Flexpage *flexpage) 85.38 +{ 85.39 + Region *region = flexpage->region; 85.40 + offset_t filepos = flexpage->base_offset; 85.41 + 85.42 + /* Tag the region with file state. */ 85.43 + 85.44 + region->fill(fileid, filepos); 85.45 + 85.46 + /* Write some data to each page of the flexpage in each region. This 85.47 + allows each page to be tested regardless of how large each flexpage 85.48 + or region is. */ 85.49 + 85.50 + offset_t addr = flexpage->base_addr; 85.51 + offset_t limit = addr + flexpage->size; 85.52 + 85.53 + while (addr < limit) 85.54 + { 85.55 + /* Overwrite enough of any previous data to make the new data 85.56 + readable. */ 85.57 + 85.58 + char tag[32]; 85.59 + 85.60 + sprintf(tag, "%ld:%ld", fileid, filepos); 85.61 + 85.62 + memset((void *) addr, 0, strlen(tag) + 1); 85.63 + strcpy((char *) addr, tag); 85.64 + 85.65 + filepos += PAGE_SIZE; 85.66 + addr += PAGE_SIZE; 85.67 + } 85.68 +} 85.69 + 85.70 +void TestFileAccessor::flush_populated(Flexpage *flexpage) 85.71 +{ 85.72 + flexpage->region->flush(); 85.73 +} 85.74 + 85.75 +// vim: tabstop=4 expandtab shiftwidth=4
86.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 86.2 +++ b/libfsserver/lib/files/test_file_opener.cc Thu Apr 15 23:15:17 2021 +0200 86.3 @@ -0,0 +1,50 @@ 86.4 +/* 86.5 + * An opener for a test file containing generated content. 86.6 + * 86.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 86.8 + * 86.9 + * This program is free software; you can redistribute it and/or 86.10 + * modify it under the terms of the GNU General Public License as 86.11 + * published by the Free Software Foundation; either version 2 of 86.12 + * the License, or (at your option) any later version. 86.13 + * 86.14 + * This program is distributed in the hope that it will be useful, 86.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 86.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 86.17 + * GNU General Public License for more details. 86.18 + * 86.19 + * You should have received a copy of the GNU General Public License 86.20 + * along with this program; if not, write to the Free Software 86.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 86.22 + * Boston, MA 02110-1301, USA 86.23 + */ 86.24 + 86.25 +#include "test_file_accessor.h" 86.26 +#include "test_file_opener.h" 86.27 + 86.28 +#include <stdlib.h> 86.29 + 86.30 +/* Support for providing access to files. */ 86.31 + 86.32 +TestFileOpener::TestFileOpener(Pages *pages, offset_t file_size) 86.33 +: OpenerResource(pages), _file_size(file_size) 86.34 +{ 86.35 +} 86.36 + 86.37 +/* Return a file identifier for the given 'path'. */ 86.38 + 86.39 +fileid_t TestFileOpener::get_fileid(const char *path) 86.40 +{ 86.41 + /* NOTE: Just convert the path to a number. */ 86.42 + 86.43 + return atol(path); 86.44 +} 86.45 + 86.46 +/* Return a new accessor for 'fileid'. */ 86.47 + 86.48 +Accessor *TestFileOpener::make_accessor(fileid_t fileid) 86.49 +{ 86.50 + return new TestFileAccessor(fileid, _file_size); 86.51 +} 86.52 + 86.53 +// vim: tabstop=4 expandtab shiftwidth=4
87.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 87.2 +++ b/libfsserver/lib/generic/accessor.cc Thu Apr 15 23:15:17 2021 +0200 87.3 @@ -0,0 +1,98 @@ 87.4 +/* 87.5 + * Generic accessor functionality. 87.6 + * 87.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 87.8 + * 87.9 + * This program is free software; you can redistribute it and/or 87.10 + * modify it under the terms of the GNU General Public License as 87.11 + * published by the Free Software Foundation; either version 2 of 87.12 + * the License, or (at your option) any later version. 87.13 + * 87.14 + * This program is distributed in the hope that it will be useful, 87.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 87.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 87.17 + * GNU General Public License for more details. 87.18 + * 87.19 + * You should have received a copy of the GNU General Public License 87.20 + * along with this program; if not, write to the Free Software 87.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 87.22 + * Boston, MA 02110-1301, USA 87.23 + */ 87.24 + 87.25 +#include "accessor.h" 87.26 + 87.27 +#include <string.h> 87.28 + 87.29 + 87.30 + 87.31 +Accessor::Accessor(fileid_t fileid, offset_t size) 87.32 +: _size(size), fileid(fileid) 87.33 +{ 87.34 +} 87.35 + 87.36 +Accessor::~Accessor() 87.37 +{ 87.38 +} 87.39 + 87.40 +/* Return the size of the file. */ 87.41 + 87.42 +offset_t Accessor::get_size() 87.43 +{ 87.44 + return _size; 87.45 +} 87.46 + 87.47 +/* Update the size of the file. */ 87.48 + 87.49 +void Accessor::set_size(offset_t size) 87.50 +{ 87.51 + _size = size; 87.52 +} 87.53 + 87.54 +/* Perform any closing operation on the file. */ 87.55 + 87.56 +void Accessor::close() 87.57 +{ 87.58 +} 87.59 + 87.60 +/* Perform any opening operation on the file. */ 87.61 + 87.62 +void Accessor::open() 87.63 +{ 87.64 +} 87.65 + 87.66 +/* Data transfer methods. */ 87.67 + 87.68 +void Accessor::fill(Flexpage *flexpage) 87.69 +{ 87.70 + /* Filling completely beyond the end of file should produce an empty 87.71 + flexpage. This could potentially be a shared read-only flexpage that 87.72 + would be replaced by an independent writable flexpage if ever written. */ 87.73 + 87.74 + if (flexpage->base_offset < _size) 87.75 + fill_populated(flexpage); 87.76 + else 87.77 + memset((void *) flexpage->base_addr, 0, flexpage->size); 87.78 +} 87.79 + 87.80 +void Accessor::flush(Flexpage *flexpage) 87.81 +{ 87.82 + /* Flushing completely beyond the end of file should discard the 87.83 + flexpage. */ 87.84 + 87.85 + if (flexpage->base_offset < _size) 87.86 + flush_populated(flexpage); 87.87 +} 87.88 + 87.89 +/* Data transfer helper methods. */ 87.90 + 87.91 +void Accessor::fill_populated(Flexpage *flexpage) 87.92 +{ 87.93 + (void) flexpage; 87.94 +} 87.95 + 87.96 +void Accessor::flush_populated(Flexpage *flexpage) 87.97 +{ 87.98 + (void) flexpage; 87.99 +} 87.100 + 87.101 +// vim: tabstop=4 expandtab shiftwidth=4
88.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 88.2 +++ b/libfsserver/lib/generic/pager.cc Thu Apr 15 23:15:17 2021 +0200 88.3 @@ -0,0 +1,128 @@ 88.4 +/* 88.5 + * Generic pager functionality. 88.6 + * 88.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 88.8 + * 88.9 + * This program is free software; you can redistribute it and/or 88.10 + * modify it under the terms of the GNU General Public License as 88.11 + * published by the Free Software Foundation; either version 2 of 88.12 + * the License, or (at your option) any later version. 88.13 + * 88.14 + * This program is distributed in the hope that it will be useful, 88.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 88.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 88.17 + * GNU General Public License for more details. 88.18 + * 88.19 + * You should have received a copy of the GNU General Public License 88.20 + * along with this program; if not, write to the Free Software 88.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 88.22 + * Boston, MA 02110-1301, USA 88.23 + */ 88.24 + 88.25 +#include "dataspace_server.h" 88.26 +#include "ipc.h" 88.27 +#include "pager.h" 88.28 + 88.29 + 88.30 + 88.31 +/* Initialise the pager with a page mapper and the given flags controlling 88.32 + access to a file. */ 88.33 + 88.34 +Pager::Pager(PageMapper *mapper, flags_t flags) 88.35 +: _start(0), _size(0), _mapper(mapper), _flags(flags) 88.36 +{ 88.37 + /* Some pagers may not be initialised with a mapper. */ 88.38 + 88.39 + if (_mapper != NULL) 88.40 + _mapper->attach(); 88.41 +} 88.42 + 88.43 +/* Close the pager. */ 88.44 + 88.45 +void Pager::close() 88.46 +{ 88.47 + if (_mapper != NULL) 88.48 + _mapper->detach(); 88.49 +} 88.50 + 88.51 +/* Flush data to the file. */ 88.52 + 88.53 +long Pager::flush(offset_t populated_size, offset_t *size) 88.54 +{ 88.55 + _mapper->flush_all(_start, populated_size); 88.56 + 88.57 + *size = _mapper->get_data_size(); 88.58 + return L4_EOK; 88.59 +} 88.60 + 88.61 +/* Resize the underlying file. */ 88.62 + 88.63 +long Pager::resize(offset_t *size) 88.64 +{ 88.65 + _mapper->set_data_size(*size); 88.66 + 88.67 + *size = _mapper->get_data_size(); 88.68 + return L4_EOK; 88.69 +} 88.70 + 88.71 +/* Expose a region of the file. */ 88.72 + 88.73 +long Pager::mmap(offset_t position, offset_t length, offset_t *start_pos, 88.74 + offset_t *end_pos, offset_t *size) 88.75 +{ 88.76 + /* Define region characteristics. */ 88.77 + 88.78 + _start = trunc(position, PAGE_SIZE); 88.79 + _size = round(position + length, PAGE_SIZE) - _start; 88.80 + 88.81 + /* Return the start and end positions plus populated extent. */ 88.82 + 88.83 + *start_pos = _start; 88.84 + *end_pos = _start + _size; 88.85 + *size = _mapper->get_data_size(); 88.86 + 88.87 + return L4_EOK; 88.88 +} 88.89 + 88.90 +/* Map a flexpage corresponding to the dataspace 'offset' involving a 'hot_spot' 88.91 + (flexpage offset). */ 88.92 + 88.93 +long Pager::map(offset_t offset, address_t hot_spot, flags_t flags, 88.94 + l4_snd_fpage_t *region) 88.95 +{ 88.96 + offset_t file_offset = _start + offset; 88.97 + offset_t max_offset = _start + _size; 88.98 + 88.99 + /* Prevent access beyond that defined by the pager. */ 88.100 + 88.101 + if (flags & ~_flags) 88.102 + return -L4_EACCESS; 88.103 + 88.104 + Flexpage *flexpage = _mapper->get(file_offset, flags); 88.105 + 88.106 + /* Issue the flexpage via the IPC system. */ 88.107 + 88.108 + long err = ipc_prepare_flexpage(flexpage, file_offset, max_offset, hot_spot, 88.109 + flags, region); 88.110 + 88.111 + if (!err) 88.112 + err = complete_Dataspace_map(*region); 88.113 + 88.114 + /* After the flexpage is issued, it is queued for future reuse. */ 88.115 + 88.116 + _mapper->queue(flexpage); 88.117 + 88.118 + if (err) 88.119 + return err; 88.120 + 88.121 + return IPC_MESSAGE_SENT; 88.122 +} 88.123 + 88.124 +/* Return the total size of the data. */ 88.125 + 88.126 +offset_t Pager::get_data_size() 88.127 +{ 88.128 + return _mapper->get_data_size(); 88.129 +} 88.130 + 88.131 +// vim: tabstop=4 expandtab shiftwidth=4
89.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 89.2 +++ b/libfsserver/lib/generic/resource_server.cc Thu Apr 15 23:15:17 2021 +0200 89.3 @@ -0,0 +1,131 @@ 89.4 +/* 89.5 + * Resource server functionality. 89.6 + * 89.7 + * Copyright (C) 2018, 2019, 2020, 2021 Paul Boddie <paul@boddie.org.uk> 89.8 + * 89.9 + * This program is free software; you can redistribute it and/or 89.10 + * modify it under the terms of the GNU General Public License as 89.11 + * published by the Free Software Foundation; either version 2 of 89.12 + * the License, or (at your option) any later version. 89.13 + * 89.14 + * This program is distributed in the hope that it will be useful, 89.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 89.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 89.17 + * GNU General Public License for more details. 89.18 + * 89.19 + * You should have received a copy of the GNU General Public License 89.20 + * along with this program; if not, write to the Free Software 89.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 89.22 + * Boston, MA 02110-1301, USA 89.23 + */ 89.24 + 89.25 +#include <l4/sys/types.h> 89.26 + 89.27 +#include <pthread-l4.h> 89.28 +#include <pthread.h> 89.29 + 89.30 +#include "resource_server.h" 89.31 + 89.32 + 89.33 + 89.34 +/* Convenience server methods. */ 89.35 + 89.36 +/* Bind to a named IPC gate capability. */ 89.37 + 89.38 +long ResourceServer::bind(const char *name) 89.39 +{ 89.40 + return ipc_server_bind(name, (l4_umword_t) _resource, &_config->server); 89.41 +} 89.42 + 89.43 +/* Start in the same thread with no deletion notifications or finalisation. */ 89.44 + 89.45 +long ResourceServer::start() 89.46 +{ 89.47 + resource_init_config(_config, _resource); 89.48 + _config->thread = pthread_l4_cap(pthread_self()); 89.49 + return resource_start_config(_config, _resource); 89.50 +} 89.51 + 89.52 +/* Start a new thread with deletion notifications and finalisation. */ 89.53 + 89.54 +long ResourceServer::start_thread() 89.55 +{ 89.56 + pthread_t thread; 89.57 + pthread_attr_t attr; 89.58 + long err; 89.59 + 89.60 + pthread_attr_init(&attr); 89.61 + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 89.62 + 89.63 + resource_init_config(_config, _resource); 89.64 + 89.65 + err = pthread_create(&thread, &attr, ipc_server_start_mainloop, _config); 89.66 + if (err) 89.67 + return err; 89.68 + 89.69 + resource_set_config_threaded(_config, pthread_l4_cap(thread), 1); 89.70 + 89.71 + return resource_start_config(_config, _resource); 89.72 +} 89.73 + 89.74 + 89.75 + 89.76 +/* Initialise a server configuration for a resource. */ 89.77 + 89.78 +void resource_init_config(ipc_server_config_type *config, Resource *resource) 89.79 +{ 89.80 + config->handler_obj = resource->interface(); 89.81 + config->finaliser_obj = resource; 89.82 + config->expected_items = resource->expected_items(); 89.83 + config->handler = resource->handler(); 89.84 +} 89.85 + 89.86 +/* Set a configuration to be threaded. */ 89.87 + 89.88 +void resource_set_config_threaded(ipc_server_config_type *config, 89.89 + l4_cap_idx_t thread, int new_thread) 89.90 +{ 89.91 + config->finaliser = resource_thread_finaliser; 89.92 + config->new_thread = new_thread; 89.93 + config->thread = thread; 89.94 + config->notifications = 1; 89.95 +} 89.96 + 89.97 +/* Activate a resource and start a server for it. */ 89.98 + 89.99 +long resource_start_config(ipc_server_config_type *config, Resource *resource) 89.100 +{ 89.101 + resource->activate(); 89.102 + long err = ipc_server_start_config(config); 89.103 + 89.104 + /* Discard any server resources if starting it failed. */ 89.105 + 89.106 + if (err) 89.107 + { 89.108 + ipc_server_finalise_config(config); 89.109 + ipc_server_discard_thread(config); 89.110 + } 89.111 + 89.112 + return err; 89.113 +} 89.114 + 89.115 + 89.116 + 89.117 +/* A finaliser for exposed resources. */ 89.118 + 89.119 +void resource_thread_finaliser(ipc_server_config_type *config) 89.120 +{ 89.121 + Resource *resource = reinterpret_cast<Resource *>(config->finaliser_obj); 89.122 + 89.123 + /* Close and delete the resource. */ 89.124 + 89.125 + resource->close(); 89.126 + delete resource; 89.127 + 89.128 + /* Release the capabilities. */ 89.129 + 89.130 + ipc_server_finalise_config(config); 89.131 + delete config; 89.132 +} 89.133 + 89.134 +// vim: tabstop=2 expandtab shiftwidth=2
90.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 90.2 +++ b/libfsserver/lib/generic/simple_pager.cc Thu Apr 15 23:15:17 2021 +0200 90.3 @@ -0,0 +1,85 @@ 90.4 +/* 90.5 + * A simple pager exposing a single memory region. 90.6 + * 90.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 90.8 + * 90.9 + * This program is free software; you can redistribute it and/or 90.10 + * modify it under the terms of the GNU General Public License as 90.11 + * published by the Free Software Foundation; either version 2 of 90.12 + * the License, or (at your option) any later version. 90.13 + * 90.14 + * This program is distributed in the hope that it will be useful, 90.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 90.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 90.17 + * GNU General Public License for more details. 90.18 + * 90.19 + * You should have received a copy of the GNU General Public License 90.20 + * along with this program; if not, write to the Free Software 90.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 90.22 + * Boston, MA 02110-1301, USA 90.23 + */ 90.24 + 90.25 +#include <l4/re/c/dataspace.h> 90.26 + 90.27 +#include <mem/memory_incremental.h> 90.28 + 90.29 +#include "dataspace_server.h" 90.30 +#include "ipc.h" 90.31 +#include "simple_pager.h" 90.32 + 90.33 + 90.34 + 90.35 +SimplePager::SimplePager(Memory *memory) 90.36 +{ 90.37 + if (memory == NULL) 90.38 + _memory = new MemoryIncremental(); 90.39 + else 90.40 + _memory = memory; 90.41 + 90.42 + _region = _memory->region(); 90.43 +} 90.44 + 90.45 +void SimplePager::close() 90.46 +{ 90.47 + if (_region != NULL) 90.48 + { 90.49 + _memory->release(_region); 90.50 + _region = NULL; 90.51 + } 90.52 +} 90.53 + 90.54 +/* Map a flexpage corresponding to the dataspace 'offset' involving a 'hot_spot' 90.55 + (flexpage offset). */ 90.56 + 90.57 +long SimplePager::map(offset_t offset, address_t hot_spot, flags_t flags, l4_snd_fpage_t *region) 90.58 +{ 90.59 + Flexpage flexpage(_region); 90.60 + 90.61 + flexpage.reset(offset); 90.62 + flexpage.upgrade(flags); 90.63 + 90.64 + /* Send the flexpage explicitly. */ 90.65 + 90.66 + long err = ipc_prepare_flexpage(&flexpage, offset, _region->size(), 90.67 + hot_spot, flags, region); 90.68 + 90.69 + if (err) 90.70 + return err; 90.71 + 90.72 + err = complete_Dataspace_map(*region); 90.73 + 90.74 + if (err) 90.75 + return err; 90.76 + 90.77 + return IPC_MESSAGE_SENT; 90.78 +} 90.79 + 90.80 +long SimplePager::info(offset_t *size, flags_t *flags) 90.81 +{ 90.82 + *size = _region->size(); 90.83 + *flags = L4_FPAGE_RW; 90.84 + 90.85 + return L4_EOK; 90.86 +} 90.87 + 90.88 +// vim: tabstop=4 expandtab shiftwidth=4
91.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 91.2 +++ b/libfsserver/lib/mapping/access_map.cc Thu Apr 15 23:15:17 2021 +0200 91.3 @@ -0,0 +1,155 @@ 91.4 +/* 91.5 + * An access map providing memory corresponding to file regions. 91.6 + * 91.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 91.8 + * 91.9 + * This program is free software; you can redistribute it and/or 91.10 + * modify it under the terms of the GNU General Public License as 91.11 + * published by the Free Software Foundation; either version 2 of 91.12 + * the License, or (at your option) any later version. 91.13 + * 91.14 + * This program is distributed in the hope that it will be useful, 91.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 91.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 91.17 + * GNU General Public License for more details. 91.18 + * 91.19 + * You should have received a copy of the GNU General Public License 91.20 + * along with this program; if not, write to the Free Software 91.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 91.22 + * Boston, MA 02110-1301, USA 91.23 + */ 91.24 + 91.25 +#include "access_map.h" 91.26 + 91.27 +/* Return the flexpage supporting 'position'. */ 91.28 + 91.29 +Flexpage *AccessMap::find(offset_t position) 91.30 +{ 91.31 + std::lock_guard<std::mutex> guard(_lock); 91.32 + 91.33 + _AccessMap::iterator it = _flexpages.upper_bound(position); 91.34 + 91.35 + if ((_flexpages.size() > 0) && (it != _flexpages.begin())) 91.36 + { 91.37 + it--; 91.38 + 91.39 + if (it->second->supports_position(position)) 91.40 + return it->second; 91.41 + } 91.42 + 91.43 + return NULL; 91.44 +} 91.45 + 91.46 +/* Insert a mapping for 'flexpage'. */ 91.47 + 91.48 +void AccessMap::insert(Flexpage *flexpage) 91.49 +{ 91.50 + std::lock_guard<std::mutex> guard(_lock); 91.51 + 91.52 + _flexpages.insert(_AccessMapEntry(flexpage->base_offset, flexpage)); 91.53 +} 91.54 + 91.55 +/* Remove the mapping supported by 'flexpage'. 91.56 + 91.57 + The flexpage may have obtained by another mapper before being purged from 91.58 + this object's mapping and before being purged from the queue (and thus 91.59 + disassociated from this mapper), leaving an opportunity for another mapper to 91.60 + now be removing it here. In such a situation, flushing has already occurred 91.61 + and will not be performed again. */ 91.62 + 91.63 +bool AccessMap::remove(PageOwner *owner, Flexpage *flexpage) 91.64 +{ 91.65 + std::lock_guard<std::mutex> guard(_lock); 91.66 + 91.67 + _AccessMap::iterator it = _flexpages.find(flexpage->base_offset); 91.68 + 91.69 + if (it != _flexpages.end()) 91.70 + { 91.71 + owner->flush(flexpage, true); 91.72 + _flexpages.erase(flexpage->base_offset); 91.73 + return true; 91.74 + } 91.75 + 91.76 + return false; 91.77 +} 91.78 + 91.79 +/* Purge all flexpages, using the 'owner' to flush their contents and 91.80 + 'pages' to make the flexpages available to other accessors. */ 91.81 + 91.82 +void AccessMap::purge(PageOwner *owner, Pages *pages) 91.83 +{ 91.84 + std::lock_guard<std::mutex> guard(_lock); 91.85 + 91.86 + _AccessMap::iterator it = _flexpages.begin(), entry; 91.87 + 91.88 + while (it != _flexpages.end()) 91.89 + { 91.90 + entry = it; 91.91 + it++; 91.92 + 91.93 + Flexpage *flexpage = entry->second; 91.94 + 91.95 + /* Some flexpages may be unavailable in the queue. Only those 91.96 + that can be reserved should be flushed and made available 91.97 + again. */ 91.98 + 91.99 + if (pages->reserve(owner, flexpage)) 91.100 + { 91.101 + owner->flush(flexpage, true); 91.102 + pages->release(flexpage); 91.103 + _flexpages.erase(entry); 91.104 + } 91.105 + } 91.106 +} 91.107 + 91.108 +/* Flush flexpages in the given range from 'start' with 'size', using 'owner' 91.109 + and 'pages'. */ 91.110 + 91.111 +void AccessMap::flush_all(offset_t start, offset_t size, PageOwner *owner, Pages *pages) 91.112 +{ 91.113 + offset_t end = start + size; 91.114 + 91.115 + std::lock_guard<std::mutex> guard(_lock); 91.116 + 91.117 + /* The start may be within an existing flexpage where the flexpage size is a 91.118 + page multiple. */ 91.119 + 91.120 + _AccessMap::iterator it = _flexpages.upper_bound(start), entry; 91.121 + 91.122 + if ((_flexpages.size() > 0) && (it != _flexpages.begin())) 91.123 + it--; 91.124 + 91.125 + /* Inspect flexpages at or after start until end. */ 91.126 + 91.127 + while (it != _flexpages.end()) 91.128 + { 91.129 + entry = it; 91.130 + it++; 91.131 + 91.132 + Flexpage *flexpage = entry->second; 91.133 + 91.134 + if (flexpage->base_offset >= end) 91.135 + break; 91.136 + 91.137 + /* Attempt to flush each flexpage, releasing ones that are no longer 91.138 + needed. */ 91.139 + 91.140 + if (pages->reserve(owner, flexpage)) 91.141 + { 91.142 + owner->flush(flexpage, false); 91.143 + 91.144 + /* Where no users of the flexpage persist, release the flexpage for 91.145 + reuse and remove this entry. */ 91.146 + 91.147 + if (!flexpage->valid()) 91.148 + { 91.149 + pages->release(flexpage); 91.150 + _flexpages.erase(entry); 91.151 + } 91.152 + else 91.153 + pages->queue(owner, flexpage); 91.154 + } 91.155 + } 91.156 +} 91.157 + 91.158 +// vim: tabstop=4 expandtab shiftwidth=4
92.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 92.2 +++ b/libfsserver/lib/mapping/ipc.cc Thu Apr 15 23:15:17 2021 +0200 92.3 @@ -0,0 +1,68 @@ 92.4 +/* 92.5 + * Interprocess communication utilities. 92.6 + * 92.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 92.8 + * 92.9 + * This program is free software; you can redistribute it and/or 92.10 + * modify it under the terms of the GNU General Public License as 92.11 + * published by the Free Software Foundation; either version 2 of 92.12 + * the License, or (at your option) any later version. 92.13 + * 92.14 + * This program is distributed in the hope that it will be useful, 92.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 92.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 92.17 + * GNU General Public License for more details. 92.18 + * 92.19 + * You should have received a copy of the GNU General Public License 92.20 + * along with this program; if not, write to the Free Software 92.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 92.22 + * Boston, MA 02110-1301, USA 92.23 + */ 92.24 + 92.25 +#include <l4/re/c/dataspace.h> 92.26 +#include <l4/re/consts.h> 92.27 +#include <l4/sys/task.h> 92.28 + 92.29 +#include <mem/send_flexpage.h> 92.30 + 92.31 +#include "ipc.h" 92.32 + 92.33 + 92.34 +/* Make an L4 representation of the given flexpage. */ 92.35 + 92.36 +static l4_fpage_t ipc_get_fpage(SendFlexpage *send_flexpage) 92.37 +{ 92.38 + return l4_fpage(send_flexpage->base_addr, send_flexpage->order, 92.39 + (send_flexpage->flags & L4RE_DS_MAP_FLAG_RW) ? L4_FPAGE_RW : L4_FPAGE_RO); 92.40 +} 92.41 + 92.42 +/* Make a representation of a flexpage for the IPC system. */ 92.43 + 92.44 +long ipc_prepare_flexpage(Flexpage *flexpage, offset_t offset, 92.45 + offset_t max_offset, address_t hot_spot, 92.46 + flags_t flags, l4_snd_fpage_t *region) 92.47 +{ 92.48 + SendFlexpage send_flexpage = flexpage->to_send(offset, hot_spot, flags, 92.49 + max_offset); 92.50 + 92.51 + /* NOTE: Consider l4_fpage_invalid() as the fpage here. */ 92.52 + 92.53 + if (!send_flexpage.order) 92.54 + return -L4_ERANGE; 92.55 + 92.56 + region->fpage = ipc_get_fpage(&send_flexpage); 92.57 + region->snd_base = hot_spot; 92.58 + 92.59 + return L4_EOK; 92.60 +} 92.61 + 92.62 +/* Unmap the given flexpage. */ 92.63 + 92.64 +void ipc_unmap_flexpage(Flexpage *flexpage) 92.65 +{ 92.66 + SendFlexpage send_flexpage = flexpage->to_unmap(); 92.67 + 92.68 + l4_task_unmap(L4RE_THIS_TASK_CAP, ipc_get_fpage(&send_flexpage), L4_FP_OTHER_SPACES); 92.69 +} 92.70 + 92.71 +// vim: tabstop=4 expandtab shiftwidth=4
93.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 93.2 +++ b/libfsserver/lib/mapping/page_mapper.cc Thu Apr 15 23:15:17 2021 +0200 93.3 @@ -0,0 +1,196 @@ 93.4 +/* 93.5 + * A page mapper providing memory pages to satisfy file accesses. 93.6 + * 93.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 93.8 + * 93.9 + * This program is free software; you can redistribute it and/or 93.10 + * modify it under the terms of the GNU General Public License as 93.11 + * published by the Free Software Foundation; either version 2 of 93.12 + * the License, or (at your option) any later version. 93.13 + * 93.14 + * This program is distributed in the hope that it will be useful, 93.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 93.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 93.17 + * GNU General Public License for more details. 93.18 + * 93.19 + * You should have received a copy of the GNU General Public License 93.20 + * along with this program; if not, write to the Free Software 93.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 93.22 + * Boston, MA 02110-1301, USA 93.23 + */ 93.24 + 93.25 +#include "ipc.h" 93.26 +#include "page_mapper.h" 93.27 + 93.28 + 93.29 + 93.30 +PageMapper::PageMapper(Accessor *accessor, Pages *pages) 93.31 +: _accessor(accessor), _pages(pages), _attached(0) 93.32 +{ 93.33 +} 93.34 + 93.35 +/* Accounting methods. */ 93.36 + 93.37 +/* Attach a pager, opening the accessor if required. */ 93.38 + 93.39 +void PageMapper::attach() 93.40 +{ 93.41 + std::lock_guard<std::mutex> guard(_lock); 93.42 + 93.43 + if (!_attached) 93.44 + _accessor->open(); 93.45 + 93.46 + _attached += 1; 93.47 +} 93.48 + 93.49 +/* Detach a pager, purging active pages and closing the accessor if no more 93.50 + pagers are attached. Return whether any pagers are still attached. */ 93.51 + 93.52 +unsigned int PageMapper::detach() 93.53 +{ 93.54 + std::lock_guard<std::mutex> guard(_lock); 93.55 + 93.56 + if (_attached) 93.57 + { 93.58 + _attached -= 1; 93.59 + 93.60 + if (!_attached) 93.61 + { 93.62 + _map.purge(this, _pages); 93.63 + _accessor->close(); 93.64 + } 93.65 + } 93.66 + 93.67 + return _attached; 93.68 +} 93.69 + 93.70 +/* Interface for the pager. */ 93.71 + 93.72 +/* Return a flexpage providing access to the indicated file 'offset'. 93.73 + 93.74 + The returned flexpage will either be an existing, compatible flexpage or a 93.75 + completely new flexpage. 93.76 + 93.77 + This method locks the mapper to prevent concurrent queries with the same 93.78 + details, with the lock held until the queue operation releases the lock. */ 93.79 + 93.80 +Flexpage *PageMapper::get(offset_t offset, flags_t flags) 93.81 +{ 93.82 + _lock.lock(); 93.83 + 93.84 + Flexpage *f = find(offset); 93.85 + 93.86 + if (f == NULL) 93.87 + f = flexpage(offset); 93.88 + 93.89 + /* Record a new user of the flexpage and upgrade the access flags. */ 93.90 + 93.91 + f->increment(); 93.92 + f->upgrade(flags); 93.93 + return f; 93.94 +} 93.95 + 93.96 +/* Queue the given 'flexpage' in the page collection, making it available for 93.97 + eventual reuse. 93.98 + 93.99 + This method unlocks the mapper. */ 93.100 + 93.101 +void PageMapper::queue(Flexpage *flexpage) 93.102 +{ 93.103 + _pages->queue(this, flexpage); 93.104 + 93.105 + _lock.unlock(); 93.106 +} 93.107 + 93.108 +/* Flush pages in the given range from 'start' with 'size'. */ 93.109 + 93.110 +void PageMapper::flush_all(offset_t start, offset_t size) 93.111 +{ 93.112 + std::lock_guard<std::mutex> guard(_lock); 93.113 + 93.114 + _map.flush_all(start, size, this, _pages); 93.115 +} 93.116 + 93.117 +/* Return the maximum extent of the mapped resource. */ 93.118 + 93.119 +offset_t PageMapper::get_data_size() 93.120 +{ 93.121 + return _accessor->get_size(); 93.122 +} 93.123 + 93.124 +/* Set the maximum extent of the mapped resource. */ 93.125 + 93.126 +void PageMapper::set_data_size(offset_t size) 93.127 +{ 93.128 + _accessor->set_size(size); 93.129 +} 93.130 + 93.131 +/* Internal flexpage retrieval methods. */ 93.132 + 93.133 +/* Find an existing flexpage for 'offset'. Where the accessor has registered a 93.134 + compatible flexpage, an attempt is made to reserve it in the page collection; 93.135 + if this succeeds, the flexpage is returned. Otherwise, NULL is returned. */ 93.136 + 93.137 +Flexpage *PageMapper::find(offset_t offset) 93.138 +{ 93.139 + Flexpage *flexpage = _map.find(offset); 93.140 + 93.141 + /* Between finding and reserving a flexpage, there is a possibility that 93.142 + another accessor might acquire the flexpage, issue it, and even purge 93.143 + it. */ 93.144 + 93.145 + if ((flexpage != NULL) && _pages->reserve(this, flexpage)) 93.146 + return flexpage; 93.147 + else 93.148 + return NULL; 93.149 +} 93.150 + 93.151 +/* Obtain a new flexpage for the file 'offset'. If the page collection is unable 93.152 + to obtain a completely new flexpage, an existing flexpage is requested from 93.153 + the page collection and recycled. 93.154 + 93.155 + The obtained flexpage is filled with content. */ 93.156 + 93.157 +Flexpage *PageMapper::flexpage(offset_t offset) 93.158 +{ 93.159 + Flexpage *flexpage = _pages->flexpage(); 93.160 + 93.161 + /* Obtain an existing flexpage and reuse it. */ 93.162 + 93.163 + if (flexpage == NULL) 93.164 + flexpage = _pages->remove(); 93.165 + 93.166 + flexpage->reset(offset); 93.167 + 93.168 + fill(flexpage); 93.169 + _map.insert(flexpage); 93.170 + return flexpage; 93.171 +} 93.172 + 93.173 +/* Interface for the page collection. */ 93.174 + 93.175 +/* Remove the record of 'flexpage' in this accessor, flushing its content. */ 93.176 + 93.177 +void PageMapper::remove(Flexpage *flexpage) 93.178 +{ 93.179 + _map.remove(this, flexpage); 93.180 +} 93.181 + 93.182 +/* Data transfer methods. */ 93.183 + 93.184 +void PageMapper::fill(Flexpage *flexpage) 93.185 +{ 93.186 + _accessor->fill(flexpage); 93.187 +} 93.188 + 93.189 +void PageMapper::flush(Flexpage *flexpage, bool purge) 93.190 +{ 93.191 + if (flexpage->decrement() || purge) 93.192 + { 93.193 + _accessor->flush(flexpage); 93.194 + ipc_unmap_flexpage(flexpage); 93.195 + flexpage->invalidate(); 93.196 + } 93.197 +} 93.198 + 93.199 +// vim: tabstop=4 expandtab shiftwidth=4
94.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 94.2 +++ b/libfsserver/lib/pages/page_queue.cc Thu Apr 15 23:15:17 2021 +0200 94.3 @@ -0,0 +1,66 @@ 94.4 +/* 94.5 + * A page queue abstraction. 94.6 + * 94.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 94.8 + * 94.9 + * This program is free software; you can redistribute it and/or 94.10 + * modify it under the terms of the GNU General Public License as 94.11 + * published by the Free Software Foundation; either version 2 of 94.12 + * the License, or (at your option) any later version. 94.13 + * 94.14 + * This program is distributed in the hope that it will be useful, 94.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 94.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 94.17 + * GNU General Public License for more details. 94.18 + * 94.19 + * You should have received a copy of the GNU General Public License 94.20 + * along with this program; if not, write to the Free Software 94.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 94.22 + * Boston, MA 02110-1301, USA 94.23 + */ 94.24 + 94.25 +#include "page_queue.h" 94.26 + 94.27 + 94.28 + 94.29 +PageQueue::~PageQueue() 94.30 +{ 94.31 +} 94.32 + 94.33 + 94.34 + 94.35 +void PageQueue::discard(Queue &queue, Memory *memory) 94.36 +{ 94.37 + while (!queue.empty()) 94.38 + { 94.39 + Flexpage *flexpage = queue.front().flexpage; 94.40 + 94.41 + queue.pop_front(); 94.42 + memory->release(flexpage->region); 94.43 + delete flexpage; 94.44 + } 94.45 +} 94.46 + 94.47 +bool PageQueue::remove(Queue &queue, Positions &positions, PageOwner *owner, Flexpage *flexpage) 94.48 +{ 94.49 + Positions::iterator position = positions.find(flexpage); 94.50 + 94.51 + if (position == positions.end()) 94.52 + return false; 94.53 + 94.54 + /* The found owner may be different from the requesting owner or even NULL 94.55 + if another owner has acquired and then purged its pages. Such a purged 94.56 + flexpage is not immediately usable, however. */ 94.57 + 94.58 + Queue::iterator entry = position->second; 94.59 + 94.60 + if ((entry->owner == NULL) || (entry->owner != owner)) 94.61 + return false; 94.62 + 94.63 + queue.erase(entry); 94.64 + positions.erase(position); 94.65 + 94.66 + return true; 94.67 +} 94.68 + 94.69 +// vim: tabstop=4 expandtab shiftwidth=4
95.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 95.2 +++ b/libfsserver/lib/pages/page_queue_partitioned.cc Thu Apr 15 23:15:17 2021 +0200 95.3 @@ -0,0 +1,133 @@ 95.4 +/* 95.5 + * A page queue retaining two internal collections of memory pages. 95.6 + * 95.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 95.8 + * 95.9 + * This program is free software; you can redistribute it and/or 95.10 + * modify it under the terms of the GNU General Public License as 95.11 + * published by the Free Software Foundation; either version 2 of 95.12 + * the License, or (at your option) any later version. 95.13 + * 95.14 + * This program is distributed in the hope that it will be useful, 95.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 95.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 95.17 + * GNU General Public License for more details. 95.18 + * 95.19 + * You should have received a copy of the GNU General Public License 95.20 + * along with this program; if not, write to the Free Software 95.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 95.22 + * Boston, MA 02110-1301, USA 95.23 + */ 95.24 + 95.25 +#include "page_queue_partitioned.h" 95.26 + 95.27 + 95.28 + 95.29 +/* Discard all queued flexpages. */ 95.30 + 95.31 +void PageQueuePartitioned::close(Memory *memory) 95.32 +{ 95.33 + discard(_available, memory); 95.34 + discard(_issued, memory); 95.35 +} 95.36 + 95.37 +/* Keep waiting for a potential queue non-empty condition. 95.38 + Then, attempt to pop an entry from the queue. */ 95.39 + 95.40 +void PageQueuePartitioned::pop(PageOwner **owner, Flexpage **flexpage) 95.41 +{ 95.42 + std::unique_lock<std::mutex> guard(_lock); 95.43 + QueueEntry entry; 95.44 + 95.45 + while (1) 95.46 + { 95.47 + if (_pop(&entry)) 95.48 + { 95.49 + *owner = entry.owner; 95.50 + *flexpage = entry.flexpage; 95.51 + return; 95.52 + } 95.53 + else 95.54 + _counter.wait(guard); 95.55 + } 95.56 +} 95.57 + 95.58 +/* Check the available pages queue for entries, returning false if no entries 95.59 + are available, returning true and providing the details if an entry can be 95.60 + removed from the front of the queue. */ 95.61 + 95.62 +bool PageQueuePartitioned::_pop(QueueEntry *entry) 95.63 +{ 95.64 + if (_available.empty()) 95.65 + return false; 95.66 + 95.67 + *entry = _available.front(); 95.68 + _available.pop_front(); 95.69 + 95.70 + return true; 95.71 +} 95.72 + 95.73 +/* Push an entry for the given owner and flexpage to the appropriate queue. */ 95.74 + 95.75 +void PageQueuePartitioned::push(PageOwner *owner, Flexpage *flexpage) 95.76 +{ 95.77 + std::lock_guard<std::mutex> guard(_lock); 95.78 + 95.79 + /* Record the entry and a position reference for the flexpage. */ 95.80 + 95.81 + Queue *queue; 95.82 + Positions *positions = NULL; 95.83 + 95.84 + if (owner == NULL) 95.85 + queue = &_available; 95.86 + else 95.87 + { 95.88 + queue = &_issued; 95.89 + positions = &_positions; 95.90 + } 95.91 + 95.92 + queue->push_back((QueueEntry) {flexpage, owner}); 95.93 + 95.94 + if (positions != NULL) 95.95 + { 95.96 + Queue::iterator last = queue->end(); 95.97 + last--; 95.98 + positions->insert(Position(flexpage, last)); 95.99 + } 95.100 + 95.101 + _counter.notify_one(); 95.102 +} 95.103 + 95.104 +/* Push an entry to the front of the appropriate queue. */ 95.105 + 95.106 +void PageQueuePartitioned::push_front(PageOwner *owner, Flexpage *flexpage) 95.107 +{ 95.108 + std::lock_guard<std::mutex> guard(_lock); 95.109 + 95.110 + Queue *queue; 95.111 + Positions *positions = NULL; 95.112 + 95.113 + if (owner == NULL) 95.114 + queue = &_available; 95.115 + else 95.116 + { 95.117 + queue = &_issued; 95.118 + positions = &_positions; 95.119 + } 95.120 + 95.121 + queue->push_back((QueueEntry) {flexpage, owner}); 95.122 + 95.123 + if (positions != NULL) 95.124 + positions->insert(Position(flexpage, queue->begin())); 95.125 + 95.126 + _counter.notify_one(); 95.127 +} 95.128 + 95.129 +/* Remove an entry for the given owner and flexpage from the queue. */ 95.130 + 95.131 +bool PageQueuePartitioned::remove(PageOwner *owner, Flexpage *flexpage) 95.132 +{ 95.133 + return PageQueue::remove(_issued, _positions, owner, flexpage); 95.134 +} 95.135 + 95.136 +// vim: tabstop=4 expandtab shiftwidth=4
96.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 96.2 +++ b/libfsserver/lib/pages/page_queue_shared.cc Thu Apr 15 23:15:17 2021 +0200 96.3 @@ -0,0 +1,112 @@ 96.4 +/* 96.5 + * A page queue whose users take turns to access pages. 96.6 + * 96.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 96.8 + * 96.9 + * This program is free software; you can redistribute it and/or 96.10 + * modify it under the terms of the GNU General Public License as 96.11 + * published by the Free Software Foundation; either version 2 of 96.12 + * the License, or (at your option) any later version. 96.13 + * 96.14 + * This program is distributed in the hope that it will be useful, 96.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 96.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 96.17 + * GNU General Public License for more details. 96.18 + * 96.19 + * You should have received a copy of the GNU General Public License 96.20 + * along with this program; if not, write to the Free Software 96.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 96.22 + * Boston, MA 02110-1301, USA 96.23 + */ 96.24 + 96.25 +#include "page_queue_shared.h" 96.26 + 96.27 + 96.28 + 96.29 +/* Discard all queued flexpages. */ 96.30 + 96.31 +void PageQueueShared::close(Memory *memory) 96.32 +{ 96.33 + discard(_queue, memory); 96.34 +} 96.35 + 96.36 +/* Keep waiting for a potential queue non-empty condition. 96.37 + Then, attempt to pop an entry from the queue. */ 96.38 + 96.39 +void PageQueueShared::pop(PageOwner **owner, Flexpage **flexpage) 96.40 +{ 96.41 + std::unique_lock<std::mutex> guard(_lock); 96.42 + QueueEntry entry; 96.43 + 96.44 + while (1) 96.45 + { 96.46 + if (_pop(&entry)) 96.47 + { 96.48 + *owner = entry.owner; 96.49 + *flexpage = entry.flexpage; 96.50 + return; 96.51 + } 96.52 + else 96.53 + _counter.wait(guard); 96.54 + } 96.55 +} 96.56 + 96.57 +/* Check the queue for entries, returning false if no entries are available, 96.58 + returning true and providing the details if an entry can be removed from the 96.59 + front of the queue. */ 96.60 + 96.61 +bool PageQueueShared::_pop(QueueEntry *entry) 96.62 +{ 96.63 + if (_queue.empty()) 96.64 + return false; 96.65 + 96.66 + *entry = _queue.front(); 96.67 + _queue.pop_front(); 96.68 + 96.69 + /* Remove any position reference for the flexpage. */ 96.70 + 96.71 + Positions::iterator position = _positions.find(entry->flexpage); 96.72 + 96.73 + if (position != _positions.end()) 96.74 + _positions.erase(position); 96.75 + 96.76 + return true; 96.77 +} 96.78 + 96.79 +/* Push an entry for the given owner and flexpage to the queue. */ 96.80 + 96.81 +void PageQueueShared::push(PageOwner *owner, Flexpage *flexpage) 96.82 +{ 96.83 + std::lock_guard<std::mutex> guard(_lock); 96.84 + 96.85 + /* Record the entry and a position reference for the flexpage. */ 96.86 + 96.87 + _queue.push_back((QueueEntry) {flexpage, owner}); 96.88 + 96.89 + Queue::iterator last = _queue.end(); 96.90 + last--; 96.91 + _positions.insert(Position(flexpage, last)); 96.92 + 96.93 + _counter.notify_one(); 96.94 +} 96.95 + 96.96 +/* Push an entry to the front of the queue. */ 96.97 + 96.98 +void PageQueueShared::push_front(PageOwner *owner, Flexpage *flexpage) 96.99 +{ 96.100 + std::lock_guard<std::mutex> guard(_lock); 96.101 + 96.102 + _queue.push_back((QueueEntry) {flexpage, owner}); 96.103 + _positions.insert(Position(flexpage, _queue.begin())); 96.104 + 96.105 + _counter.notify_one(); 96.106 +} 96.107 + 96.108 +/* Remove an entry for the given owner and flexpage from the queue. */ 96.109 + 96.110 +bool PageQueueShared::remove(PageOwner *owner, Flexpage *flexpage) 96.111 +{ 96.112 + return PageQueue::remove(_queue, _positions, owner, flexpage); 96.113 +} 96.114 + 96.115 +// vim: tabstop=4 expandtab shiftwidth=4
97.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 97.2 +++ b/libfsserver/lib/pages/pages.cc Thu Apr 15 23:15:17 2021 +0200 97.3 @@ -0,0 +1,89 @@ 97.4 +/* 97.5 + * A page collection abstraction providing pages from a queue to users. 97.6 + * 97.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 97.8 + * 97.9 + * This program is free software; you can redistribute it and/or 97.10 + * modify it under the terms of the GNU General Public License as 97.11 + * published by the Free Software Foundation; either version 2 of 97.12 + * the License, or (at your option) any later version. 97.13 + * 97.14 + * This program is distributed in the hope that it will be useful, 97.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 97.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 97.17 + * GNU General Public License for more details. 97.18 + * 97.19 + * You should have received a copy of the GNU General Public License 97.20 + * along with this program; if not, write to the Free Software 97.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 97.22 + * Boston, MA 02110-1301, USA 97.23 + */ 97.24 + 97.25 +#include <mem/memory_incremental.h> 97.26 + 97.27 +#include "pages.h" 97.28 + 97.29 + 97.30 + 97.31 +Pages::Pages(Memory *memory, PageQueue *queue) 97.32 +: _memory(memory), _queue(queue) 97.33 +{ 97.34 +} 97.35 + 97.36 +Pages::~Pages() 97.37 +{ 97.38 + _queue->close(_memory); 97.39 +} 97.40 + 97.41 +/* Remove the first flexpage in the queue. If its owner exists, remove it from 97.42 + the owner (retiring the content). Return the flexpage for reuse. */ 97.43 + 97.44 +Flexpage *Pages::remove() 97.45 +{ 97.46 + PageOwner *owner; 97.47 + Flexpage *flexpage; 97.48 + 97.49 + _queue->pop(&owner, &flexpage); 97.50 + 97.51 + if (owner != NULL) 97.52 + owner->remove(flexpage); 97.53 + 97.54 + return flexpage; 97.55 +} 97.56 + 97.57 +/* Reserve 'flexpage' by removing it from this collection. */ 97.58 + 97.59 +bool Pages::reserve(PageOwner *owner, Flexpage *flexpage) 97.60 +{ 97.61 + return _queue->remove(owner, flexpage); 97.62 +} 97.63 + 97.64 +/* Obtain a new flexpage. Return the flexpage or None if no new flexpage could 97.65 + be created. */ 97.66 + 97.67 +Flexpage *Pages::flexpage() 97.68 +{ 97.69 + Region *region = _memory->region(); 97.70 + 97.71 + if (region != NULL) 97.72 + return new Flexpage(region); 97.73 + else 97.74 + return NULL; 97.75 +} 97.76 + 97.77 +/* Queue an entry associating the given 'owner' and 'flexpage'. */ 97.78 + 97.79 +void Pages::queue(PageOwner *owner, Flexpage *flexpage) 97.80 +{ 97.81 + _queue->push(owner, flexpage); 97.82 +} 97.83 + 97.84 +/* Push an entry for 'flexpage' without owner association for immediate 97.85 + reuse. */ 97.86 + 97.87 +void Pages::release(Flexpage *flexpage) 97.88 +{ 97.89 + _queue->push_front(NULL, flexpage); 97.90 +} 97.91 + 97.92 +// vim: tabstop=4 expandtab shiftwidth=4
98.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 98.2 +++ b/libfsserver/lib/pipes/pipe_accessor.cc Thu Apr 15 23:15:17 2021 +0200 98.3 @@ -0,0 +1,64 @@ 98.4 +/* 98.5 + * A pipe accessor merely resetting allocated memory for use. 98.6 + * 98.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 98.8 + * 98.9 + * This program is free software; you can redistribute it and/or 98.10 + * modify it under the terms of the GNU General Public License as 98.11 + * published by the Free Software Foundation; either version 2 of 98.12 + * the License, or (at your option) any later version. 98.13 + * 98.14 + * This program is distributed in the hope that it will be useful, 98.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 98.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 98.17 + * GNU General Public License for more details. 98.18 + * 98.19 + * You should have received a copy of the GNU General Public License 98.20 + * along with this program; if not, write to the Free Software 98.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 98.22 + * Boston, MA 02110-1301, USA 98.23 + */ 98.24 + 98.25 +#include "pipe_accessor.h" 98.26 + 98.27 +#include <string.h> 98.28 + 98.29 +PipeAccessor::PipeAccessor() 98.30 +: Accessor(0) 98.31 +{ 98.32 +} 98.33 + 98.34 +/* Perform any closing operation on the file. */ 98.35 + 98.36 +void PipeAccessor::close() 98.37 +{ 98.38 +} 98.39 + 98.40 +/* Perform any opening operation on the file. */ 98.41 + 98.42 +void PipeAccessor::open() 98.43 +{ 98.44 +} 98.45 + 98.46 +/* Data transfer helper methods. */ 98.47 + 98.48 +void PipeAccessor::fill_populated(Flexpage *flexpage) 98.49 +{ 98.50 + offset_t filepos = flexpage->base_offset; 98.51 + offset_t addr = flexpage->base_addr; 98.52 + 98.53 + /* Tag the region with file state. */ 98.54 + 98.55 + flexpage->region->fill(fileid, filepos); 98.56 + 98.57 + /* File the flexpage with zero. */ 98.58 + 98.59 + memset((void *) addr, 0, flexpage->size); 98.60 +} 98.61 + 98.62 +void PipeAccessor::flush_populated(Flexpage *flexpage) 98.63 +{ 98.64 + flexpage->region->flush(); 98.65 +} 98.66 + 98.67 +// vim: tabstop=4 expandtab shiftwidth=4
99.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 99.2 +++ b/libfsserver/lib/pipes/pipe_opener_resource.cc Thu Apr 15 23:15:17 2021 +0200 99.3 @@ -0,0 +1,85 @@ 99.4 +/* 99.5 + * A pipe opener resource. 99.6 + * 99.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 99.8 + * 99.9 + * This program is free software; you can redistribute it and/or 99.10 + * modify it under the terms of the GNU General Public License as 99.11 + * published by the Free Software Foundation; either version 2 of 99.12 + * the License, or (at your option) any later version. 99.13 + * 99.14 + * This program is distributed in the hope that it will be useful, 99.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 99.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 99.17 + * GNU General Public License for more details. 99.18 + * 99.19 + * You should have received a copy of the GNU General Public License 99.20 + * along with this program; if not, write to the Free Software 99.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 99.22 + * Boston, MA 02110-1301, USA 99.23 + */ 99.24 + 99.25 +#include <mem/memory_incremental.h> 99.26 + 99.27 +#include "pipe_opener_resource.h" 99.28 +#include "pipe_opener_server.h" 99.29 +#include "pipe_pager.h" 99.30 +#include "resource_server.h" 99.31 + 99.32 + 99.33 + 99.34 +/* Support for providing access to pipes. */ 99.35 + 99.36 +PipeOpenerResource::PipeOpenerResource(Memory *memory) 99.37 +: _memory(memory) 99.38 +{ 99.39 +} 99.40 + 99.41 +int PipeOpenerResource::expected_items() 99.42 +{ 99.43 + return PipeOpener_expected_items; 99.44 +} 99.45 + 99.46 +ipc_server_handler_type PipeOpenerResource::handler() 99.47 +{ 99.48 + return (ipc_server_handler_type) handle_PipeOpener; 99.49 +} 99.50 + 99.51 + 99.52 + 99.53 +/* Pipe opener interface methods. */ 99.54 + 99.55 +long PipeOpenerResource::pipe(offset_t size, l4_cap_idx_t *reader, l4_cap_idx_t *writer) 99.56 +{ 99.57 + /* Both endpoints will employ a common paging coordinator. */ 99.58 + 99.59 + PipePaging *paging = new PipePaging(_memory, size); 99.60 + 99.61 + /* Each endpoint will have its own pager. */ 99.62 + 99.63 + /* NOTE: Failure to open an endpoint should invalidate both, plus the 99.64 + paging object. Also, any active server thread would need to be 99.65 + cancelled. */ 99.66 + 99.67 + return open_endpoint(paging, false, reader) || open_endpoint(paging, true, writer); 99.68 +} 99.69 + 99.70 +long PipeOpenerResource::open_endpoint(PipePaging *paging, bool writing, l4_cap_idx_t *endpoint) 99.71 +{ 99.72 + PipePager *pager = new PipePager(paging, writing); 99.73 + 99.74 + /* Start the endpoint server in a new thread. 99.75 + If the thread does not start, the resource should be finalised. */ 99.76 + 99.77 + ResourceServer server(pager); 99.78 + long err = server.start_thread(); 99.79 + 99.80 + /* Return the server capability to the caller. */ 99.81 + 99.82 + if (!err) 99.83 + *endpoint = server.config()->server; 99.84 + 99.85 + return err; 99.86 +} 99.87 + 99.88 +// vim: tabstop=4 expandtab shiftwidth=4
100.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 100.2 +++ b/libfsserver/lib/pipes/pipe_pager.cc Thu Apr 15 23:15:17 2021 +0200 100.3 @@ -0,0 +1,126 @@ 100.4 +/* 100.5 + * A pipe pager providing access to pipe content and navigation support. 100.6 + * 100.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 100.8 + * 100.9 + * This program is free software; you can redistribute it and/or 100.10 + * modify it under the terms of the GNU General Public License as 100.11 + * published by the Free Software Foundation; either version 2 of 100.12 + * the License, or (at your option) any later version. 100.13 + * 100.14 + * This program is distributed in the hope that it will be useful, 100.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 100.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 100.17 + * GNU General Public License for more details. 100.18 + * 100.19 + * You should have received a copy of the GNU General Public License 100.20 + * along with this program; if not, write to the Free Software 100.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 100.22 + * Boston, MA 02110-1301, USA 100.23 + */ 100.24 + 100.25 +#include "pipe_pager.h" 100.26 +#include "pipe_object_server.h" 100.27 + 100.28 + 100.29 + 100.30 +/* Initialise a pager for a pipe with a shared page mapper for moderating 100.31 + access to loaded pages. At first, no mapper will be configured: this must be 100.32 + done by requesting a region. */ 100.33 + 100.34 +PipePager::PipePager(PipePaging *paging, bool writing) 100.35 +: Pager(NULL, writing ? L4RE_DS_MAP_FLAG_RW : L4RE_DS_MAP_FLAG_RO), 100.36 + _paging(paging), _writing(writing) 100.37 +{ 100.38 + /* Initialise the size of the paged region. */ 100.39 + 100.40 + _size = _paging->region_size(); 100.41 +} 100.42 + 100.43 +int PipePager::expected_items() 100.44 +{ 100.45 + return PipeObject_expected_items; 100.46 +} 100.47 + 100.48 +ipc_server_handler_type PipePager::handler() 100.49 +{ 100.50 + return (ipc_server_handler_type) handle_PipeObject; 100.51 +} 100.52 + 100.53 + 100.54 + 100.55 +/* Close the pager, releasing the paging coordinator for the pipe. This will 100.56 + release all active page mappers. */ 100.57 + 100.58 +void PipePager::close() 100.59 +{ 100.60 + _paging->detach(); 100.61 +} 100.62 + 100.63 +/* Support paging. */ 100.64 + 100.65 +long PipePager::map(offset_t offset, address_t hot_spot, flags_t flags, l4_snd_fpage_t *region) 100.66 +{ 100.67 + return Pager::map(offset, hot_spot, flags, region); 100.68 +} 100.69 + 100.70 + 100.71 + 100.72 +/* Return details of the current region. */ 100.73 + 100.74 +long PipePager::current_region(offset_t *populated_size, offset_t *size) 100.75 +{ 100.76 + if (_mapper != NULL) 100.77 + { 100.78 + *populated_size = _mapper->get_data_size(); 100.79 + *size = _size; 100.80 + return L4_EOK; 100.81 + } 100.82 + else 100.83 + return -L4_EIO; 100.84 +} 100.85 + 100.86 +/* Obtain the next region and its details. */ 100.87 + 100.88 +long PipePager::next_region(offset_t *populated_size, offset_t *size) 100.89 +{ 100.90 + /* Obtain a new region if writing. */ 100.91 + 100.92 + if (_writing) 100.93 + return next_region_for_writer(populated_size, size); 100.94 + else 100.95 + return next_region_for_reader(populated_size, size); 100.96 +} 100.97 + 100.98 +long PipePager::next_region_for_reader(offset_t *populated_size, offset_t *size) 100.99 +{ 100.100 + PageMapper *mapper = _paging->next_region(); 100.101 + 100.102 + if (mapper == NULL) 100.103 + return -L4_EIO; 100.104 + 100.105 + _mapper = mapper; 100.106 + 100.107 + return current_region(populated_size, size); 100.108 +} 100.109 + 100.110 +long PipePager::next_region_for_writer(offset_t *populated_size, offset_t *size) 100.111 +{ 100.112 + /* Set the populated size before moving on. */ 100.113 + 100.114 + if (_mapper != NULL) 100.115 + _mapper->set_data_size(*populated_size); 100.116 + 100.117 + /* Obtain the page mapper for the region. */ 100.118 + 100.119 + PageMapper *mapper = _paging->add_region(); 100.120 + 100.121 + if (mapper == NULL) 100.122 + return -L4_EIO; 100.123 + 100.124 + _mapper = mapper; 100.125 + 100.126 + return current_region(populated_size, size); 100.127 +} 100.128 + 100.129 +// vim: tabstop=4 expandtab shiftwidth=4
101.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 101.2 +++ b/libfsserver/lib/pipes/pipe_paging.cc Thu Apr 15 23:15:17 2021 +0200 101.3 @@ -0,0 +1,140 @@ 101.4 +/* 101.5 + * A pipe paging coordinator, permitting memory sharing pipe endpoints. 101.6 + * 101.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 101.8 + * 101.9 + * This program is free software; you can redistribute it and/or 101.10 + * modify it under the terms of the GNU General Public License as 101.11 + * published by the Free Software Foundation; either version 2 of 101.12 + * the License, or (at your option) any later version. 101.13 + * 101.14 + * This program is distributed in the hope that it will be useful, 101.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 101.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 101.17 + * GNU General Public License for more details. 101.18 + * 101.19 + * You should have received a copy of the GNU General Public License 101.20 + * along with this program; if not, write to the Free Software 101.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 101.22 + * Boston, MA 02110-1301, USA 101.23 + */ 101.24 + 101.25 +#include <mem/memory_incremental.h> 101.26 +#include <mem/memory_preallocated.h> 101.27 + 101.28 +#include "page_queue_partitioned.h" 101.29 +#include "pipe_paging.h" 101.30 + 101.31 + 101.32 + 101.33 +PipePaging::PipePaging(Memory *memory, offset_t size) 101.34 +: _memory(NULL), _size(size) 101.35 +{ 101.36 + /* Reserve space for two pipe regions. */ 101.37 + 101.38 + _memory = new MemoryPreallocated(memory, round(size, memory->region_size()) * 2); 101.39 + _queue = new PageQueuePartitioned(); 101.40 + _pages = new Pages(_memory, _queue); 101.41 + 101.42 + for (unsigned int i = 0; i < 2; i++) 101.43 + _regions[i] = NULL; 101.44 +} 101.45 + 101.46 +/* Detach one endpoint. */ 101.47 + 101.48 +void PipePaging::detach() 101.49 +{ 101.50 + if (!_endpoints) 101.51 + return; 101.52 + else 101.53 + _endpoints--; 101.54 + 101.55 + /* Return if the other endpoint is attached. */ 101.56 + 101.57 + if (_endpoints) 101.58 + return; 101.59 + 101.60 + /* Discard all regions from the pipe. */ 101.61 + 101.62 + for (unsigned int i = 0; i < 2; i++) 101.63 + { 101.64 + PageMapper *mapper = _regions[i]; 101.65 + 101.66 + if (mapper != NULL) 101.67 + { 101.68 + mapper->detach(); 101.69 + _regions[i] = NULL; 101.70 + delete mapper; 101.71 + } 101.72 + } 101.73 + 101.74 + /* Delete the page collection and related objects. */ 101.75 + 101.76 + delete _pages; 101.77 + delete _queue; 101.78 + delete _memory; 101.79 +} 101.80 + 101.81 +/* Add a region to the sequence. */ 101.82 + 101.83 +PageMapper *PipePaging::add_region() 101.84 +{ 101.85 + /* If the writer already accesses a different region to the reader, no new 101.86 + region is added. */ 101.87 + 101.88 + if (_writing != _reading) 101.89 + return NULL; 101.90 + 101.91 + /* Select the other region of the pair being maintained. */ 101.92 + 101.93 + _writing = 1 - _writing; 101.94 + 101.95 + /* Make a new mapper for the region. */ 101.96 + 101.97 + PageMapper *mapper = new PageMapper(&_accessors[_writing], _pages); 101.98 + 101.99 + /* Initialise and record the mapper. */ 101.100 + 101.101 + mapper->attach(); 101.102 + mapper->set_data_size(0); 101.103 + 101.104 + _regions[_writing] = mapper; 101.105 + return mapper; 101.106 +} 101.107 + 101.108 +/* Return the current region for reading. */ 101.109 + 101.110 +PageMapper *PipePaging::current_region() 101.111 +{ 101.112 + return _regions[_reading]; 101.113 +} 101.114 + 101.115 +/* Return the next region for the reader if the writer is using a different one. 101.116 + Otherwise, return NULL. */ 101.117 + 101.118 +PageMapper *PipePaging::next_region() 101.119 +{ 101.120 + /* If the reader already accesses the same region to the writer, no next 101.121 + region can be obtained. */ 101.122 + 101.123 + if (_reading == _writing) 101.124 + return NULL; 101.125 + 101.126 + /* Detach and discard the current page mapper. */ 101.127 + 101.128 + PageMapper *mapper = _regions[_reading]; 101.129 + 101.130 + if (mapper != NULL) 101.131 + { 101.132 + mapper->detach(); 101.133 + _regions[_reading] = NULL; 101.134 + delete mapper; 101.135 + } 101.136 + 101.137 + /* Return the next region. */ 101.138 + 101.139 + _reading = 1 - _reading; 101.140 + return _regions[_reading]; 101.141 +} 101.142 + 101.143 +// vim: tabstop=4 expandtab shiftwidth=4
102.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 102.2 +++ b/libmem/Control Thu Apr 15 23:15:17 2021 +0200 102.3 @@ -0,0 +1,3 @@ 102.4 +requires: libstdc++ libc libsystypes 102.5 +provides: libmem 102.6 +maintainer: paul@boddie.org.uk
103.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 103.2 +++ b/libmem/Makefile Thu Apr 15 23:15:17 2021 +0200 103.3 @@ -0,0 +1,4 @@ 103.4 +PKGDIR ?= . 103.5 +L4DIR ?= $(PKGDIR)/../../.. 103.6 + 103.7 +include $(L4DIR)/mk/subdir.mk
104.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 104.2 +++ b/libmem/include/Makefile Thu Apr 15 23:15:17 2021 +0200 104.3 @@ -0,0 +1,7 @@ 104.4 +PKGDIR ?= .. 104.5 +L4DIR ?= $(PKGDIR)/../../.. 104.6 + 104.7 +PKGNAME = libmem 104.8 +CONTRIB_HEADERS = 1 104.9 + 104.10 +include $(L4DIR)/mk/include.mk
105.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 105.2 +++ b/libmem/include/mem/flexpage.h Thu Apr 15 23:15:17 2021 +0200 105.3 @@ -0,0 +1,76 @@ 105.4 +/* 105.5 + * A flexpage abstraction. 105.6 + * 105.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 105.8 + * 105.9 + * This program is free software; you can redistribute it and/or 105.10 + * modify it under the terms of the GNU General Public License as 105.11 + * published by the Free Software Foundation; either version 2 of 105.12 + * the License, or (at your option) any later version. 105.13 + * 105.14 + * This program is distributed in the hope that it will be useful, 105.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 105.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 105.17 + * GNU General Public License for more details. 105.18 + * 105.19 + * You should have received a copy of the GNU General Public License 105.20 + * along with this program; if not, write to the Free Software 105.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 105.22 + * Boston, MA 02110-1301, USA 105.23 + */ 105.24 + 105.25 +#pragma once 105.26 + 105.27 +#include <mem/memory_utils.h> 105.28 +#include <mem/region.h> 105.29 +#include <mem/send_flexpage.h> 105.30 + 105.31 + 105.32 + 105.33 +/* A flexpage abstraction. */ 105.34 + 105.35 +class Flexpage 105.36 +{ 105.37 +protected: 105.38 + unsigned int _counter; 105.39 + flags_t _flags; 105.40 + 105.41 +public: 105.42 + Region *region; 105.43 + 105.44 + /* General flexpage characteristics. */ 105.45 + 105.46 + offset_t base_addr, size; 105.47 + offset_t base_offset; 105.48 + 105.49 + /* Transient debugging information. */ 105.50 + 105.51 + offset_t page_addr, page_offset; 105.52 + 105.53 + /* Associate a flexpage with a memory 'region'. */ 105.54 + 105.55 + explicit Flexpage(Region *region) : region(region) 105.56 + { 105.57 + } 105.58 + 105.59 + void reset(offset_t offset); 105.60 + 105.61 + bool decrement(); 105.62 + 105.63 + void increment(); 105.64 + 105.65 + void invalidate(); 105.66 + 105.67 + bool valid(); 105.68 + 105.69 + bool supports_position(offset_t position); 105.70 + 105.71 + void upgrade(flags_t flags); 105.72 + 105.73 + SendFlexpage to_send(offset_t offset, offset_t hot_spot, flags_t flags, 105.74 + offset_t max_offset=0); 105.75 + 105.76 + SendFlexpage to_unmap(); 105.77 +}; 105.78 + 105.79 +// vim: tabstop=4 expandtab shiftwidth=4
106.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 106.2 +++ b/libmem/include/mem/memory.h Thu Apr 15 23:15:17 2021 +0200 106.3 @@ -0,0 +1,44 @@ 106.4 +/* 106.5 + * A generic memory pool abstraction. 106.6 + * 106.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 106.8 + * 106.9 + * This program is free software; you can redistribute it and/or 106.10 + * modify it under the terms of the GNU General Public License as 106.11 + * published by the Free Software Foundation; either version 2 of 106.12 + * the License, or (at your option) any later version. 106.13 + * 106.14 + * This program is distributed in the hope that it will be useful, 106.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 106.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 106.17 + * GNU General Public License for more details. 106.18 + * 106.19 + * You should have received a copy of the GNU General Public License 106.20 + * along with this program; if not, write to the Free Software 106.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 106.22 + * Boston, MA 02110-1301, USA 106.23 + */ 106.24 + 106.25 +#pragma once 106.26 + 106.27 +#include <mem/region.h> 106.28 + 106.29 + 106.30 + 106.31 +/* A memory pool interface. */ 106.32 + 106.33 +class Memory 106.34 +{ 106.35 +public: 106.36 + virtual ~Memory() 106.37 + { 106.38 + } 106.39 + 106.40 + virtual Region *region() = 0; 106.41 + 106.42 + virtual offset_t region_size() = 0; 106.43 + 106.44 + virtual void release(Region *region) = 0; 106.45 +}; 106.46 + 106.47 +// vim: tabstop=4 expandtab shiftwidth=4
107.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 107.2 +++ b/libmem/include/mem/memory_incremental.h Thu Apr 15 23:15:17 2021 +0200 107.3 @@ -0,0 +1,61 @@ 107.4 +/* 107.5 + * A memory pool allocating a region at a time from the system. 107.6 + * 107.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 107.8 + * 107.9 + * This program is free software; you can redistribute it and/or 107.10 + * modify it under the terms of the GNU General Public License as 107.11 + * published by the Free Software Foundation; either version 2 of 107.12 + * the License, or (at your option) any later version. 107.13 + * 107.14 + * This program is distributed in the hope that it will be useful, 107.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 107.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 107.17 + * GNU General Public License for more details. 107.18 + * 107.19 + * You should have received a copy of the GNU General Public License 107.20 + * along with this program; if not, write to the Free Software 107.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 107.22 + * Boston, MA 02110-1301, USA 107.23 + */ 107.24 + 107.25 +#pragma once 107.26 + 107.27 +#include <systypes/base.h> 107.28 + 107.29 +#include <mutex> 107.30 + 107.31 +#include <mem/memory.h> 107.32 +#include <mem/memory_utils.h> 107.33 + 107.34 + 107.35 + 107.36 +/* A memory pool abstraction. */ 107.37 + 107.38 +class MemoryIncremental : public Memory 107.39 +{ 107.40 +protected: 107.41 + std::mutex _lock; 107.42 + 107.43 + unsigned int _limit; 107.44 + offset_t _region_size; 107.45 + bool _limited; 107.46 + 107.47 + Region *allocate(offset_t size); 107.48 + 107.49 +public: 107.50 + explicit MemoryIncremental(unsigned int limit, offset_t region_size=PAGE_SIZE); 107.51 + 107.52 + explicit MemoryIncremental(); 107.53 + 107.54 + virtual Region *region(offset_t size); 107.55 + 107.56 + virtual Region *region(); 107.57 + 107.58 + virtual offset_t region_size() 107.59 + { return _region_size; } 107.60 + 107.61 + virtual void release(Region *region); 107.62 +}; 107.63 + 107.64 +// vim: tabstop=4 expandtab shiftwidth=4
108.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 108.2 +++ b/libmem/include/mem/memory_preallocated.h Thu Apr 15 23:15:17 2021 +0200 108.3 @@ -0,0 +1,59 @@ 108.4 +/* 108.5 + * A memory pool providing regions from a preallocated amount of memory. 108.6 + * 108.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 108.8 + * 108.9 + * This program is free software; you can redistribute it and/or 108.10 + * modify it under the terms of the GNU General Public License as 108.11 + * published by the Free Software Foundation; either version 2 of 108.12 + * the License, or (at your option) any later version. 108.13 + * 108.14 + * This program is distributed in the hope that it will be useful, 108.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 108.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 108.17 + * GNU General Public License for more details. 108.18 + * 108.19 + * You should have received a copy of the GNU General Public License 108.20 + * along with this program; if not, write to the Free Software 108.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 108.22 + * Boston, MA 02110-1301, USA 108.23 + */ 108.24 + 108.25 +#pragma once 108.26 + 108.27 +#include <systypes/base.h> 108.28 + 108.29 +#include <list> 108.30 +#include <mutex> 108.31 + 108.32 +#include <mem/memory.h> 108.33 + 108.34 + 108.35 + 108.36 +/* A memory pool abstraction. */ 108.37 + 108.38 +class MemoryPreallocated : public Memory 108.39 +{ 108.40 +protected: 108.41 + std::mutex _lock; 108.42 + std::list<Region *> _regions; 108.43 + 108.44 + Memory *_memory; 108.45 + offset_t _amount; 108.46 + 108.47 +public: 108.48 + explicit MemoryPreallocated(Memory *memory, offset_t amount); 108.49 + 108.50 + explicit MemoryPreallocated(); 108.51 + 108.52 + virtual ~MemoryPreallocated(); 108.53 + 108.54 + virtual Region *region(); 108.55 + 108.56 + virtual offset_t region_size() 108.57 + { return _memory->region_size(); } 108.58 + 108.59 + virtual void release(Region *region); 108.60 +}; 108.61 + 108.62 +// vim: tabstop=4 expandtab shiftwidth=4
109.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 109.2 +++ b/libmem/include/mem/memory_utils.h Thu Apr 15 23:15:17 2021 +0200 109.3 @@ -0,0 +1,46 @@ 109.4 +/* 109.5 + * Memory quantity calculation utilities. 109.6 + * 109.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 109.8 + * 109.9 + * This program is free software; you can redistribute it and/or 109.10 + * modify it under the terms of the GNU General Public License as 109.11 + * published by the Free Software Foundation; either version 2 of 109.12 + * the License, or (at your option) any later version. 109.13 + * 109.14 + * This program is distributed in the hope that it will be useful, 109.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 109.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 109.17 + * GNU General Public License for more details. 109.18 + * 109.19 + * You should have received a copy of the GNU General Public License 109.20 + * along with this program; if not, write to the Free Software 109.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 109.22 + * Boston, MA 02110-1301, USA 109.23 + */ 109.24 + 109.25 +#pragma once 109.26 + 109.27 +#include <systypes/base.h> 109.28 + 109.29 +#define PAGE_SIZE 4096 109.30 + 109.31 + 109.32 + 109.33 +/* Address arithmetic. */ 109.34 + 109.35 +offset_t page(unsigned int n); 109.36 + 109.37 +unsigned int page_order(offset_t size); 109.38 + 109.39 +offset_t round(offset_t value, offset_t increment); 109.40 + 109.41 +offset_t round_multiple(offset_t value, offset_t increment); 109.42 + 109.43 +offset_t trunc(offset_t value, offset_t increment); 109.44 + 109.45 +offset_t trunc_multiple(offset_t value, offset_t increment); 109.46 + 109.47 +offset_t max_multiple(offset_t start, offset_t end, offset_t increment); 109.48 + 109.49 +// vim: tabstop=4 expandtab shiftwidth=4
110.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 110.2 +++ b/libmem/include/mem/region.h Thu Apr 15 23:15:17 2021 +0200 110.3 @@ -0,0 +1,80 @@ 110.4 +/* 110.5 + * Memory region abstractions. 110.6 + * 110.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 110.8 + * 110.9 + * This program is free software; you can redistribute it and/or 110.10 + * modify it under the terms of the GNU General Public License as 110.11 + * published by the Free Software Foundation; either version 2 of 110.12 + * the License, or (at your option) any later version. 110.13 + * 110.14 + * This program is distributed in the hope that it will be useful, 110.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 110.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 110.17 + * GNU General Public License for more details. 110.18 + * 110.19 + * You should have received a copy of the GNU General Public License 110.20 + * along with this program; if not, write to the Free Software 110.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 110.22 + * Boston, MA 02110-1301, USA 110.23 + */ 110.24 + 110.25 +#pragma once 110.26 + 110.27 +#include <systypes/base.h> 110.28 + 110.29 +#include "types.h" 110.30 + 110.31 + 110.32 + 110.33 +/* Region-related state information. */ 110.34 + 110.35 +class RegionState 110.36 +{ 110.37 +public: 110.38 + unsigned long size; 110.39 + fileid_t fileid; 110.40 + offset_t filepos; 110.41 + 110.42 + explicit RegionState(unsigned long size=0, fileid_t fileid=0, offset_t filepos=0); 110.43 + 110.44 + void fill(fileid_t fileid, offset_t filepos); 110.45 + 110.46 + bool valid() { return size != 0; } 110.47 +}; 110.48 + 110.49 + 110.50 + 110.51 +/* A memory region abstraction. */ 110.52 + 110.53 +class Region 110.54 +{ 110.55 +public: 110.56 + offset_t start, end; 110.57 + 110.58 + /* Debugging information. */ 110.59 + 110.60 + RegionState state; 110.61 + 110.62 + /* Methods. */ 110.63 + 110.64 + explicit Region(offset_t start, offset_t end); 110.65 + 110.66 + virtual ~Region(); 110.67 + 110.68 + offset_t size(); 110.69 + 110.70 + int compare(Region *other); 110.71 + 110.72 + void fill(fileid_t fileid, offset_t filepos); 110.73 + 110.74 + void flush(); 110.75 + 110.76 + /* Simulation methods. */ 110.77 + 110.78 + char *read(offset_t offset=0); 110.79 + 110.80 + void write(const char *data, offset_t offset=0); 110.81 +}; 110.82 + 110.83 +// vim: tabstop=4 expandtab shiftwidth=4
111.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 111.2 +++ b/libmem/include/mem/send_flexpage.h Thu Apr 15 23:15:17 2021 +0200 111.3 @@ -0,0 +1,44 @@ 111.4 +/* 111.5 + * A "send" flexpage abstraction for communicating memory mappings. 111.6 + * 111.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 111.8 + * 111.9 + * This program is free software; you can redistribute it and/or 111.10 + * modify it under the terms of the GNU General Public License as 111.11 + * published by the Free Software Foundation; either version 2 of 111.12 + * the License, or (at your option) any later version. 111.13 + * 111.14 + * This program is distributed in the hope that it will be useful, 111.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 111.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 111.17 + * GNU General Public License for more details. 111.18 + * 111.19 + * You should have received a copy of the GNU General Public License 111.20 + * along with this program; if not, write to the Free Software 111.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 111.22 + * Boston, MA 02110-1301, USA 111.23 + */ 111.24 + 111.25 +#pragma once 111.26 + 111.27 +#include <systypes/base.h> 111.28 + 111.29 + 111.30 + 111.31 +/* A "send" flexpage abstraction. */ 111.32 + 111.33 +class SendFlexpage 111.34 +{ 111.35 +public: 111.36 + offset_t base_addr; 111.37 + unsigned int order; 111.38 + flags_t flags; 111.39 + 111.40 + explicit SendFlexpage(offset_t base_addr, unsigned int order, 111.41 + flags_t flags) 111.42 + : base_addr(base_addr), order(order), flags(flags) 111.43 + { 111.44 + } 111.45 +}; 111.46 + 111.47 +// vim: tabstop=4 expandtab shiftwidth=4
112.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 112.2 +++ b/libmem/include/mem/types.h Thu Apr 15 23:15:17 2021 +0200 112.3 @@ -0,0 +1,32 @@ 112.4 +/* 112.5 + * Miscellaneous types. 112.6 + * 112.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 112.8 + * 112.9 + * This program is free software; you can redistribute it and/or 112.10 + * modify it under the terms of the GNU General Public License as 112.11 + * published by the Free Software Foundation; either version 2 of 112.12 + * the License, or (at your option) any later version. 112.13 + * 112.14 + * This program is distributed in the hope that it will be useful, 112.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 112.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 112.17 + * GNU General Public License for more details. 112.18 + * 112.19 + * You should have received a copy of the GNU General Public License 112.20 + * along with this program; if not, write to the Free Software 112.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 112.22 + * Boston, MA 02110-1301, USA 112.23 + */ 112.24 + 112.25 +#pragma once 112.26 + 112.27 + 112.28 + 112.29 +/* File identification. */ 112.30 + 112.31 +typedef unsigned long fileid_t; 112.32 + 112.33 +#define FILEID_INVALID (~0UL) 112.34 + 112.35 +// vim: tabstop=4 expandtab shiftwidth=4
113.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 113.2 +++ b/libmem/lib/Makefile Thu Apr 15 23:15:17 2021 +0200 113.3 @@ -0,0 +1,4 @@ 113.4 +PKGDIR ?= .. 113.5 +L4DIR ?= $(PKGDIR)/../../.. 113.6 + 113.7 +include $(L4DIR)/mk/subdir.mk
114.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 114.2 +++ b/libmem/lib/src/Makefile Thu Apr 15 23:15:17 2021 +0200 114.3 @@ -0,0 +1,16 @@ 114.4 +PKGDIR ?= ../.. 114.5 +L4DIR ?= $(PKGDIR)/../../.. 114.6 + 114.7 +TARGET = libmem.so libmem.a 114.8 +PC_FILENAME = libmem 114.9 + 114.10 +SRC_CC = \ 114.11 + flexpage.cc memory_incremental.cc memory_preallocated.cc \ 114.12 + memory_utils.cc region.cc 114.13 + 114.14 +REQUIRES_LIBS = l4re_c-util libstdc++ libsystypes 114.15 + 114.16 +PRIVATE_INCDIR = $(PKGDIR)/include $(PKGDIR)/include/mem 114.17 +CONTRIB_INCDIR = libmem 114.18 + 114.19 +include $(L4DIR)/mk/lib.mk
115.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 115.2 +++ b/libmem/lib/src/flexpage.cc Thu Apr 15 23:15:17 2021 +0200 115.3 @@ -0,0 +1,163 @@ 115.4 +/* 115.5 + * A flexpage abstraction. 115.6 + * 115.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 115.8 + * 115.9 + * This program is free software; you can redistribute it and/or 115.10 + * modify it under the terms of the GNU General Public License as 115.11 + * published by the Free Software Foundation; either version 2 of 115.12 + * the License, or (at your option) any later version. 115.13 + * 115.14 + * This program is distributed in the hope that it will be useful, 115.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 115.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 115.17 + * GNU General Public License for more details. 115.18 + * 115.19 + * You should have received a copy of the GNU General Public License 115.20 + * along with this program; if not, write to the Free Software 115.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 115.22 + * Boston, MA 02110-1301, USA 115.23 + */ 115.24 + 115.25 +#include <algorithm> 115.26 + 115.27 +#include "flexpage.h" 115.28 + 115.29 + 115.30 + 115.31 +/* Reset the flexpage using 'offset', being the file offset. */ 115.32 + 115.33 +void Flexpage::reset(offset_t offset) 115.34 +{ 115.35 + _counter = 0; 115.36 + 115.37 + /* By definition (see "Flexible-Sized Page Objects - Object-Orientation 115.38 + in Operation Systems"), flexpages are aligned to multiples of their 115.39 + size. 115.40 + 115.41 + The size of the flexpage depends on the amount of space around the 115.42 + accessed page. It cannot exceed the size of the memory region. */ 115.43 + 115.44 + size = max_multiple(region->start, region->end, PAGE_SIZE); 115.45 + 115.46 + /* The base address of the flexpage is computed from the region start 115.47 + and flexpage size. It will be no lower than the region start. 115.48 + 115.49 + Sent flexpages may use higher bases due to receive window constraints, 115.50 + these being communicated by the "hot spot". */ 115.51 + 115.52 + base_addr = round(region->start, size); 115.53 + 115.54 + /* Get the file offset for the base of the flexpage. This will be a 115.55 + multiple of the flexpage size for alignment purposes. */ 115.56 + 115.57 + base_offset = trunc(offset, size); 115.58 + 115.59 + /* The page being accessed is relative to the base. 115.60 + (This is transient information recording the initialising access 115.61 + details.) */ 115.62 + 115.63 + page_offset = trunc(offset - base_offset, PAGE_SIZE); 115.64 + page_addr = base_addr + page_offset; 115.65 +} 115.66 + 115.67 +bool Flexpage::decrement() 115.68 +{ 115.69 + if (_counter) 115.70 + { 115.71 + _counter--; 115.72 + return _counter == 0; 115.73 + } 115.74 + else 115.75 + return 0; 115.76 +} 115.77 + 115.78 +void Flexpage::increment() 115.79 +{ 115.80 + _counter++; 115.81 +} 115.82 + 115.83 +void Flexpage::invalidate() 115.84 +{ 115.85 + _counter = 0; 115.86 +} 115.87 + 115.88 +bool Flexpage::valid() 115.89 +{ 115.90 + return _counter != 0; 115.91 +} 115.92 + 115.93 +/* Return whether the flexpage supports the given file 'position'. */ 115.94 + 115.95 +bool Flexpage::supports_position(offset_t position) 115.96 +{ 115.97 + return (base_offset <= position) && (position < (base_offset + size)); 115.98 +} 115.99 + 115.100 +/* Upgrade the flags involved with this flexpage. This is used to track the 115.101 + maximal flags employed by the different pagers, with the result being used in 115.102 + unmap operations. */ 115.103 + 115.104 +void Flexpage::upgrade(flags_t flags) 115.105 +{ 115.106 + if (flags && (flags != _flags)) 115.107 + _flags |= flags; 115.108 +} 115.109 + 115.110 +/* Return a "send" flexpage for an access to 'offset' by positioning it relative 115.111 + to 'hot_spot' for the receive flexpage window. */ 115.112 + 115.113 +SendFlexpage Flexpage::to_send(offset_t offset, offset_t hot_spot, 115.114 + flags_t flags, offset_t max_offset) 115.115 +{ 115.116 + /* The dataspace offset of the flexpage base is a multiple of the flexpage 115.117 + size. */ 115.118 + 115.119 + offset_t receive_base_offset = trunc(offset, size); 115.120 + 115.121 + /* The offset of the accessed page within the flexpage is constrained by the 115.122 + current flexpage size. */ 115.123 + 115.124 + offset_t page_offset = trunc(offset - receive_base_offset, PAGE_SIZE); 115.125 + 115.126 + /* The receive flexpage offset (hot spot) must be constrained to the 115.127 + flexpage, both the size and the start. */ 115.128 + 115.129 + offset_t receive_size; 115.130 + 115.131 + if (max_offset) 115.132 + { 115.133 + receive_size = trunc_multiple(max_offset - receive_base_offset, PAGE_SIZE); 115.134 + receive_size = std::min(size, receive_size); 115.135 + } 115.136 + else 115.137 + receive_size = size; 115.138 + 115.139 + if (!receive_size) 115.140 + return SendFlexpage(base_addr, page_order(0), flags); 115.141 + 115.142 + offset_t receive_page_offset = hot_spot % receive_size; 115.143 + 115.144 + while ((receive_size > PAGE_SIZE) && (receive_page_offset != page_offset)) 115.145 + { 115.146 + receive_size /= 2; 115.147 + receive_page_offset = hot_spot % receive_size; 115.148 + } 115.149 + 115.150 + /* The flexpage base address is adjusted using the difference in page 115.151 + offsets. Where the receive flexpage offset is constained further, the 115.152 + base address will be raised to become closer to the accessed page. */ 115.153 + 115.154 + offset_t adjustment = page_offset - receive_page_offset; 115.155 + 115.156 + return SendFlexpage(base_addr + adjustment, page_order(receive_size), flags); 115.157 +} 115.158 + 115.159 +/* Return a representation of the flexpage for unmapping. */ 115.160 + 115.161 +SendFlexpage Flexpage::to_unmap() 115.162 +{ 115.163 + return SendFlexpage(base_addr, page_order(size), _flags); 115.164 +} 115.165 + 115.166 +// vim: tabstop=4 expandtab shiftwidth=4
116.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 116.2 +++ b/libmem/lib/src/memory_incremental.cc Thu Apr 15 23:15:17 2021 +0200 116.3 @@ -0,0 +1,110 @@ 116.4 +/* 116.5 + * A memory pool allocating a region at a time from the system. 116.6 + * 116.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 116.8 + * 116.9 + * This program is free software; you can redistribute it and/or 116.10 + * modify it under the terms of the GNU General Public License as 116.11 + * published by the Free Software Foundation; either version 2 of 116.12 + * the License, or (at your option) any later version. 116.13 + * 116.14 + * This program is distributed in the hope that it will be useful, 116.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 116.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 116.17 + * GNU General Public License for more details. 116.18 + * 116.19 + * You should have received a copy of the GNU General Public License 116.20 + * along with this program; if not, write to the Free Software 116.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 116.22 + * Boston, MA 02110-1301, USA 116.23 + */ 116.24 + 116.25 +#include "memory_incremental.h" 116.26 + 116.27 +#include <stdlib.h> 116.28 + 116.29 +/* Initialise the memory pool with an optional 'limit' in pages. */ 116.30 + 116.31 +MemoryIncremental::MemoryIncremental(unsigned int limit, offset_t region_size) 116.32 +: _limit(limit), _region_size(region_size) 116.33 +{ 116.34 + _limited = true; 116.35 +} 116.36 + 116.37 +MemoryIncremental::MemoryIncremental() 116.38 +: _region_size(PAGE_SIZE) 116.39 +{ 116.40 + _limited = false; 116.41 +} 116.42 + 116.43 +/* Allocate a block of the given 'size'. */ 116.44 + 116.45 +Region *MemoryIncremental::allocate(offset_t size) 116.46 +{ 116.47 + /* Attempt to allocate aligned memory. */ 116.48 + 116.49 + void *current; 116.50 + 116.51 + /* Make the size appropriate for the invocation. */ 116.52 + 116.53 + size = round_multiple(size, PAGE_SIZE); 116.54 + 116.55 + if (posix_memalign(¤t, size, size)) 116.56 + return NULL; 116.57 + 116.58 + return new Region((offset_t) current, (offset_t) current + size); 116.59 +} 116.60 + 116.61 +/* Allocate a new region of the given 'size' rounded to the nearest page. */ 116.62 + 116.63 +Region *MemoryIncremental::region(offset_t size) 116.64 +{ 116.65 + std::lock_guard<std::mutex> guard(_lock); 116.66 + 116.67 + offset_t rounded = round(size, PAGE_SIZE); 116.68 + offset_t pages = rounded / PAGE_SIZE; 116.69 + 116.70 + /* Check for sufficient pages. */ 116.71 + 116.72 + if (!_limited || (_limit >= pages)) 116.73 + { 116.74 + /* Attempt to allocate aligned memory. */ 116.75 + 116.76 + Region *region = allocate(rounded); 116.77 + 116.78 + if (region == NULL) 116.79 + return NULL; 116.80 + 116.81 + if (_limited) 116.82 + _limit -= pages; 116.83 + 116.84 + return region; 116.85 + } 116.86 + 116.87 + /* Return no region without sufficient pages. */ 116.88 + 116.89 + else 116.90 + return NULL; 116.91 +} 116.92 + 116.93 +Region *MemoryIncremental::region() 116.94 +{ 116.95 + return region(_region_size); 116.96 +} 116.97 + 116.98 +/* Release the allocated 'region'. */ 116.99 + 116.100 +void MemoryIncremental::release(Region *region) 116.101 +{ 116.102 + std::lock_guard<std::mutex> guard(_lock); 116.103 + 116.104 + offset_t rounded = round(region->size(), PAGE_SIZE); 116.105 + offset_t pages = rounded / PAGE_SIZE; 116.106 + 116.107 + if (_limited) 116.108 + _limit += pages; 116.109 + 116.110 + delete region; 116.111 +} 116.112 + 116.113 +// vim: tabstop=4 expandtab shiftwidth=4
117.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 117.2 +++ b/libmem/lib/src/memory_preallocated.cc Thu Apr 15 23:15:17 2021 +0200 117.3 @@ -0,0 +1,80 @@ 117.4 +/* 117.5 + * A memory pool providing regions from a preallocated amount of memory. 117.6 + * 117.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 117.8 + * 117.9 + * This program is free software; you can redistribute it and/or 117.10 + * modify it under the terms of the GNU General Public License as 117.11 + * published by the Free Software Foundation; either version 2 of 117.12 + * the License, or (at your option) any later version. 117.13 + * 117.14 + * This program is distributed in the hope that it will be useful, 117.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 117.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 117.17 + * GNU General Public License for more details. 117.18 + * 117.19 + * You should have received a copy of the GNU General Public License 117.20 + * along with this program; if not, write to the Free Software 117.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 117.22 + * Boston, MA 02110-1301, USA 117.23 + */ 117.24 + 117.25 +#include "memory_preallocated.h" 117.26 + 117.27 + 117.28 + 117.29 +/* Initialise the memory pool with the given amount in bytes. */ 117.30 + 117.31 +MemoryPreallocated::MemoryPreallocated(Memory *memory, offset_t amount) 117.32 +: _memory(memory), _amount(amount) 117.33 +{ 117.34 + // NOTE: Handle allocation failure. 117.35 + 117.36 + offset_t remaining = amount; 117.37 + 117.38 + while (remaining) 117.39 + { 117.40 + _regions.push_back(memory->region()); 117.41 + 117.42 + if (memory->region_size() >= remaining) 117.43 + break; 117.44 + 117.45 + remaining -= memory->region_size(); 117.46 + } 117.47 +} 117.48 + 117.49 +/* Discard all unused regions. */ 117.50 + 117.51 +MemoryPreallocated::~MemoryPreallocated() 117.52 +{ 117.53 + while (!_regions.empty()) 117.54 + { 117.55 + Region *region = _regions.front(); 117.56 + 117.57 + _regions.pop_front(); 117.58 + _memory->release(region); 117.59 + } 117.60 +} 117.61 + 117.62 +/* Obtain an allocated region. */ 117.63 + 117.64 +Region *MemoryPreallocated::region() 117.65 +{ 117.66 + std::lock_guard<std::mutex> guard(_lock); 117.67 + 117.68 + Region *region = _regions.front(); 117.69 + 117.70 + _regions.pop_front(); 117.71 + return region; 117.72 +} 117.73 + 117.74 +/* Release the allocated 'region'. */ 117.75 + 117.76 +void MemoryPreallocated::release(Region *region) 117.77 +{ 117.78 + std::lock_guard<std::mutex> guard(_lock); 117.79 + 117.80 + _regions.push_back(region); 117.81 +} 117.82 + 117.83 +// vim: tabstop=4 expandtab shiftwidth=4
118.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 118.2 +++ b/libmem/lib/src/memory_utils.cc Thu Apr 15 23:15:17 2021 +0200 118.3 @@ -0,0 +1,132 @@ 118.4 +/* 118.5 + * Memory quantity calculation utilities. 118.6 + * 118.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 118.8 + * 118.9 + * This program is free software; you can redistribute it and/or 118.10 + * modify it under the terms of the GNU General Public License as 118.11 + * published by the Free Software Foundation; either version 2 of 118.12 + * the License, or (at your option) any later version. 118.13 + * 118.14 + * This program is distributed in the hope that it will be useful, 118.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 118.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 118.17 + * GNU General Public License for more details. 118.18 + * 118.19 + * You should have received a copy of the GNU General Public License 118.20 + * along with this program; if not, write to the Free Software 118.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 118.22 + * Boston, MA 02110-1301, USA 118.23 + */ 118.24 + 118.25 +#include "memory_utils.h" 118.26 + 118.27 + 118.28 + 118.29 +/* Return page 'n' for the configured page size. */ 118.30 + 118.31 +offset_t page(unsigned int n) 118.32 +{ 118.33 + return PAGE_SIZE * n; 118.34 +} 118.35 + 118.36 +/* Return the order of 'size', where 2 ** order yields the size. */ 118.37 + 118.38 +unsigned int page_order(offset_t size) 118.39 +{ 118.40 + /* Count zeros from the left, stopping at the first set bit, using the width 118.41 + of the size value (in bits, starting with the width in bytes) to 118.42 + calculate the position of this bit and thus the order of the value. */ 118.43 + 118.44 + return sizeof(unsigned long) * 8 - 1 - __builtin_clzl(size); 118.45 +} 118.46 + 118.47 +/* Return 'value' rounded up to the nearest 'increment'. */ 118.48 + 118.49 +offset_t round(offset_t value, offset_t increment) 118.50 +{ 118.51 + return trunc(value + increment - 1, increment); 118.52 +} 118.53 + 118.54 +/* Return 'value' rounded up to the nearest multiple of 'increment'. */ 118.55 + 118.56 +offset_t round_multiple(offset_t value, offset_t increment) 118.57 +{ 118.58 + offset_t last = increment; 118.59 + 118.60 + while (1) 118.61 + { 118.62 + if (value < increment) 118.63 + return round(value, last); 118.64 + 118.65 + last = increment; 118.66 + increment *= 2; 118.67 + } 118.68 +} 118.69 + 118.70 +/* Return 'value' rounded down (or truncated) to the nearest 'increment'. */ 118.71 + 118.72 +offset_t trunc(offset_t value, offset_t increment) 118.73 +{ 118.74 + return (value / increment) * increment; 118.75 +} 118.76 + 118.77 +/* Return 'value' rounded down (or truncated) to the nearest multiple of 118.78 + 'increment'. */ 118.79 + 118.80 +offset_t trunc_multiple(offset_t value, offset_t increment) 118.81 +{ 118.82 + offset_t last = increment; 118.83 + 118.84 + while (1) 118.85 + { 118.86 + if (value < increment) 118.87 + return trunc(value, last); 118.88 + 118.89 + last = increment; 118.90 + increment *= 2; 118.91 + } 118.92 +} 118.93 + 118.94 +/* Find the maximum size aligned region within the region from 'start' to (but 118.95 + not including) 'end', with the given initial 'increment'. */ 118.96 + 118.97 +offset_t max_multiple(offset_t start, offset_t end, offset_t increment) 118.98 +{ 118.99 + /* The largest possible aligned region is derived from the region size. */ 118.100 + 118.101 + offset_t size = trunc_multiple(end - start, increment); 118.102 + 118.103 + /* Apply the alignment to the start. */ 118.104 + 118.105 + offset_t aligned = round(start, size); 118.106 + 118.107 + /* If the region is aligned, return the size. */ 118.108 + 118.109 + if (aligned == start) 118.110 + return size; 118.111 + 118.112 + /* If the region is not aligned to the current size, recalculate the aligned 118.113 + size. */ 118.114 + 118.115 + offset_t aligned_size; 118.116 + 118.117 + do 118.118 + { 118.119 + aligned_size = trunc_multiple(end - aligned, increment); 118.120 + size /= 2; 118.121 + 118.122 + /* Determine whether a smaller alignment could yield a larger aligned 118.123 + size. */ 118.124 + 118.125 + if (aligned_size >= size) 118.126 + return aligned_size; 118.127 + 118.128 + aligned = round(start, size); 118.129 + } 118.130 + while (aligned > start); 118.131 + 118.132 + return aligned_size; 118.133 +} 118.134 + 118.135 +// vim: tabstop=4 expandtab shiftwidth=4
119.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 119.2 +++ b/libmem/lib/src/region.cc Thu Apr 15 23:15:17 2021 +0200 119.3 @@ -0,0 +1,104 @@ 119.4 +/* 119.5 + * Memory region abstractions. 119.6 + * 119.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 119.8 + * 119.9 + * This program is free software; you can redistribute it and/or 119.10 + * modify it under the terms of the GNU General Public License as 119.11 + * published by the Free Software Foundation; either version 2 of 119.12 + * the License, or (at your option) any later version. 119.13 + * 119.14 + * This program is distributed in the hope that it will be useful, 119.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 119.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 119.17 + * GNU General Public License for more details. 119.18 + * 119.19 + * You should have received a copy of the GNU General Public License 119.20 + * along with this program; if not, write to the Free Software 119.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 119.22 + * Boston, MA 02110-1301, USA 119.23 + */ 119.24 + 119.25 +#include <string.h> 119.26 +#include <stdlib.h> 119.27 + 119.28 +#include "region.h" 119.29 + 119.30 + 119.31 + 119.32 +/* Initialise region state, indicating the size, file and position. */ 119.33 + 119.34 +RegionState::RegionState(unsigned long size, fileid_t fileid, offset_t filepos) 119.35 +: size(size), fileid(fileid), filepos(filepos) 119.36 +{ 119.37 +} 119.38 + 119.39 +void RegionState::fill(fileid_t fileid, offset_t filepos) 119.40 +{ 119.41 + this->fileid = fileid; 119.42 + this->filepos = filepos; 119.43 +} 119.44 + 119.45 + 119.46 + 119.47 +/* Initialise a region having the given 'start' and 'end' addresses, with the 119.48 + 'end' being one location beyond the last address in the region. */ 119.49 + 119.50 +Region::Region(offset_t start, offset_t end) 119.51 +: start(start), end(end), state(end - start) 119.52 +{ 119.53 + /* Content state. */ 119.54 + 119.55 + memset((void *) start, 0, end - start); 119.56 +} 119.57 + 119.58 +Region::~Region() 119.59 +{ 119.60 + free((void *) start); 119.61 +} 119.62 + 119.63 +offset_t Region::size() 119.64 +{ 119.65 + return end - start; 119.66 +} 119.67 + 119.68 +/* Debugging methods. */ 119.69 + 119.70 +int Region::compare(Region *other) 119.71 +{ 119.72 + if (start < other->start) 119.73 + return -1; 119.74 + else if (start > other->start) 119.75 + return 1; 119.76 + else 119.77 + return 0; 119.78 +} 119.79 + 119.80 +void Region::fill(fileid_t fileid, offset_t filepos) 119.81 +{ 119.82 + state.fill(fileid, filepos); 119.83 +} 119.84 + 119.85 +void Region::flush() 119.86 +{ 119.87 +} 119.88 + 119.89 +/* Simulation methods. */ 119.90 + 119.91 +char *Region::read(offset_t offset) 119.92 +{ 119.93 + if (offset < size()) 119.94 + return (char *) start + offset; 119.95 + else 119.96 + return NULL; 119.97 +} 119.98 + 119.99 +void Region::write(const char *data, offset_t offset) 119.100 +{ 119.101 + size_t length = strlen(data); 119.102 + 119.103 + if (offset + length < size()) 119.104 + memcpy((void *) (start + offset), data, length + 1); 119.105 +} 119.106 + 119.107 +// vim: tabstop=4 expandtab shiftwidth=4
120.1 --- a/mapping/access_map.cc Tue Apr 13 00:03:18 2021 +0200 120.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 120.3 @@ -1,155 +0,0 @@ 120.4 -/* 120.5 - * An access map providing memory corresponding to file regions. 120.6 - * 120.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 120.8 - * 120.9 - * This program is free software; you can redistribute it and/or 120.10 - * modify it under the terms of the GNU General Public License as 120.11 - * published by the Free Software Foundation; either version 2 of 120.12 - * the License, or (at your option) any later version. 120.13 - * 120.14 - * This program is distributed in the hope that it will be useful, 120.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 120.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 120.17 - * GNU General Public License for more details. 120.18 - * 120.19 - * You should have received a copy of the GNU General Public License 120.20 - * along with this program; if not, write to the Free Software 120.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 120.22 - * Boston, MA 02110-1301, USA 120.23 - */ 120.24 - 120.25 -#include "access_map.h" 120.26 - 120.27 -/* Return the flexpage supporting 'position'. */ 120.28 - 120.29 -Flexpage *AccessMap::find(offset_t position) 120.30 -{ 120.31 - std::lock_guard<std::mutex> guard(_lock); 120.32 - 120.33 - _AccessMap::iterator it = _flexpages.upper_bound(position); 120.34 - 120.35 - if ((_flexpages.size() > 0) && (it != _flexpages.begin())) 120.36 - { 120.37 - it--; 120.38 - 120.39 - if (it->second->supports_position(position)) 120.40 - return it->second; 120.41 - } 120.42 - 120.43 - return NULL; 120.44 -} 120.45 - 120.46 -/* Insert a mapping for 'flexpage'. */ 120.47 - 120.48 -void AccessMap::insert(Flexpage *flexpage) 120.49 -{ 120.50 - std::lock_guard<std::mutex> guard(_lock); 120.51 - 120.52 - _flexpages.insert(_AccessMapEntry(flexpage->base_offset, flexpage)); 120.53 -} 120.54 - 120.55 -/* Remove the mapping supported by 'flexpage'. 120.56 - 120.57 - The flexpage may have obtained by another mapper before being purged from 120.58 - this object's mapping and before being purged from the queue (and thus 120.59 - disassociated from this mapper), leaving an opportunity for another mapper to 120.60 - now be removing it here. In such a situation, flushing has already occurred 120.61 - and will not be performed again. */ 120.62 - 120.63 -bool AccessMap::remove(PageOwner *owner, Flexpage *flexpage) 120.64 -{ 120.65 - std::lock_guard<std::mutex> guard(_lock); 120.66 - 120.67 - _AccessMap::iterator it = _flexpages.find(flexpage->base_offset); 120.68 - 120.69 - if (it != _flexpages.end()) 120.70 - { 120.71 - owner->flush(flexpage, true); 120.72 - _flexpages.erase(flexpage->base_offset); 120.73 - return true; 120.74 - } 120.75 - 120.76 - return false; 120.77 -} 120.78 - 120.79 -/* Purge all flexpages, using the 'owner' to flush their contents and 120.80 - 'pages' to make the flexpages available to other accessors. */ 120.81 - 120.82 -void AccessMap::purge(PageOwner *owner, Pages *pages) 120.83 -{ 120.84 - std::lock_guard<std::mutex> guard(_lock); 120.85 - 120.86 - _AccessMap::iterator it = _flexpages.begin(), entry; 120.87 - 120.88 - while (it != _flexpages.end()) 120.89 - { 120.90 - entry = it; 120.91 - it++; 120.92 - 120.93 - Flexpage *flexpage = entry->second; 120.94 - 120.95 - /* Some flexpages may be unavailable in the queue. Only those 120.96 - that can be reserved should be flushed and made available 120.97 - again. */ 120.98 - 120.99 - if (pages->reserve(owner, flexpage)) 120.100 - { 120.101 - owner->flush(flexpage, true); 120.102 - pages->release(flexpage); 120.103 - _flexpages.erase(entry); 120.104 - } 120.105 - } 120.106 -} 120.107 - 120.108 -/* Flush flexpages in the given range from 'start' with 'size', using 'owner' 120.109 - and 'pages'. */ 120.110 - 120.111 -void AccessMap::flush_all(offset_t start, offset_t size, PageOwner *owner, Pages *pages) 120.112 -{ 120.113 - offset_t end = start + size; 120.114 - 120.115 - std::lock_guard<std::mutex> guard(_lock); 120.116 - 120.117 - /* The start may be within an existing flexpage where the flexpage size is a 120.118 - page multiple. */ 120.119 - 120.120 - _AccessMap::iterator it = _flexpages.upper_bound(start), entry; 120.121 - 120.122 - if ((_flexpages.size() > 0) && (it != _flexpages.begin())) 120.123 - it--; 120.124 - 120.125 - /* Inspect flexpages at or after start until end. */ 120.126 - 120.127 - while (it != _flexpages.end()) 120.128 - { 120.129 - entry = it; 120.130 - it++; 120.131 - 120.132 - Flexpage *flexpage = entry->second; 120.133 - 120.134 - if (flexpage->base_offset >= end) 120.135 - break; 120.136 - 120.137 - /* Attempt to flush each flexpage, releasing ones that are no longer 120.138 - needed. */ 120.139 - 120.140 - if (pages->reserve(owner, flexpage)) 120.141 - { 120.142 - owner->flush(flexpage, false); 120.143 - 120.144 - /* Where no users of the flexpage persist, release the flexpage for 120.145 - reuse and remove this entry. */ 120.146 - 120.147 - if (!flexpage->valid()) 120.148 - { 120.149 - pages->release(flexpage); 120.150 - _flexpages.erase(entry); 120.151 - } 120.152 - else 120.153 - pages->queue(owner, flexpage); 120.154 - } 120.155 - } 120.156 -} 120.157 - 120.158 -// vim: tabstop=4 expandtab shiftwidth=4
121.1 --- a/mapping/access_map.h Tue Apr 13 00:03:18 2021 +0200 121.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 121.3 @@ -1,60 +0,0 @@ 121.4 -/* 121.5 - * An access map providing memory corresponding to file regions. 121.6 - * 121.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 121.8 - * 121.9 - * This program is free software; you can redistribute it and/or 121.10 - * modify it under the terms of the GNU General Public License as 121.11 - * published by the Free Software Foundation; either version 2 of 121.12 - * the License, or (at your option) any later version. 121.13 - * 121.14 - * This program is distributed in the hope that it will be useful, 121.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 121.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 121.17 - * GNU General Public License for more details. 121.18 - * 121.19 - * You should have received a copy of the GNU General Public License 121.20 - * along with this program; if not, write to the Free Software 121.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 121.22 - * Boston, MA 02110-1301, USA 121.23 - */ 121.24 - 121.25 -#pragma once 121.26 - 121.27 -#include "flexpage.h" 121.28 -#include "page_owner.h" 121.29 -#include "pages.h" 121.30 - 121.31 -#include <map> 121.32 -#include <mutex> 121.33 - 121.34 - 121.35 - 121.36 -/* Collection types. */ 121.37 - 121.38 -typedef std::map<offset_t, Flexpage *> _AccessMap; 121.39 -typedef std::pair<offset_t, Flexpage *> _AccessMapEntry; 121.40 - 121.41 - 121.42 - 121.43 -/* A mapping from file positions to flexpages. */ 121.44 - 121.45 -class AccessMap 121.46 -{ 121.47 -protected: 121.48 - _AccessMap _flexpages; 121.49 - std::mutex _lock; 121.50 - 121.51 -public: 121.52 - Flexpage *find(offset_t position); 121.53 - 121.54 - void insert(Flexpage *flexpage); 121.55 - 121.56 - bool remove(PageOwner *owner, Flexpage *flexpage); 121.57 - 121.58 - void purge(PageOwner *owner, Pages *pages); 121.59 - 121.60 - void flush_all(offset_t start, offset_t size, PageOwner *owner, Pages *pages); 121.61 -}; 121.62 - 121.63 -// vim: tabstop=4 expandtab shiftwidth=4
122.1 --- a/mapping/flexpage.cc Tue Apr 13 00:03:18 2021 +0200 122.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 122.3 @@ -1,163 +0,0 @@ 122.4 -/* 122.5 - * A flexpage abstraction. 122.6 - * 122.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 122.8 - * 122.9 - * This program is free software; you can redistribute it and/or 122.10 - * modify it under the terms of the GNU General Public License as 122.11 - * published by the Free Software Foundation; either version 2 of 122.12 - * the License, or (at your option) any later version. 122.13 - * 122.14 - * This program is distributed in the hope that it will be useful, 122.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 122.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 122.17 - * GNU General Public License for more details. 122.18 - * 122.19 - * You should have received a copy of the GNU General Public License 122.20 - * along with this program; if not, write to the Free Software 122.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 122.22 - * Boston, MA 02110-1301, USA 122.23 - */ 122.24 - 122.25 -#include <algorithm> 122.26 - 122.27 -#include "flexpage.h" 122.28 - 122.29 - 122.30 - 122.31 -/* Reset the flexpage using 'offset', being the file offset. */ 122.32 - 122.33 -void Flexpage::reset(offset_t offset) 122.34 -{ 122.35 - _counter = 0; 122.36 - 122.37 - /* By definition (see "Flexible-Sized Page Objects - Object-Orientation 122.38 - in Operation Systems"), flexpages are aligned to multiples of their 122.39 - size. 122.40 - 122.41 - The size of the flexpage depends on the amount of space around the 122.42 - accessed page. It cannot exceed the size of the memory region. */ 122.43 - 122.44 - size = max_multiple(region->start, region->end, PAGE_SIZE); 122.45 - 122.46 - /* The base address of the flexpage is computed from the region start 122.47 - and flexpage size. It will be no lower than the region start. 122.48 - 122.49 - Sent flexpages may use higher bases due to receive window constraints, 122.50 - these being communicated by the "hot spot". */ 122.51 - 122.52 - base_addr = round(region->start, size); 122.53 - 122.54 - /* Get the file offset for the base of the flexpage. This will be a 122.55 - multiple of the flexpage size for alignment purposes. */ 122.56 - 122.57 - base_offset = trunc(offset, size); 122.58 - 122.59 - /* The page being accessed is relative to the base. 122.60 - (This is transient information recording the initialising access 122.61 - details.) */ 122.62 - 122.63 - page_offset = trunc(offset - base_offset, PAGE_SIZE); 122.64 - page_addr = base_addr + page_offset; 122.65 -} 122.66 - 122.67 -bool Flexpage::decrement() 122.68 -{ 122.69 - if (_counter) 122.70 - { 122.71 - _counter--; 122.72 - return _counter == 0; 122.73 - } 122.74 - else 122.75 - return 0; 122.76 -} 122.77 - 122.78 -void Flexpage::increment() 122.79 -{ 122.80 - _counter++; 122.81 -} 122.82 - 122.83 -void Flexpage::invalidate() 122.84 -{ 122.85 - _counter = 0; 122.86 -} 122.87 - 122.88 -bool Flexpage::valid() 122.89 -{ 122.90 - return _counter != 0; 122.91 -} 122.92 - 122.93 -/* Return whether the flexpage supports the given file 'position'. */ 122.94 - 122.95 -bool Flexpage::supports_position(offset_t position) 122.96 -{ 122.97 - return (base_offset <= position) && (position < (base_offset + size)); 122.98 -} 122.99 - 122.100 -/* Upgrade the flags involved with this flexpage. This is used to track the 122.101 - maximal flags employed by the different pagers, with the result being used in 122.102 - unmap operations. */ 122.103 - 122.104 -void Flexpage::upgrade(flags_t flags) 122.105 -{ 122.106 - if (flags && (flags != _flags)) 122.107 - _flags |= flags; 122.108 -} 122.109 - 122.110 -/* Return a "send" flexpage for an access to 'offset' by positioning it relative 122.111 - to 'hot_spot' for the receive flexpage window. */ 122.112 - 122.113 -SendFlexpage Flexpage::to_send(offset_t offset, offset_t hot_spot, 122.114 - flags_t flags, offset_t max_offset) 122.115 -{ 122.116 - /* The dataspace offset of the flexpage base is a multiple of the flexpage 122.117 - size. */ 122.118 - 122.119 - offset_t receive_base_offset = trunc(offset, size); 122.120 - 122.121 - /* The offset of the accessed page within the flexpage is constrained by the 122.122 - current flexpage size. */ 122.123 - 122.124 - offset_t page_offset = trunc(offset - receive_base_offset, PAGE_SIZE); 122.125 - 122.126 - /* The receive flexpage offset (hot spot) must be constrained to the 122.127 - flexpage, both the size and the start. */ 122.128 - 122.129 - offset_t receive_size; 122.130 - 122.131 - if (max_offset) 122.132 - { 122.133 - receive_size = trunc_multiple(max_offset - receive_base_offset, PAGE_SIZE); 122.134 - receive_size = std::min(size, receive_size); 122.135 - } 122.136 - else 122.137 - receive_size = size; 122.138 - 122.139 - if (!receive_size) 122.140 - return SendFlexpage(base_addr, page_order(0), flags); 122.141 - 122.142 - offset_t receive_page_offset = hot_spot % receive_size; 122.143 - 122.144 - while ((receive_size > PAGE_SIZE) && (receive_page_offset != page_offset)) 122.145 - { 122.146 - receive_size /= 2; 122.147 - receive_page_offset = hot_spot % receive_size; 122.148 - } 122.149 - 122.150 - /* The flexpage base address is adjusted using the difference in page 122.151 - offsets. Where the receive flexpage offset is constained further, the 122.152 - base address will be raised to become closer to the accessed page. */ 122.153 - 122.154 - offset_t adjustment = page_offset - receive_page_offset; 122.155 - 122.156 - return SendFlexpage(base_addr + adjustment, page_order(receive_size), flags); 122.157 -} 122.158 - 122.159 -/* Return a representation of the flexpage for unmapping. */ 122.160 - 122.161 -SendFlexpage Flexpage::to_unmap() 122.162 -{ 122.163 - return SendFlexpage(base_addr, page_order(size), _flags); 122.164 -} 122.165 - 122.166 -// vim: tabstop=4 expandtab shiftwidth=4
123.1 --- a/mapping/flexpage.h Tue Apr 13 00:03:18 2021 +0200 123.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 123.3 @@ -1,76 +0,0 @@ 123.4 -/* 123.5 - * A flexpage abstraction. 123.6 - * 123.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 123.8 - * 123.9 - * This program is free software; you can redistribute it and/or 123.10 - * modify it under the terms of the GNU General Public License as 123.11 - * published by the Free Software Foundation; either version 2 of 123.12 - * the License, or (at your option) any later version. 123.13 - * 123.14 - * This program is distributed in the hope that it will be useful, 123.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 123.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 123.17 - * GNU General Public License for more details. 123.18 - * 123.19 - * You should have received a copy of the GNU General Public License 123.20 - * along with this program; if not, write to the Free Software 123.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 123.22 - * Boston, MA 02110-1301, USA 123.23 - */ 123.24 - 123.25 -#pragma once 123.26 - 123.27 -#include "memory_utils.h" 123.28 -#include "region.h" 123.29 -#include "send_flexpage.h" 123.30 - 123.31 - 123.32 - 123.33 -/* A flexpage abstraction. */ 123.34 - 123.35 -class Flexpage 123.36 -{ 123.37 -protected: 123.38 - unsigned int _counter; 123.39 - flags_t _flags; 123.40 - 123.41 -public: 123.42 - Region *region; 123.43 - 123.44 - /* General flexpage characteristics. */ 123.45 - 123.46 - offset_t base_addr, size; 123.47 - offset_t base_offset; 123.48 - 123.49 - /* Transient debugging information. */ 123.50 - 123.51 - offset_t page_addr, page_offset; 123.52 - 123.53 - /* Associate a flexpage with a memory 'region'. */ 123.54 - 123.55 - explicit Flexpage(Region *region) : region(region) 123.56 - { 123.57 - } 123.58 - 123.59 - void reset(offset_t offset); 123.60 - 123.61 - bool decrement(); 123.62 - 123.63 - void increment(); 123.64 - 123.65 - void invalidate(); 123.66 - 123.67 - bool valid(); 123.68 - 123.69 - bool supports_position(offset_t position); 123.70 - 123.71 - void upgrade(flags_t flags); 123.72 - 123.73 - SendFlexpage to_send(offset_t offset, offset_t hot_spot, flags_t flags, 123.74 - offset_t max_offset=0); 123.75 - 123.76 - SendFlexpage to_unmap(); 123.77 -}; 123.78 - 123.79 -// vim: tabstop=4 expandtab shiftwidth=4
124.1 --- a/mapping/ipc.cc Tue Apr 13 00:03:18 2021 +0200 124.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 124.3 @@ -1,68 +0,0 @@ 124.4 -/* 124.5 - * Interprocess communication utilities. 124.6 - * 124.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 124.8 - * 124.9 - * This program is free software; you can redistribute it and/or 124.10 - * modify it under the terms of the GNU General Public License as 124.11 - * published by the Free Software Foundation; either version 2 of 124.12 - * the License, or (at your option) any later version. 124.13 - * 124.14 - * This program is distributed in the hope that it will be useful, 124.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 124.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 124.17 - * GNU General Public License for more details. 124.18 - * 124.19 - * You should have received a copy of the GNU General Public License 124.20 - * along with this program; if not, write to the Free Software 124.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 124.22 - * Boston, MA 02110-1301, USA 124.23 - */ 124.24 - 124.25 -#include <l4/re/c/dataspace.h> 124.26 -#include <l4/re/consts.h> 124.27 -#include <l4/sys/task.h> 124.28 - 124.29 -#include "ipc.h" 124.30 -#include "send_flexpage.h" 124.31 - 124.32 - 124.33 - 124.34 -/* Make an L4 representation of the given flexpage. */ 124.35 - 124.36 -static l4_fpage_t ipc_get_fpage(SendFlexpage *send_flexpage) 124.37 -{ 124.38 - return l4_fpage(send_flexpage->base_addr, send_flexpage->order, 124.39 - (send_flexpage->flags & L4RE_DS_MAP_FLAG_RW) ? L4_FPAGE_RW : L4_FPAGE_RO); 124.40 -} 124.41 - 124.42 -/* Make a representation of a flexpage for the IPC system. */ 124.43 - 124.44 -long ipc_prepare_flexpage(Flexpage *flexpage, offset_t offset, 124.45 - offset_t max_offset, address_t hot_spot, 124.46 - flags_t flags, l4_snd_fpage_t *region) 124.47 -{ 124.48 - SendFlexpage send_flexpage = flexpage->to_send(offset, hot_spot, flags, 124.49 - max_offset); 124.50 - 124.51 - /* NOTE: Consider l4_fpage_invalid() as the fpage here. */ 124.52 - 124.53 - if (!send_flexpage.order) 124.54 - return -L4_ERANGE; 124.55 - 124.56 - region->fpage = ipc_get_fpage(&send_flexpage); 124.57 - region->snd_base = hot_spot; 124.58 - 124.59 - return L4_EOK; 124.60 -} 124.61 - 124.62 -/* Unmap the given flexpage. */ 124.63 - 124.64 -void ipc_unmap_flexpage(Flexpage *flexpage) 124.65 -{ 124.66 - SendFlexpage send_flexpage = flexpage->to_unmap(); 124.67 - 124.68 - l4_task_unmap(L4RE_THIS_TASK_CAP, ipc_get_fpage(&send_flexpage), L4_FP_OTHER_SPACES); 124.69 -} 124.70 - 124.71 -// vim: tabstop=4 expandtab shiftwidth=4
125.1 --- a/mapping/ipc.h Tue Apr 13 00:03:18 2021 +0200 125.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 125.3 @@ -1,36 +0,0 @@ 125.4 -/* 125.5 - * Interprocess communication utilities. 125.6 - * 125.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 125.8 - * 125.9 - * This program is free software; you can redistribute it and/or 125.10 - * modify it under the terms of the GNU General Public License as 125.11 - * published by the Free Software Foundation; either version 2 of 125.12 - * the License, or (at your option) any later version. 125.13 - * 125.14 - * This program is distributed in the hope that it will be useful, 125.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 125.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 125.17 - * GNU General Public License for more details. 125.18 - * 125.19 - * You should have received a copy of the GNU General Public License 125.20 - * along with this program; if not, write to the Free Software 125.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 125.22 - * Boston, MA 02110-1301, USA 125.23 - */ 125.24 - 125.25 -#pragma once 125.26 - 125.27 -#include <l4/sys/ipc.h> 125.28 - 125.29 -#include "flexpage.h" 125.30 - 125.31 - 125.32 - 125.33 -long ipc_prepare_flexpage(Flexpage *flexpage, offset_t offset, 125.34 - offset_t max_offset, address_t hot_spot, 125.35 - flags_t flags, l4_snd_fpage_t *region); 125.36 - 125.37 -void ipc_unmap_flexpage(Flexpage *flexpage); 125.38 - 125.39 -// vim: tabstop=4 expandtab shiftwidth=4
126.1 --- a/mapping/page_mapper.cc Tue Apr 13 00:03:18 2021 +0200 126.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 126.3 @@ -1,196 +0,0 @@ 126.4 -/* 126.5 - * A page mapper providing memory pages to satisfy file accesses. 126.6 - * 126.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 126.8 - * 126.9 - * This program is free software; you can redistribute it and/or 126.10 - * modify it under the terms of the GNU General Public License as 126.11 - * published by the Free Software Foundation; either version 2 of 126.12 - * the License, or (at your option) any later version. 126.13 - * 126.14 - * This program is distributed in the hope that it will be useful, 126.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 126.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 126.17 - * GNU General Public License for more details. 126.18 - * 126.19 - * You should have received a copy of the GNU General Public License 126.20 - * along with this program; if not, write to the Free Software 126.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 126.22 - * Boston, MA 02110-1301, USA 126.23 - */ 126.24 - 126.25 -#include "ipc.h" 126.26 -#include "page_mapper.h" 126.27 - 126.28 - 126.29 - 126.30 -PageMapper::PageMapper(Accessor *accessor, Pages *pages) 126.31 -: _accessor(accessor), _pages(pages), _attached(0) 126.32 -{ 126.33 -} 126.34 - 126.35 -/* Accounting methods. */ 126.36 - 126.37 -/* Attach a pager, opening the accessor if required. */ 126.38 - 126.39 -void PageMapper::attach() 126.40 -{ 126.41 - std::lock_guard<std::mutex> guard(_lock); 126.42 - 126.43 - if (!_attached) 126.44 - _accessor->open(); 126.45 - 126.46 - _attached += 1; 126.47 -} 126.48 - 126.49 -/* Detach a pager, purging active pages and closing the accessor if no more 126.50 - pagers are attached. Return whether any pagers are still attached. */ 126.51 - 126.52 -unsigned int PageMapper::detach() 126.53 -{ 126.54 - std::lock_guard<std::mutex> guard(_lock); 126.55 - 126.56 - if (_attached) 126.57 - { 126.58 - _attached -= 1; 126.59 - 126.60 - if (!_attached) 126.61 - { 126.62 - _map.purge(this, _pages); 126.63 - _accessor->close(); 126.64 - } 126.65 - } 126.66 - 126.67 - return _attached; 126.68 -} 126.69 - 126.70 -/* Interface for the pager. */ 126.71 - 126.72 -/* Return a flexpage providing access to the indicated file 'offset'. 126.73 - 126.74 - The returned flexpage will either be an existing, compatible flexpage or a 126.75 - completely new flexpage. 126.76 - 126.77 - This method locks the mapper to prevent concurrent queries with the same 126.78 - details, with the lock held until the queue operation releases the lock. */ 126.79 - 126.80 -Flexpage *PageMapper::get(offset_t offset, flags_t flags) 126.81 -{ 126.82 - _lock.lock(); 126.83 - 126.84 - Flexpage *f = find(offset); 126.85 - 126.86 - if (f == NULL) 126.87 - f = flexpage(offset); 126.88 - 126.89 - /* Record a new user of the flexpage and upgrade the access flags. */ 126.90 - 126.91 - f->increment(); 126.92 - f->upgrade(flags); 126.93 - return f; 126.94 -} 126.95 - 126.96 -/* Queue the given 'flexpage' in the page collection, making it available for 126.97 - eventual reuse. 126.98 - 126.99 - This method unlocks the mapper. */ 126.100 - 126.101 -void PageMapper::queue(Flexpage *flexpage) 126.102 -{ 126.103 - _pages->queue(this, flexpage); 126.104 - 126.105 - _lock.unlock(); 126.106 -} 126.107 - 126.108 -/* Flush pages in the given range from 'start' with 'size'. */ 126.109 - 126.110 -void PageMapper::flush_all(offset_t start, offset_t size) 126.111 -{ 126.112 - std::lock_guard<std::mutex> guard(_lock); 126.113 - 126.114 - _map.flush_all(start, size, this, _pages); 126.115 -} 126.116 - 126.117 -/* Return the maximum extent of the mapped resource. */ 126.118 - 126.119 -offset_t PageMapper::get_data_size() 126.120 -{ 126.121 - return _accessor->get_size(); 126.122 -} 126.123 - 126.124 -/* Set the maximum extent of the mapped resource. */ 126.125 - 126.126 -void PageMapper::set_data_size(offset_t size) 126.127 -{ 126.128 - _accessor->set_size(size); 126.129 -} 126.130 - 126.131 -/* Internal flexpage retrieval methods. */ 126.132 - 126.133 -/* Find an existing flexpage for 'offset'. Where the accessor has registered a 126.134 - compatible flexpage, an attempt is made to reserve it in the page collection; 126.135 - if this succeeds, the flexpage is returned. Otherwise, NULL is returned. */ 126.136 - 126.137 -Flexpage *PageMapper::find(offset_t offset) 126.138 -{ 126.139 - Flexpage *flexpage = _map.find(offset); 126.140 - 126.141 - /* Between finding and reserving a flexpage, there is a possibility that 126.142 - another accessor might acquire the flexpage, issue it, and even purge 126.143 - it. */ 126.144 - 126.145 - if ((flexpage != NULL) && _pages->reserve(this, flexpage)) 126.146 - return flexpage; 126.147 - else 126.148 - return NULL; 126.149 -} 126.150 - 126.151 -/* Obtain a new flexpage for the file 'offset'. If the page collection is unable 126.152 - to obtain a completely new flexpage, an existing flexpage is requested from 126.153 - the page collection and recycled. 126.154 - 126.155 - The obtained flexpage is filled with content. */ 126.156 - 126.157 -Flexpage *PageMapper::flexpage(offset_t offset) 126.158 -{ 126.159 - Flexpage *flexpage = _pages->flexpage(); 126.160 - 126.161 - /* Obtain an existing flexpage and reuse it. */ 126.162 - 126.163 - if (flexpage == NULL) 126.164 - flexpage = _pages->remove(); 126.165 - 126.166 - flexpage->reset(offset); 126.167 - 126.168 - fill(flexpage); 126.169 - _map.insert(flexpage); 126.170 - return flexpage; 126.171 -} 126.172 - 126.173 -/* Interface for the page collection. */ 126.174 - 126.175 -/* Remove the record of 'flexpage' in this accessor, flushing its content. */ 126.176 - 126.177 -void PageMapper::remove(Flexpage *flexpage) 126.178 -{ 126.179 - _map.remove(this, flexpage); 126.180 -} 126.181 - 126.182 -/* Data transfer methods. */ 126.183 - 126.184 -void PageMapper::fill(Flexpage *flexpage) 126.185 -{ 126.186 - _accessor->fill(flexpage); 126.187 -} 126.188 - 126.189 -void PageMapper::flush(Flexpage *flexpage, bool purge) 126.190 -{ 126.191 - if (flexpage->decrement() || purge) 126.192 - { 126.193 - _accessor->flush(flexpage); 126.194 - ipc_unmap_flexpage(flexpage); 126.195 - flexpage->invalidate(); 126.196 - } 126.197 -} 126.198 - 126.199 -// vim: tabstop=4 expandtab shiftwidth=4
127.1 --- a/mapping/page_mapper.h Tue Apr 13 00:03:18 2021 +0200 127.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 127.3 @@ -1,87 +0,0 @@ 127.4 -/* 127.5 - * A page mapper providing memory pages to satisfy file accesses. 127.6 - * 127.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 127.8 - * 127.9 - * This program is free software; you can redistribute it and/or 127.10 - * modify it under the terms of the GNU General Public License as 127.11 - * published by the Free Software Foundation; either version 2 of 127.12 - * the License, or (at your option) any later version. 127.13 - * 127.14 - * This program is distributed in the hope that it will be useful, 127.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 127.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 127.17 - * GNU General Public License for more details. 127.18 - * 127.19 - * You should have received a copy of the GNU General Public License 127.20 - * along with this program; if not, write to the Free Software 127.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 127.22 - * Boston, MA 02110-1301, USA 127.23 - */ 127.24 - 127.25 -#pragma once 127.26 - 127.27 -#include "access_map.h" 127.28 -#include "accessor.h" 127.29 -#include "page_owner.h" 127.30 - 127.31 -#include <mutex> 127.32 - 127.33 - 127.34 - 127.35 -/* A file mapper, associating flexpages with file regions. */ 127.36 - 127.37 -class PageMapper : public PageOwner 127.38 -{ 127.39 -protected: 127.40 - AccessMap _map; 127.41 - Accessor *_accessor; 127.42 - Pages *_pages; 127.43 - unsigned int _attached; 127.44 - 127.45 - /* Serialisation of accesses. */ 127.46 - 127.47 - std::mutex _lock; 127.48 - 127.49 - /* Internal flexpage retrieval methods. */ 127.50 - 127.51 - Flexpage *find(offset_t offset); 127.52 - 127.53 - Flexpage *flexpage(offset_t offset); 127.54 - 127.55 -public: 127.56 - explicit PageMapper(Accessor *accessor, Pages *pages); 127.57 - 127.58 - /* Accounting methods. */ 127.59 - 127.60 - void attach(); 127.61 - 127.62 - unsigned int detach(); 127.63 - 127.64 - Accessor *accessor() 127.65 - { return _accessor; } 127.66 - 127.67 - /* Interface for the pager. */ 127.68 - 127.69 - Flexpage *get(offset_t offset, flags_t flags); 127.70 - 127.71 - void queue(Flexpage *flexpage); 127.72 - 127.73 - void flush_all(offset_t start, offset_t size); 127.74 - 127.75 - offset_t get_data_size(); 127.76 - 127.77 - void set_data_size(offset_t size); 127.78 - 127.79 - /* Data transfer methods, implementing PageOwner. */ 127.80 - 127.81 - void fill(Flexpage *flexpage); 127.82 - 127.83 - void flush(Flexpage *flexpage, bool purge); 127.84 - 127.85 - /* Interface for the page collection, implementing PageOwner. */ 127.86 - 127.87 - void remove(Flexpage *flexpage); 127.88 -}; 127.89 - 127.90 -// vim: tabstop=4 expandtab shiftwidth=4
128.1 --- a/mapping/page_owner.h Tue Apr 13 00:03:18 2021 +0200 128.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 128.3 @@ -1,53 +0,0 @@ 128.4 -/* 128.5 - * A page owner abstraction, indicating the current user of a memory region. 128.6 - * 128.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 128.8 - * 128.9 - * This program is free software; you can redistribute it and/or 128.10 - * modify it under the terms of the GNU General Public License as 128.11 - * published by the Free Software Foundation; either version 2 of 128.12 - * the License, or (at your option) any later version. 128.13 - * 128.14 - * This program is distributed in the hope that it will be useful, 128.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 128.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 128.17 - * GNU General Public License for more details. 128.18 - * 128.19 - * You should have received a copy of the GNU General Public License 128.20 - * along with this program; if not, write to the Free Software 128.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 128.22 - * Boston, MA 02110-1301, USA 128.23 - */ 128.24 - 128.25 -#pragma once 128.26 - 128.27 -#include "flexpage.h" 128.28 - 128.29 - 128.30 - 128.31 -/* The owner of a flexpage. */ 128.32 - 128.33 -class PageOwner 128.34 -{ 128.35 -public: 128.36 - virtual ~PageOwner() 128.37 - { 128.38 - } 128.39 - 128.40 - virtual void fill(Flexpage *flexpage) 128.41 - { 128.42 - (void) flexpage; 128.43 - } 128.44 - 128.45 - virtual void flush(Flexpage *flexpage, bool purge) 128.46 - { 128.47 - (void) flexpage; (void) purge; 128.48 - } 128.49 - 128.50 - virtual void remove(Flexpage *flexpage) 128.51 - { 128.52 - (void) flexpage; 128.53 - } 128.54 -}; 128.55 - 128.56 -// vim: tabstop=4 expandtab shiftwidth=4
129.1 --- a/mapping/send_flexpage.h Tue Apr 13 00:03:18 2021 +0200 129.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 129.3 @@ -1,44 +0,0 @@ 129.4 -/* 129.5 - * A "send" flexpage abstraction for communicating memory mappings. 129.6 - * 129.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 129.8 - * 129.9 - * This program is free software; you can redistribute it and/or 129.10 - * modify it under the terms of the GNU General Public License as 129.11 - * published by the Free Software Foundation; either version 2 of 129.12 - * the License, or (at your option) any later version. 129.13 - * 129.14 - * This program is distributed in the hope that it will be useful, 129.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 129.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 129.17 - * GNU General Public License for more details. 129.18 - * 129.19 - * You should have received a copy of the GNU General Public License 129.20 - * along with this program; if not, write to the Free Software 129.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 129.22 - * Boston, MA 02110-1301, USA 129.23 - */ 129.24 - 129.25 -#pragma once 129.26 - 129.27 -#include "types.h" 129.28 - 129.29 - 129.30 - 129.31 -/* A "send" flexpage abstraction. */ 129.32 - 129.33 -class SendFlexpage 129.34 -{ 129.35 -public: 129.36 - offset_t base_addr; 129.37 - unsigned int order; 129.38 - flags_t flags; 129.39 - 129.40 - explicit SendFlexpage(offset_t base_addr, unsigned int order, 129.41 - flags_t flags) 129.42 - : base_addr(base_addr), order(order), flags(flags) 129.43 - { 129.44 - } 129.45 -}; 129.46 - 129.47 -// vim: tabstop=4 expandtab shiftwidth=4
130.1 --- a/memory/memory.h Tue Apr 13 00:03:18 2021 +0200 130.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 130.3 @@ -1,44 +0,0 @@ 130.4 -/* 130.5 - * A generic memory pool abstraction. 130.6 - * 130.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 130.8 - * 130.9 - * This program is free software; you can redistribute it and/or 130.10 - * modify it under the terms of the GNU General Public License as 130.11 - * published by the Free Software Foundation; either version 2 of 130.12 - * the License, or (at your option) any later version. 130.13 - * 130.14 - * This program is distributed in the hope that it will be useful, 130.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 130.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 130.17 - * GNU General Public License for more details. 130.18 - * 130.19 - * You should have received a copy of the GNU General Public License 130.20 - * along with this program; if not, write to the Free Software 130.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 130.22 - * Boston, MA 02110-1301, USA 130.23 - */ 130.24 - 130.25 -#pragma once 130.26 - 130.27 -#include "region.h" 130.28 - 130.29 - 130.30 - 130.31 -/* A memory pool interface. */ 130.32 - 130.33 -class Memory 130.34 -{ 130.35 -public: 130.36 - virtual ~Memory() 130.37 - { 130.38 - } 130.39 - 130.40 - virtual Region *region() = 0; 130.41 - 130.42 - virtual offset_t region_size() = 0; 130.43 - 130.44 - virtual void release(Region *region) = 0; 130.45 -}; 130.46 - 130.47 -// vim: tabstop=4 expandtab shiftwidth=4
131.1 --- a/memory/memory_incremental.cc Tue Apr 13 00:03:18 2021 +0200 131.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 131.3 @@ -1,110 +0,0 @@ 131.4 -/* 131.5 - * A memory pool allocating a region at a time from the system. 131.6 - * 131.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 131.8 - * 131.9 - * This program is free software; you can redistribute it and/or 131.10 - * modify it under the terms of the GNU General Public License as 131.11 - * published by the Free Software Foundation; either version 2 of 131.12 - * the License, or (at your option) any later version. 131.13 - * 131.14 - * This program is distributed in the hope that it will be useful, 131.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 131.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 131.17 - * GNU General Public License for more details. 131.18 - * 131.19 - * You should have received a copy of the GNU General Public License 131.20 - * along with this program; if not, write to the Free Software 131.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 131.22 - * Boston, MA 02110-1301, USA 131.23 - */ 131.24 - 131.25 -#include "memory_incremental.h" 131.26 - 131.27 -#include <stdlib.h> 131.28 - 131.29 -/* Initialise the memory pool with an optional 'limit' in pages. */ 131.30 - 131.31 -MemoryIncremental::MemoryIncremental(unsigned int limit, offset_t region_size) 131.32 -: _limit(limit), _region_size(region_size) 131.33 -{ 131.34 - _limited = true; 131.35 -} 131.36 - 131.37 -MemoryIncremental::MemoryIncremental() 131.38 -: _region_size(PAGE_SIZE) 131.39 -{ 131.40 - _limited = false; 131.41 -} 131.42 - 131.43 -/* Allocate a block of the given 'size'. */ 131.44 - 131.45 -Region *MemoryIncremental::allocate(offset_t size) 131.46 -{ 131.47 - /* Attempt to allocate aligned memory. */ 131.48 - 131.49 - void *current; 131.50 - 131.51 - /* Make the size appropriate for the invocation. */ 131.52 - 131.53 - size = round_multiple(size, PAGE_SIZE); 131.54 - 131.55 - if (posix_memalign(¤t, size, size)) 131.56 - return NULL; 131.57 - 131.58 - return new Region((offset_t) current, (offset_t) current + size); 131.59 -} 131.60 - 131.61 -/* Allocate a new region of the given 'size' rounded to the nearest page. */ 131.62 - 131.63 -Region *MemoryIncremental::region(offset_t size) 131.64 -{ 131.65 - std::lock_guard<std::mutex> guard(_lock); 131.66 - 131.67 - offset_t rounded = round(size, PAGE_SIZE); 131.68 - offset_t pages = rounded / PAGE_SIZE; 131.69 - 131.70 - /* Check for sufficient pages. */ 131.71 - 131.72 - if (!_limited || (_limit >= pages)) 131.73 - { 131.74 - /* Attempt to allocate aligned memory. */ 131.75 - 131.76 - Region *region = allocate(rounded); 131.77 - 131.78 - if (region == NULL) 131.79 - return NULL; 131.80 - 131.81 - if (_limited) 131.82 - _limit -= pages; 131.83 - 131.84 - return region; 131.85 - } 131.86 - 131.87 - /* Return no region without sufficient pages. */ 131.88 - 131.89 - else 131.90 - return NULL; 131.91 -} 131.92 - 131.93 -Region *MemoryIncremental::region() 131.94 -{ 131.95 - return region(_region_size); 131.96 -} 131.97 - 131.98 -/* Release the allocated 'region'. */ 131.99 - 131.100 -void MemoryIncremental::release(Region *region) 131.101 -{ 131.102 - std::lock_guard<std::mutex> guard(_lock); 131.103 - 131.104 - offset_t rounded = round(region->size(), PAGE_SIZE); 131.105 - offset_t pages = rounded / PAGE_SIZE; 131.106 - 131.107 - if (_limited) 131.108 - _limit += pages; 131.109 - 131.110 - delete region; 131.111 -} 131.112 - 131.113 -// vim: tabstop=4 expandtab shiftwidth=4
132.1 --- a/memory/memory_incremental.h Tue Apr 13 00:03:18 2021 +0200 132.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 132.3 @@ -1,61 +0,0 @@ 132.4 -/* 132.5 - * A memory pool allocating a region at a time from the system. 132.6 - * 132.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 132.8 - * 132.9 - * This program is free software; you can redistribute it and/or 132.10 - * modify it under the terms of the GNU General Public License as 132.11 - * published by the Free Software Foundation; either version 2 of 132.12 - * the License, or (at your option) any later version. 132.13 - * 132.14 - * This program is distributed in the hope that it will be useful, 132.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 132.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 132.17 - * GNU General Public License for more details. 132.18 - * 132.19 - * You should have received a copy of the GNU General Public License 132.20 - * along with this program; if not, write to the Free Software 132.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 132.22 - * Boston, MA 02110-1301, USA 132.23 - */ 132.24 - 132.25 -#pragma once 132.26 - 132.27 -#include <systypes/base.h> 132.28 - 132.29 -#include <mutex> 132.30 - 132.31 -#include "memory.h" 132.32 -#include "memory_utils.h" 132.33 - 132.34 - 132.35 - 132.36 -/* A memory pool abstraction. */ 132.37 - 132.38 -class MemoryIncremental : public Memory 132.39 -{ 132.40 -protected: 132.41 - std::mutex _lock; 132.42 - 132.43 - unsigned int _limit; 132.44 - offset_t _region_size; 132.45 - bool _limited; 132.46 - 132.47 - Region *allocate(offset_t size); 132.48 - 132.49 -public: 132.50 - explicit MemoryIncremental(unsigned int limit, offset_t region_size=PAGE_SIZE); 132.51 - 132.52 - explicit MemoryIncremental(); 132.53 - 132.54 - virtual Region *region(offset_t size); 132.55 - 132.56 - virtual Region *region(); 132.57 - 132.58 - virtual offset_t region_size() 132.59 - { return _region_size; } 132.60 - 132.61 - virtual void release(Region *region); 132.62 -}; 132.63 - 132.64 -// vim: tabstop=4 expandtab shiftwidth=4
133.1 --- a/memory/memory_preallocated.cc Tue Apr 13 00:03:18 2021 +0200 133.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 133.3 @@ -1,80 +0,0 @@ 133.4 -/* 133.5 - * A memory pool providing regions from a preallocated amount of memory. 133.6 - * 133.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 133.8 - * 133.9 - * This program is free software; you can redistribute it and/or 133.10 - * modify it under the terms of the GNU General Public License as 133.11 - * published by the Free Software Foundation; either version 2 of 133.12 - * the License, or (at your option) any later version. 133.13 - * 133.14 - * This program is distributed in the hope that it will be useful, 133.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 133.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 133.17 - * GNU General Public License for more details. 133.18 - * 133.19 - * You should have received a copy of the GNU General Public License 133.20 - * along with this program; if not, write to the Free Software 133.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 133.22 - * Boston, MA 02110-1301, USA 133.23 - */ 133.24 - 133.25 -#include "memory_preallocated.h" 133.26 - 133.27 - 133.28 - 133.29 -/* Initialise the memory pool with the given amount in bytes. */ 133.30 - 133.31 -MemoryPreallocated::MemoryPreallocated(Memory *memory, offset_t amount) 133.32 -: _memory(memory), _amount(amount) 133.33 -{ 133.34 - // NOTE: Handle allocation failure. 133.35 - 133.36 - offset_t remaining = amount; 133.37 - 133.38 - while (remaining) 133.39 - { 133.40 - _regions.push_back(memory->region()); 133.41 - 133.42 - if (memory->region_size() >= remaining) 133.43 - break; 133.44 - 133.45 - remaining -= memory->region_size(); 133.46 - } 133.47 -} 133.48 - 133.49 -/* Discard all unused regions. */ 133.50 - 133.51 -MemoryPreallocated::~MemoryPreallocated() 133.52 -{ 133.53 - while (!_regions.empty()) 133.54 - { 133.55 - Region *region = _regions.front(); 133.56 - 133.57 - _regions.pop_front(); 133.58 - _memory->release(region); 133.59 - } 133.60 -} 133.61 - 133.62 -/* Obtain an allocated region. */ 133.63 - 133.64 -Region *MemoryPreallocated::region() 133.65 -{ 133.66 - std::lock_guard<std::mutex> guard(_lock); 133.67 - 133.68 - Region *region = _regions.front(); 133.69 - 133.70 - _regions.pop_front(); 133.71 - return region; 133.72 -} 133.73 - 133.74 -/* Release the allocated 'region'. */ 133.75 - 133.76 -void MemoryPreallocated::release(Region *region) 133.77 -{ 133.78 - std::lock_guard<std::mutex> guard(_lock); 133.79 - 133.80 - _regions.push_back(region); 133.81 -} 133.82 - 133.83 -// vim: tabstop=4 expandtab shiftwidth=4
134.1 --- a/memory/memory_preallocated.h Tue Apr 13 00:03:18 2021 +0200 134.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 134.3 @@ -1,59 +0,0 @@ 134.4 -/* 134.5 - * A memory pool providing regions from a preallocated amount of memory. 134.6 - * 134.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 134.8 - * 134.9 - * This program is free software; you can redistribute it and/or 134.10 - * modify it under the terms of the GNU General Public License as 134.11 - * published by the Free Software Foundation; either version 2 of 134.12 - * the License, or (at your option) any later version. 134.13 - * 134.14 - * This program is distributed in the hope that it will be useful, 134.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 134.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 134.17 - * GNU General Public License for more details. 134.18 - * 134.19 - * You should have received a copy of the GNU General Public License 134.20 - * along with this program; if not, write to the Free Software 134.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 134.22 - * Boston, MA 02110-1301, USA 134.23 - */ 134.24 - 134.25 -#pragma once 134.26 - 134.27 -#include <systypes/base.h> 134.28 - 134.29 -#include <list> 134.30 -#include <mutex> 134.31 - 134.32 -#include "memory.h" 134.33 - 134.34 - 134.35 - 134.36 -/* A memory pool abstraction. */ 134.37 - 134.38 -class MemoryPreallocated : public Memory 134.39 -{ 134.40 -protected: 134.41 - std::mutex _lock; 134.42 - std::list<Region *> _regions; 134.43 - 134.44 - Memory *_memory; 134.45 - offset_t _amount; 134.46 - 134.47 -public: 134.48 - explicit MemoryPreallocated(Memory *memory, offset_t amount); 134.49 - 134.50 - explicit MemoryPreallocated(); 134.51 - 134.52 - virtual ~MemoryPreallocated(); 134.53 - 134.54 - virtual Region *region(); 134.55 - 134.56 - virtual offset_t region_size() 134.57 - { return _memory->region_size(); } 134.58 - 134.59 - virtual void release(Region *region); 134.60 -}; 134.61 - 134.62 -// vim: tabstop=4 expandtab shiftwidth=4
135.1 --- a/memory/memory_utils.cc Tue Apr 13 00:03:18 2021 +0200 135.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 135.3 @@ -1,132 +0,0 @@ 135.4 -/* 135.5 - * Memory quantity calculation utilities. 135.6 - * 135.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 135.8 - * 135.9 - * This program is free software; you can redistribute it and/or 135.10 - * modify it under the terms of the GNU General Public License as 135.11 - * published by the Free Software Foundation; either version 2 of 135.12 - * the License, or (at your option) any later version. 135.13 - * 135.14 - * This program is distributed in the hope that it will be useful, 135.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 135.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 135.17 - * GNU General Public License for more details. 135.18 - * 135.19 - * You should have received a copy of the GNU General Public License 135.20 - * along with this program; if not, write to the Free Software 135.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 135.22 - * Boston, MA 02110-1301, USA 135.23 - */ 135.24 - 135.25 -#include "memory_utils.h" 135.26 - 135.27 - 135.28 - 135.29 -/* Return page 'n' for the configured page size. */ 135.30 - 135.31 -offset_t page(unsigned int n) 135.32 -{ 135.33 - return PAGE_SIZE * n; 135.34 -} 135.35 - 135.36 -/* Return the order of 'size', where 2 ** order yields the size. */ 135.37 - 135.38 -unsigned int page_order(offset_t size) 135.39 -{ 135.40 - /* Count zeros from the left, stopping at the first set bit, using the width 135.41 - of the size value (in bits, starting with the width in bytes) to 135.42 - calculate the position of this bit and thus the order of the value. */ 135.43 - 135.44 - return sizeof(unsigned long) * 8 - 1 - __builtin_clzl(size); 135.45 -} 135.46 - 135.47 -/* Return 'value' rounded up to the nearest 'increment'. */ 135.48 - 135.49 -offset_t round(offset_t value, offset_t increment) 135.50 -{ 135.51 - return trunc(value + increment - 1, increment); 135.52 -} 135.53 - 135.54 -/* Return 'value' rounded up to the nearest multiple of 'increment'. */ 135.55 - 135.56 -offset_t round_multiple(offset_t value, offset_t increment) 135.57 -{ 135.58 - offset_t last = increment; 135.59 - 135.60 - while (1) 135.61 - { 135.62 - if (value < increment) 135.63 - return round(value, last); 135.64 - 135.65 - last = increment; 135.66 - increment *= 2; 135.67 - } 135.68 -} 135.69 - 135.70 -/* Return 'value' rounded down (or truncated) to the nearest 'increment'. */ 135.71 - 135.72 -offset_t trunc(offset_t value, offset_t increment) 135.73 -{ 135.74 - return (value / increment) * increment; 135.75 -} 135.76 - 135.77 -/* Return 'value' rounded down (or truncated) to the nearest multiple of 135.78 - 'increment'. */ 135.79 - 135.80 -offset_t trunc_multiple(offset_t value, offset_t increment) 135.81 -{ 135.82 - offset_t last = increment; 135.83 - 135.84 - while (1) 135.85 - { 135.86 - if (value < increment) 135.87 - return trunc(value, last); 135.88 - 135.89 - last = increment; 135.90 - increment *= 2; 135.91 - } 135.92 -} 135.93 - 135.94 -/* Find the maximum size aligned region within the region from 'start' to (but 135.95 - not including) 'end', with the given initial 'increment'. */ 135.96 - 135.97 -offset_t max_multiple(offset_t start, offset_t end, offset_t increment) 135.98 -{ 135.99 - /* The largest possible aligned region is derived from the region size. */ 135.100 - 135.101 - offset_t size = trunc_multiple(end - start, increment); 135.102 - 135.103 - /* Apply the alignment to the start. */ 135.104 - 135.105 - offset_t aligned = round(start, size); 135.106 - 135.107 - /* If the region is aligned, return the size. */ 135.108 - 135.109 - if (aligned == start) 135.110 - return size; 135.111 - 135.112 - /* If the region is not aligned to the current size, recalculate the aligned 135.113 - size. */ 135.114 - 135.115 - offset_t aligned_size; 135.116 - 135.117 - do 135.118 - { 135.119 - aligned_size = trunc_multiple(end - aligned, increment); 135.120 - size /= 2; 135.121 - 135.122 - /* Determine whether a smaller alignment could yield a larger aligned 135.123 - size. */ 135.124 - 135.125 - if (aligned_size >= size) 135.126 - return aligned_size; 135.127 - 135.128 - aligned = round(start, size); 135.129 - } 135.130 - while (aligned > start); 135.131 - 135.132 - return aligned_size; 135.133 -} 135.134 - 135.135 -// vim: tabstop=4 expandtab shiftwidth=4
136.1 --- a/memory/memory_utils.h Tue Apr 13 00:03:18 2021 +0200 136.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 136.3 @@ -1,46 +0,0 @@ 136.4 -/* 136.5 - * Memory quantity calculation utilities. 136.6 - * 136.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 136.8 - * 136.9 - * This program is free software; you can redistribute it and/or 136.10 - * modify it under the terms of the GNU General Public License as 136.11 - * published by the Free Software Foundation; either version 2 of 136.12 - * the License, or (at your option) any later version. 136.13 - * 136.14 - * This program is distributed in the hope that it will be useful, 136.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 136.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 136.17 - * GNU General Public License for more details. 136.18 - * 136.19 - * You should have received a copy of the GNU General Public License 136.20 - * along with this program; if not, write to the Free Software 136.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 136.22 - * Boston, MA 02110-1301, USA 136.23 - */ 136.24 - 136.25 -#pragma once 136.26 - 136.27 -#include <systypes/base.h> 136.28 - 136.29 -#define PAGE_SIZE 4096 136.30 - 136.31 - 136.32 - 136.33 -/* Address arithmetic. */ 136.34 - 136.35 -offset_t page(unsigned int n); 136.36 - 136.37 -unsigned int page_order(offset_t size); 136.38 - 136.39 -offset_t round(offset_t value, offset_t increment); 136.40 - 136.41 -offset_t round_multiple(offset_t value, offset_t increment); 136.42 - 136.43 -offset_t trunc(offset_t value, offset_t increment); 136.44 - 136.45 -offset_t trunc_multiple(offset_t value, offset_t increment); 136.46 - 136.47 -offset_t max_multiple(offset_t start, offset_t end, offset_t increment); 136.48 - 136.49 -// vim: tabstop=4 expandtab shiftwidth=4
137.1 --- a/memory/region.cc Tue Apr 13 00:03:18 2021 +0200 137.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 137.3 @@ -1,104 +0,0 @@ 137.4 -/* 137.5 - * Memory region abstractions. 137.6 - * 137.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 137.8 - * 137.9 - * This program is free software; you can redistribute it and/or 137.10 - * modify it under the terms of the GNU General Public License as 137.11 - * published by the Free Software Foundation; either version 2 of 137.12 - * the License, or (at your option) any later version. 137.13 - * 137.14 - * This program is distributed in the hope that it will be useful, 137.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 137.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 137.17 - * GNU General Public License for more details. 137.18 - * 137.19 - * You should have received a copy of the GNU General Public License 137.20 - * along with this program; if not, write to the Free Software 137.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 137.22 - * Boston, MA 02110-1301, USA 137.23 - */ 137.24 - 137.25 -#include <string.h> 137.26 -#include <stdlib.h> 137.27 - 137.28 -#include "region.h" 137.29 - 137.30 - 137.31 - 137.32 -/* Initialise region state, indicating the size, file and position. */ 137.33 - 137.34 -RegionState::RegionState(unsigned long size, fileid_t fileid, offset_t filepos) 137.35 -: size(size), fileid(fileid), filepos(filepos) 137.36 -{ 137.37 -} 137.38 - 137.39 -void RegionState::fill(fileid_t fileid, offset_t filepos) 137.40 -{ 137.41 - this->fileid = fileid; 137.42 - this->filepos = filepos; 137.43 -} 137.44 - 137.45 - 137.46 - 137.47 -/* Initialise a region having the given 'start' and 'end' addresses, with the 137.48 - 'end' being one location beyond the last address in the region. */ 137.49 - 137.50 -Region::Region(offset_t start, offset_t end) 137.51 -: start(start), end(end), state(end - start) 137.52 -{ 137.53 - /* Content state. */ 137.54 - 137.55 - memset((void *) start, 0, end - start); 137.56 -} 137.57 - 137.58 -Region::~Region() 137.59 -{ 137.60 - free((void *) start); 137.61 -} 137.62 - 137.63 -offset_t Region::size() 137.64 -{ 137.65 - return end - start; 137.66 -} 137.67 - 137.68 -/* Debugging methods. */ 137.69 - 137.70 -int Region::compare(Region *other) 137.71 -{ 137.72 - if (start < other->start) 137.73 - return -1; 137.74 - else if (start > other->start) 137.75 - return 1; 137.76 - else 137.77 - return 0; 137.78 -} 137.79 - 137.80 -void Region::fill(fileid_t fileid, offset_t filepos) 137.81 -{ 137.82 - state.fill(fileid, filepos); 137.83 -} 137.84 - 137.85 -void Region::flush() 137.86 -{ 137.87 -} 137.88 - 137.89 -/* Simulation methods. */ 137.90 - 137.91 -char *Region::read(offset_t offset) 137.92 -{ 137.93 - if (offset < size()) 137.94 - return (char *) start + offset; 137.95 - else 137.96 - return NULL; 137.97 -} 137.98 - 137.99 -void Region::write(const char *data, offset_t offset) 137.100 -{ 137.101 - size_t length = strlen(data); 137.102 - 137.103 - if (offset + length < size()) 137.104 - memcpy((void *) (start + offset), data, length + 1); 137.105 -} 137.106 - 137.107 -// vim: tabstop=4 expandtab shiftwidth=4
138.1 --- a/memory/region.h Tue Apr 13 00:03:18 2021 +0200 138.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 138.3 @@ -1,80 +0,0 @@ 138.4 -/* 138.5 - * Memory region abstractions. 138.6 - * 138.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 138.8 - * 138.9 - * This program is free software; you can redistribute it and/or 138.10 - * modify it under the terms of the GNU General Public License as 138.11 - * published by the Free Software Foundation; either version 2 of 138.12 - * the License, or (at your option) any later version. 138.13 - * 138.14 - * This program is distributed in the hope that it will be useful, 138.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 138.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 138.17 - * GNU General Public License for more details. 138.18 - * 138.19 - * You should have received a copy of the GNU General Public License 138.20 - * along with this program; if not, write to the Free Software 138.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 138.22 - * Boston, MA 02110-1301, USA 138.23 - */ 138.24 - 138.25 -#pragma once 138.26 - 138.27 -#include <systypes/base.h> 138.28 - 138.29 -#include "types.h" 138.30 - 138.31 - 138.32 - 138.33 -/* Region-related state information. */ 138.34 - 138.35 -class RegionState 138.36 -{ 138.37 -public: 138.38 - unsigned long size; 138.39 - fileid_t fileid; 138.40 - offset_t filepos; 138.41 - 138.42 - explicit RegionState(unsigned long size=0, fileid_t fileid=0, offset_t filepos=0); 138.43 - 138.44 - void fill(fileid_t fileid, offset_t filepos); 138.45 - 138.46 - bool valid() { return size != 0; } 138.47 -}; 138.48 - 138.49 - 138.50 - 138.51 -/* A memory region abstraction. */ 138.52 - 138.53 -class Region 138.54 -{ 138.55 -public: 138.56 - offset_t start, end; 138.57 - 138.58 - /* Debugging information. */ 138.59 - 138.60 - RegionState state; 138.61 - 138.62 - /* Methods. */ 138.63 - 138.64 - explicit Region(offset_t start, offset_t end); 138.65 - 138.66 - virtual ~Region(); 138.67 - 138.68 - offset_t size(); 138.69 - 138.70 - int compare(Region *other); 138.71 - 138.72 - void fill(fileid_t fileid, offset_t filepos); 138.73 - 138.74 - void flush(); 138.75 - 138.76 - /* Simulation methods. */ 138.77 - 138.78 - char *read(offset_t offset=0); 138.79 - 138.80 - void write(const char *data, offset_t offset=0); 138.81 -}; 138.82 - 138.83 -// vim: tabstop=4 expandtab shiftwidth=4
139.1 --- a/pages/page_queue.cc Tue Apr 13 00:03:18 2021 +0200 139.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 139.3 @@ -1,60 +0,0 @@ 139.4 -/* 139.5 - * A page queue abstraction. 139.6 - * 139.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 139.8 - * 139.9 - * This program is free software; you can redistribute it and/or 139.10 - * modify it under the terms of the GNU General Public License as 139.11 - * published by the Free Software Foundation; either version 2 of 139.12 - * the License, or (at your option) any later version. 139.13 - * 139.14 - * This program is distributed in the hope that it will be useful, 139.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 139.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 139.17 - * GNU General Public License for more details. 139.18 - * 139.19 - * You should have received a copy of the GNU General Public License 139.20 - * along with this program; if not, write to the Free Software 139.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 139.22 - * Boston, MA 02110-1301, USA 139.23 - */ 139.24 - 139.25 -#include "page_queue.h" 139.26 - 139.27 - 139.28 - 139.29 -void PageQueue::discard(Queue &queue, Memory *memory) 139.30 -{ 139.31 - while (!queue.empty()) 139.32 - { 139.33 - Flexpage *flexpage = queue.front().flexpage; 139.34 - 139.35 - queue.pop_front(); 139.36 - memory->release(flexpage->region); 139.37 - delete flexpage; 139.38 - } 139.39 -} 139.40 - 139.41 -bool PageQueue::remove(Queue &queue, Positions &positions, PageOwner *owner, Flexpage *flexpage) 139.42 -{ 139.43 - Positions::iterator position = positions.find(flexpage); 139.44 - 139.45 - if (position == positions.end()) 139.46 - return false; 139.47 - 139.48 - /* The found owner may be different from the requesting owner or even NULL 139.49 - if another owner has acquired and then purged its pages. Such a purged 139.50 - flexpage is not immediately usable, however. */ 139.51 - 139.52 - Queue::iterator entry = position->second; 139.53 - 139.54 - if ((entry->owner == NULL) || (entry->owner != owner)) 139.55 - return false; 139.56 - 139.57 - queue.erase(entry); 139.58 - positions.erase(position); 139.59 - 139.60 - return true; 139.61 -} 139.62 - 139.63 -// vim: tabstop=4 expandtab shiftwidth=4
140.1 --- a/pages/page_queue.h Tue Apr 13 00:03:18 2021 +0200 140.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 140.3 @@ -1,71 +0,0 @@ 140.4 -/* 140.5 - * A page queue abstraction. 140.6 - * 140.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 140.8 - * 140.9 - * This program is free software; you can redistribute it and/or 140.10 - * modify it under the terms of the GNU General Public License as 140.11 - * published by the Free Software Foundation; either version 2 of 140.12 - * the License, or (at your option) any later version. 140.13 - * 140.14 - * This program is distributed in the hope that it will be useful, 140.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 140.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 140.17 - * GNU General Public License for more details. 140.18 - * 140.19 - * You should have received a copy of the GNU General Public License 140.20 - * along with this program; if not, write to the Free Software 140.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 140.22 - * Boston, MA 02110-1301, USA 140.23 - */ 140.24 - 140.25 -#pragma once 140.26 - 140.27 -#include <list> 140.28 -#include <map> 140.29 - 140.30 -#include "flexpage.h" 140.31 -#include "memory.h" 140.32 -#include "page_owner.h" 140.33 - 140.34 - 140.35 - 140.36 -/* Collection types. */ 140.37 - 140.38 -typedef struct { Flexpage *flexpage; PageOwner *owner; } QueueEntry; 140.39 -typedef std::list<QueueEntry> Queue; 140.40 - 140.41 -typedef std::pair<Flexpage *, Queue::iterator> Position; 140.42 -typedef std::map<Flexpage *, Queue::iterator> Positions; 140.43 - 140.44 - 140.45 - 140.46 -/* A queue of managed pages. */ 140.47 - 140.48 -class PageQueue 140.49 -{ 140.50 -protected: 140.51 - 140.52 - /* Helper methods. */ 140.53 - 140.54 - virtual void discard(Queue &queue, Memory *memory); 140.55 - 140.56 - virtual bool remove(Queue &queue, Positions &positions, PageOwner *owner, Flexpage *flexpage); 140.57 - 140.58 -public: 140.59 - virtual ~PageQueue() 140.60 - { 140.61 - } 140.62 - 140.63 - virtual void close(Memory *memory) = 0; 140.64 - 140.65 - virtual void pop(PageOwner **owner, Flexpage **flexpage) = 0; 140.66 - 140.67 - virtual void push(PageOwner *owner, Flexpage *flexpage) = 0; 140.68 - 140.69 - virtual void push_front(PageOwner *owner, Flexpage *flexpage) = 0; 140.70 - 140.71 - virtual bool remove(PageOwner *owner, Flexpage *flexpage) = 0; 140.72 -}; 140.73 - 140.74 -// vim: tabstop=4 expandtab shiftwidth=4
141.1 --- a/pages/page_queue_partitioned.cc Tue Apr 13 00:03:18 2021 +0200 141.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 141.3 @@ -1,133 +0,0 @@ 141.4 -/* 141.5 - * A page queue retaining two internal collections of memory pages. 141.6 - * 141.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 141.8 - * 141.9 - * This program is free software; you can redistribute it and/or 141.10 - * modify it under the terms of the GNU General Public License as 141.11 - * published by the Free Software Foundation; either version 2 of 141.12 - * the License, or (at your option) any later version. 141.13 - * 141.14 - * This program is distributed in the hope that it will be useful, 141.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 141.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 141.17 - * GNU General Public License for more details. 141.18 - * 141.19 - * You should have received a copy of the GNU General Public License 141.20 - * along with this program; if not, write to the Free Software 141.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 141.22 - * Boston, MA 02110-1301, USA 141.23 - */ 141.24 - 141.25 -#include "page_queue_partitioned.h" 141.26 - 141.27 - 141.28 - 141.29 -/* Discard all queued flexpages. */ 141.30 - 141.31 -void PageQueuePartitioned::close(Memory *memory) 141.32 -{ 141.33 - discard(_available, memory); 141.34 - discard(_issued, memory); 141.35 -} 141.36 - 141.37 -/* Keep waiting for a potential queue non-empty condition. 141.38 - Then, attempt to pop an entry from the queue. */ 141.39 - 141.40 -void PageQueuePartitioned::pop(PageOwner **owner, Flexpage **flexpage) 141.41 -{ 141.42 - std::unique_lock<std::mutex> guard(_lock); 141.43 - QueueEntry entry; 141.44 - 141.45 - while (1) 141.46 - { 141.47 - if (_pop(&entry)) 141.48 - { 141.49 - *owner = entry.owner; 141.50 - *flexpage = entry.flexpage; 141.51 - return; 141.52 - } 141.53 - else 141.54 - _counter.wait(guard); 141.55 - } 141.56 -} 141.57 - 141.58 -/* Check the available pages queue for entries, returning false if no entries 141.59 - are available, returning true and providing the details if an entry can be 141.60 - removed from the front of the queue. */ 141.61 - 141.62 -bool PageQueuePartitioned::_pop(QueueEntry *entry) 141.63 -{ 141.64 - if (_available.empty()) 141.65 - return false; 141.66 - 141.67 - *entry = _available.front(); 141.68 - _available.pop_front(); 141.69 - 141.70 - return true; 141.71 -} 141.72 - 141.73 -/* Push an entry for the given owner and flexpage to the appropriate queue. */ 141.74 - 141.75 -void PageQueuePartitioned::push(PageOwner *owner, Flexpage *flexpage) 141.76 -{ 141.77 - std::lock_guard<std::mutex> guard(_lock); 141.78 - 141.79 - /* Record the entry and a position reference for the flexpage. */ 141.80 - 141.81 - Queue *queue; 141.82 - Positions *positions = NULL; 141.83 - 141.84 - if (owner == NULL) 141.85 - queue = &_available; 141.86 - else 141.87 - { 141.88 - queue = &_issued; 141.89 - positions = &_positions; 141.90 - } 141.91 - 141.92 - queue->push_back((QueueEntry) {flexpage, owner}); 141.93 - 141.94 - if (positions != NULL) 141.95 - { 141.96 - Queue::iterator last = queue->end(); 141.97 - last--; 141.98 - positions->insert(Position(flexpage, last)); 141.99 - } 141.100 - 141.101 - _counter.notify_one(); 141.102 -} 141.103 - 141.104 -/* Push an entry to the front of the appropriate queue. */ 141.105 - 141.106 -void PageQueuePartitioned::push_front(PageOwner *owner, Flexpage *flexpage) 141.107 -{ 141.108 - std::lock_guard<std::mutex> guard(_lock); 141.109 - 141.110 - Queue *queue; 141.111 - Positions *positions = NULL; 141.112 - 141.113 - if (owner == NULL) 141.114 - queue = &_available; 141.115 - else 141.116 - { 141.117 - queue = &_issued; 141.118 - positions = &_positions; 141.119 - } 141.120 - 141.121 - queue->push_back((QueueEntry) {flexpage, owner}); 141.122 - 141.123 - if (positions != NULL) 141.124 - positions->insert(Position(flexpage, queue->begin())); 141.125 - 141.126 - _counter.notify_one(); 141.127 -} 141.128 - 141.129 -/* Remove an entry for the given owner and flexpage from the queue. */ 141.130 - 141.131 -bool PageQueuePartitioned::remove(PageOwner *owner, Flexpage *flexpage) 141.132 -{ 141.133 - return PageQueue::remove(_issued, _positions, owner, flexpage); 141.134 -} 141.135 - 141.136 -// vim: tabstop=4 expandtab shiftwidth=4
142.1 --- a/pages/page_queue_partitioned.h Tue Apr 13 00:03:18 2021 +0200 142.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 142.3 @@ -1,56 +0,0 @@ 142.4 -/* 142.5 - * A page queue retaining two internal collections of memory pages. 142.6 - * 142.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 142.8 - * 142.9 - * This program is free software; you can redistribute it and/or 142.10 - * modify it under the terms of the GNU General Public License as 142.11 - * published by the Free Software Foundation; either version 2 of 142.12 - * the License, or (at your option) any later version. 142.13 - * 142.14 - * This program is distributed in the hope that it will be useful, 142.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 142.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 142.17 - * GNU General Public License for more details. 142.18 - * 142.19 - * You should have received a copy of the GNU General Public License 142.20 - * along with this program; if not, write to the Free Software 142.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 142.22 - * Boston, MA 02110-1301, USA 142.23 - */ 142.24 - 142.25 -#pragma once 142.26 - 142.27 -#include <condition_variable> 142.28 -#include <mutex> 142.29 - 142.30 -#include "page_queue.h" 142.31 - 142.32 - 142.33 - 142.34 -/* Queues of issued and available pages. */ 142.35 - 142.36 -class PageQueuePartitioned : public PageQueue 142.37 -{ 142.38 -protected: 142.39 - Queue _issued, _available; 142.40 - Positions _positions; 142.41 - 142.42 - std::mutex _lock; 142.43 - std::condition_variable _counter; 142.44 - 142.45 - virtual bool _pop(QueueEntry *entry); 142.46 - 142.47 -public: 142.48 - virtual void close(Memory *memory); 142.49 - 142.50 - virtual void pop(PageOwner **owner, Flexpage **flexpage); 142.51 - 142.52 - virtual void push(PageOwner *owner, Flexpage *flexpage); 142.53 - 142.54 - virtual void push_front(PageOwner *owner, Flexpage *flexpage); 142.55 - 142.56 - virtual bool remove(PageOwner *owner, Flexpage *flexpage); 142.57 -}; 142.58 - 142.59 -// vim: tabstop=4 expandtab shiftwidth=4
143.1 --- a/pages/page_queue_shared.cc Tue Apr 13 00:03:18 2021 +0200 143.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 143.3 @@ -1,112 +0,0 @@ 143.4 -/* 143.5 - * A page queue whose users take turns to access pages. 143.6 - * 143.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 143.8 - * 143.9 - * This program is free software; you can redistribute it and/or 143.10 - * modify it under the terms of the GNU General Public License as 143.11 - * published by the Free Software Foundation; either version 2 of 143.12 - * the License, or (at your option) any later version. 143.13 - * 143.14 - * This program is distributed in the hope that it will be useful, 143.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 143.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 143.17 - * GNU General Public License for more details. 143.18 - * 143.19 - * You should have received a copy of the GNU General Public License 143.20 - * along with this program; if not, write to the Free Software 143.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 143.22 - * Boston, MA 02110-1301, USA 143.23 - */ 143.24 - 143.25 -#include "page_queue_shared.h" 143.26 - 143.27 - 143.28 - 143.29 -/* Discard all queued flexpages. */ 143.30 - 143.31 -void PageQueueShared::close(Memory *memory) 143.32 -{ 143.33 - discard(_queue, memory); 143.34 -} 143.35 - 143.36 -/* Keep waiting for a potential queue non-empty condition. 143.37 - Then, attempt to pop an entry from the queue. */ 143.38 - 143.39 -void PageQueueShared::pop(PageOwner **owner, Flexpage **flexpage) 143.40 -{ 143.41 - std::unique_lock<std::mutex> guard(_lock); 143.42 - QueueEntry entry; 143.43 - 143.44 - while (1) 143.45 - { 143.46 - if (_pop(&entry)) 143.47 - { 143.48 - *owner = entry.owner; 143.49 - *flexpage = entry.flexpage; 143.50 - return; 143.51 - } 143.52 - else 143.53 - _counter.wait(guard); 143.54 - } 143.55 -} 143.56 - 143.57 -/* Check the queue for entries, returning false if no entries are available, 143.58 - returning true and providing the details if an entry can be removed from the 143.59 - front of the queue. */ 143.60 - 143.61 -bool PageQueueShared::_pop(QueueEntry *entry) 143.62 -{ 143.63 - if (_queue.empty()) 143.64 - return false; 143.65 - 143.66 - *entry = _queue.front(); 143.67 - _queue.pop_front(); 143.68 - 143.69 - /* Remove any position reference for the flexpage. */ 143.70 - 143.71 - Positions::iterator position = _positions.find(entry->flexpage); 143.72 - 143.73 - if (position != _positions.end()) 143.74 - _positions.erase(position); 143.75 - 143.76 - return true; 143.77 -} 143.78 - 143.79 -/* Push an entry for the given owner and flexpage to the queue. */ 143.80 - 143.81 -void PageQueueShared::push(PageOwner *owner, Flexpage *flexpage) 143.82 -{ 143.83 - std::lock_guard<std::mutex> guard(_lock); 143.84 - 143.85 - /* Record the entry and a position reference for the flexpage. */ 143.86 - 143.87 - _queue.push_back((QueueEntry) {flexpage, owner}); 143.88 - 143.89 - Queue::iterator last = _queue.end(); 143.90 - last--; 143.91 - _positions.insert(Position(flexpage, last)); 143.92 - 143.93 - _counter.notify_one(); 143.94 -} 143.95 - 143.96 -/* Push an entry to the front of the queue. */ 143.97 - 143.98 -void PageQueueShared::push_front(PageOwner *owner, Flexpage *flexpage) 143.99 -{ 143.100 - std::lock_guard<std::mutex> guard(_lock); 143.101 - 143.102 - _queue.push_back((QueueEntry) {flexpage, owner}); 143.103 - _positions.insert(Position(flexpage, _queue.begin())); 143.104 - 143.105 - _counter.notify_one(); 143.106 -} 143.107 - 143.108 -/* Remove an entry for the given owner and flexpage from the queue. */ 143.109 - 143.110 -bool PageQueueShared::remove(PageOwner *owner, Flexpage *flexpage) 143.111 -{ 143.112 - return PageQueue::remove(_queue, _positions, owner, flexpage); 143.113 -} 143.114 - 143.115 -// vim: tabstop=4 expandtab shiftwidth=4
144.1 --- a/pages/page_queue_shared.h Tue Apr 13 00:03:18 2021 +0200 144.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 144.3 @@ -1,56 +0,0 @@ 144.4 -/* 144.5 - * A page queue whose users take turns to access pages. 144.6 - * 144.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 144.8 - * 144.9 - * This program is free software; you can redistribute it and/or 144.10 - * modify it under the terms of the GNU General Public License as 144.11 - * published by the Free Software Foundation; either version 2 of 144.12 - * the License, or (at your option) any later version. 144.13 - * 144.14 - * This program is distributed in the hope that it will be useful, 144.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 144.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 144.17 - * GNU General Public License for more details. 144.18 - * 144.19 - * You should have received a copy of the GNU General Public License 144.20 - * along with this program; if not, write to the Free Software 144.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 144.22 - * Boston, MA 02110-1301, USA 144.23 - */ 144.24 - 144.25 -#pragma once 144.26 - 144.27 -#include <condition_variable> 144.28 -#include <mutex> 144.29 - 144.30 -#include "page_queue.h" 144.31 - 144.32 - 144.33 - 144.34 -/* A queue of issued pages. */ 144.35 - 144.36 -class PageQueueShared : public PageQueue 144.37 -{ 144.38 -protected: 144.39 - Queue _queue; 144.40 - Positions _positions; 144.41 - 144.42 - std::mutex _lock; 144.43 - std::condition_variable _counter; 144.44 - 144.45 - virtual bool _pop(QueueEntry *entry); 144.46 - 144.47 -public: 144.48 - virtual void close(Memory *memory); 144.49 - 144.50 - virtual void pop(PageOwner **owner, Flexpage **flexpage); 144.51 - 144.52 - virtual void push(PageOwner *owner, Flexpage *flexpage); 144.53 - 144.54 - virtual void push_front(PageOwner *owner, Flexpage *flexpage); 144.55 - 144.56 - virtual bool remove(PageOwner *owner, Flexpage *flexpage); 144.57 -}; 144.58 - 144.59 -// vim: tabstop=4 expandtab shiftwidth=4
145.1 --- a/pages/pages.cc Tue Apr 13 00:03:18 2021 +0200 145.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 145.3 @@ -1,88 +0,0 @@ 145.4 -/* 145.5 - * A page collection abstraction providing pages from a queue to users. 145.6 - * 145.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 145.8 - * 145.9 - * This program is free software; you can redistribute it and/or 145.10 - * modify it under the terms of the GNU General Public License as 145.11 - * published by the Free Software Foundation; either version 2 of 145.12 - * the License, or (at your option) any later version. 145.13 - * 145.14 - * This program is distributed in the hope that it will be useful, 145.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 145.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 145.17 - * GNU General Public License for more details. 145.18 - * 145.19 - * You should have received a copy of the GNU General Public License 145.20 - * along with this program; if not, write to the Free Software 145.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 145.22 - * Boston, MA 02110-1301, USA 145.23 - */ 145.24 - 145.25 -#include "memory_incremental.h" 145.26 -#include "pages.h" 145.27 - 145.28 - 145.29 - 145.30 -Pages::Pages(Memory *memory, PageQueue *queue) 145.31 -: _memory(memory), _queue(queue) 145.32 -{ 145.33 -} 145.34 - 145.35 -Pages::~Pages() 145.36 -{ 145.37 - _queue->close(_memory); 145.38 -} 145.39 - 145.40 -/* Remove the first flexpage in the queue. If its owner exists, remove it from 145.41 - the owner (retiring the content). Return the flexpage for reuse. */ 145.42 - 145.43 -Flexpage *Pages::remove() 145.44 -{ 145.45 - PageOwner *owner; 145.46 - Flexpage *flexpage; 145.47 - 145.48 - _queue->pop(&owner, &flexpage); 145.49 - 145.50 - if (owner != NULL) 145.51 - owner->remove(flexpage); 145.52 - 145.53 - return flexpage; 145.54 -} 145.55 - 145.56 -/* Reserve 'flexpage' by removing it from this collection. */ 145.57 - 145.58 -bool Pages::reserve(PageOwner *owner, Flexpage *flexpage) 145.59 -{ 145.60 - return _queue->remove(owner, flexpage); 145.61 -} 145.62 - 145.63 -/* Obtain a new flexpage. Return the flexpage or None if no new flexpage could 145.64 - be created. */ 145.65 - 145.66 -Flexpage *Pages::flexpage() 145.67 -{ 145.68 - Region *region = _memory->region(); 145.69 - 145.70 - if (region != NULL) 145.71 - return new Flexpage(region); 145.72 - else 145.73 - return NULL; 145.74 -} 145.75 - 145.76 -/* Queue an entry associating the given 'owner' and 'flexpage'. */ 145.77 - 145.78 -void Pages::queue(PageOwner *owner, Flexpage *flexpage) 145.79 -{ 145.80 - _queue->push(owner, flexpage); 145.81 -} 145.82 - 145.83 -/* Push an entry for 'flexpage' without owner association for immediate 145.84 - reuse. */ 145.85 - 145.86 -void Pages::release(Flexpage *flexpage) 145.87 -{ 145.88 - _queue->push_front(NULL, flexpage); 145.89 -} 145.90 - 145.91 -// vim: tabstop=4 expandtab shiftwidth=4
146.1 --- a/pages/pages.h Tue Apr 13 00:03:18 2021 +0200 146.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 146.3 @@ -1,55 +0,0 @@ 146.4 -/* 146.5 - * A page collection abstraction providing pages from a queue to users. 146.6 - * 146.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 146.8 - * 146.9 - * This program is free software; you can redistribute it and/or 146.10 - * modify it under the terms of the GNU General Public License as 146.11 - * published by the Free Software Foundation; either version 2 of 146.12 - * the License, or (at your option) any later version. 146.13 - * 146.14 - * This program is distributed in the hope that it will be useful, 146.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 146.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 146.17 - * GNU General Public License for more details. 146.18 - * 146.19 - * You should have received a copy of the GNU General Public License 146.20 - * along with this program; if not, write to the Free Software 146.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 146.22 - * Boston, MA 02110-1301, USA 146.23 - */ 146.24 - 146.25 -#pragma once 146.26 - 146.27 -#include "flexpage.h" 146.28 -#include "memory.h" 146.29 -#include "page_owner.h" 146.30 -#include "page_queue.h" 146.31 - 146.32 - 146.33 - 146.34 -/* A page collection. */ 146.35 - 146.36 -class Pages 146.37 -{ 146.38 -protected: 146.39 - Memory *_memory; 146.40 - PageQueue *_queue; 146.41 - 146.42 -public: 146.43 - explicit Pages(Memory *memory, PageQueue *queue); 146.44 - 146.45 - virtual ~Pages(); 146.46 - 146.47 - virtual Flexpage *remove(); 146.48 - 146.49 - virtual bool reserve(PageOwner *owner, Flexpage *flexpage); 146.50 - 146.51 - virtual Flexpage *flexpage(); 146.52 - 146.53 - virtual void queue(PageOwner *owner, Flexpage *flexpage); 146.54 - 146.55 - virtual void release(Flexpage *flexpage); 146.56 -}; 146.57 - 146.58 -// vim: tabstop=4 expandtab shiftwidth=4
147.1 --- a/pipes/pipe_accessor.cc Tue Apr 13 00:03:18 2021 +0200 147.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 147.3 @@ -1,64 +0,0 @@ 147.4 -/* 147.5 - * A pipe accessor merely resetting allocated memory for use. 147.6 - * 147.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 147.8 - * 147.9 - * This program is free software; you can redistribute it and/or 147.10 - * modify it under the terms of the GNU General Public License as 147.11 - * published by the Free Software Foundation; either version 2 of 147.12 - * the License, or (at your option) any later version. 147.13 - * 147.14 - * This program is distributed in the hope that it will be useful, 147.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 147.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 147.17 - * GNU General Public License for more details. 147.18 - * 147.19 - * You should have received a copy of the GNU General Public License 147.20 - * along with this program; if not, write to the Free Software 147.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 147.22 - * Boston, MA 02110-1301, USA 147.23 - */ 147.24 - 147.25 -#include "pipe_accessor.h" 147.26 - 147.27 -#include <string.h> 147.28 - 147.29 -PipeAccessor::PipeAccessor() 147.30 -: Accessor(0) 147.31 -{ 147.32 -} 147.33 - 147.34 -/* Perform any closing operation on the file. */ 147.35 - 147.36 -void PipeAccessor::close() 147.37 -{ 147.38 -} 147.39 - 147.40 -/* Perform any opening operation on the file. */ 147.41 - 147.42 -void PipeAccessor::open() 147.43 -{ 147.44 -} 147.45 - 147.46 -/* Data transfer helper methods. */ 147.47 - 147.48 -void PipeAccessor::fill_populated(Flexpage *flexpage) 147.49 -{ 147.50 - offset_t filepos = flexpage->base_offset; 147.51 - offset_t addr = flexpage->base_addr; 147.52 - 147.53 - /* Tag the region with file state. */ 147.54 - 147.55 - flexpage->region->fill(fileid, filepos); 147.56 - 147.57 - /* File the flexpage with zero. */ 147.58 - 147.59 - memset((void *) addr, 0, flexpage->size); 147.60 -} 147.61 - 147.62 -void PipeAccessor::flush_populated(Flexpage *flexpage) 147.63 -{ 147.64 - flexpage->region->flush(); 147.65 -} 147.66 - 147.67 -// vim: tabstop=4 expandtab shiftwidth=4
148.1 --- a/pipes/pipe_accessor.h Tue Apr 13 00:03:18 2021 +0200 148.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 148.3 @@ -1,48 +0,0 @@ 148.4 -/* 148.5 - * A pipe accessor merely resetting allocated memory for use. 148.6 - * 148.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 148.8 - * 148.9 - * This program is free software; you can redistribute it and/or 148.10 - * modify it under the terms of the GNU General Public License as 148.11 - * published by the Free Software Foundation; either version 2 of 148.12 - * the License, or (at your option) any later version. 148.13 - * 148.14 - * This program is distributed in the hope that it will be useful, 148.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 148.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 148.17 - * GNU General Public License for more details. 148.18 - * 148.19 - * You should have received a copy of the GNU General Public License 148.20 - * along with this program; if not, write to the Free Software 148.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 148.22 - * Boston, MA 02110-1301, USA 148.23 - */ 148.24 - 148.25 -#pragma once 148.26 - 148.27 -#include "accessor.h" 148.28 - 148.29 - 148.30 - 148.31 -/* A pipe accessor, providing flexpages for pipe sections. */ 148.32 - 148.33 -class PipeAccessor : public Accessor 148.34 -{ 148.35 -protected: 148.36 - 148.37 - /* Data transfer helper methods. */ 148.38 - 148.39 - virtual void fill_populated(Flexpage *flexpage); 148.40 - 148.41 - virtual void flush_populated(Flexpage *flexpage); 148.42 - 148.43 -public: 148.44 - explicit PipeAccessor(); 148.45 - 148.46 - virtual void close(); 148.47 - 148.48 - virtual void open(); 148.49 -}; 148.50 - 148.51 -// vim: tabstop=4 expandtab shiftwidth=4
149.1 --- a/pipes/pipe_opener_resource.cc Tue Apr 13 00:03:18 2021 +0200 149.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 149.3 @@ -1,84 +0,0 @@ 149.4 -/* 149.5 - * A pipe opener resource. 149.6 - * 149.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 149.8 - * 149.9 - * This program is free software; you can redistribute it and/or 149.10 - * modify it under the terms of the GNU General Public License as 149.11 - * published by the Free Software Foundation; either version 2 of 149.12 - * the License, or (at your option) any later version. 149.13 - * 149.14 - * This program is distributed in the hope that it will be useful, 149.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 149.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 149.17 - * GNU General Public License for more details. 149.18 - * 149.19 - * You should have received a copy of the GNU General Public License 149.20 - * along with this program; if not, write to the Free Software 149.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 149.22 - * Boston, MA 02110-1301, USA 149.23 - */ 149.24 - 149.25 -#include "memory_incremental.h" 149.26 -#include "pipe_opener_resource.h" 149.27 -#include "pipe_opener_server.h" 149.28 -#include "pipe_pager.h" 149.29 -#include "resource_server.h" 149.30 - 149.31 - 149.32 - 149.33 -/* Support for providing access to pipes. */ 149.34 - 149.35 -PipeOpenerResource::PipeOpenerResource(Memory *memory) 149.36 -: _memory(memory) 149.37 -{ 149.38 -} 149.39 - 149.40 -int PipeOpenerResource::expected_items() 149.41 -{ 149.42 - return PipeOpener_expected_items; 149.43 -} 149.44 - 149.45 -ipc_server_handler_type PipeOpenerResource::handler() 149.46 -{ 149.47 - return (ipc_server_handler_type) handle_PipeOpener; 149.48 -} 149.49 - 149.50 - 149.51 - 149.52 -/* Pipe opener interface methods. */ 149.53 - 149.54 -long PipeOpenerResource::pipe(offset_t size, l4_cap_idx_t *reader, l4_cap_idx_t *writer) 149.55 -{ 149.56 - /* Both endpoints will employ a common paging coordinator. */ 149.57 - 149.58 - PipePaging *paging = new PipePaging(_memory, size); 149.59 - 149.60 - /* Each endpoint will have its own pager. */ 149.61 - 149.62 - /* NOTE: Failure to open an endpoint should invalidate both, plus the 149.63 - paging object. Also, any active server thread would need to be 149.64 - cancelled. */ 149.65 - 149.66 - return open_endpoint(paging, false, reader) || open_endpoint(paging, true, writer); 149.67 -} 149.68 - 149.69 -long PipeOpenerResource::open_endpoint(PipePaging *paging, bool writing, l4_cap_idx_t *endpoint) 149.70 -{ 149.71 - PipePager *pager = new PipePager(paging, writing); 149.72 - 149.73 - /* Start the endpoint server in a new thread. 149.74 - If the thread does not start, the resource should be finalised. */ 149.75 - 149.76 - ResourceServer server(pager); 149.77 - long err = server.start_thread(); 149.78 - 149.79 - /* Return the server capability to the caller. */ 149.80 - 149.81 - if (!err) 149.82 - *endpoint = server.config()->server; 149.83 - 149.84 - return err; 149.85 -} 149.86 - 149.87 -// vim: tabstop=4 expandtab shiftwidth=4
150.1 --- a/pipes/pipe_opener_resource.h Tue Apr 13 00:03:18 2021 +0200 150.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 150.3 @@ -1,57 +0,0 @@ 150.4 -/* 150.5 - * A pipe opener resource. 150.6 - * 150.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 150.8 - * 150.9 - * This program is free software; you can redistribute it and/or 150.10 - * modify it under the terms of the GNU General Public License as 150.11 - * published by the Free Software Foundation; either version 2 of 150.12 - * the License, or (at your option) any later version. 150.13 - * 150.14 - * This program is distributed in the hope that it will be useful, 150.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 150.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 150.17 - * GNU General Public License for more details. 150.18 - * 150.19 - * You should have received a copy of the GNU General Public License 150.20 - * along with this program; if not, write to the Free Software 150.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 150.22 - * Boston, MA 02110-1301, USA 150.23 - */ 150.24 - 150.25 -#pragma once 150.26 - 150.27 -#include "memory.h" 150.28 -#include "pipe_opener_interface.h" 150.29 -#include "pipe_paging.h" 150.30 -#include "resource.h" 150.31 - 150.32 - 150.33 - 150.34 -/* Support for providing access to pipes. */ 150.35 - 150.36 -class PipeOpenerResource : public Resource, public PipeOpener 150.37 -{ 150.38 -protected: 150.39 - Memory *_memory; 150.40 - 150.41 - long open_endpoint(PipePaging *paging, bool writing, l4_cap_idx_t *endpoint); 150.42 - 150.43 -public: 150.44 - explicit PipeOpenerResource(Memory *memory); 150.45 - 150.46 - /* Server details. */ 150.47 - 150.48 - int expected_items(); 150.49 - 150.50 - ipc_server_handler_type handler(); 150.51 - 150.52 - void *interface() 150.53 - { return static_cast<PipeOpener *>(this); } 150.54 - 150.55 - /* PipeOpener interface methods. */ 150.56 - 150.57 - long pipe(offset_t size, l4_cap_idx_t *reader, l4_cap_idx_t *writer); 150.58 -}; 150.59 - 150.60 -// vim: tabstop=4 expandtab shiftwidth=4
151.1 --- a/pipes/pipe_pager.cc Tue Apr 13 00:03:18 2021 +0200 151.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 151.3 @@ -1,126 +0,0 @@ 151.4 -/* 151.5 - * A pipe pager providing access to pipe content and navigation support. 151.6 - * 151.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 151.8 - * 151.9 - * This program is free software; you can redistribute it and/or 151.10 - * modify it under the terms of the GNU General Public License as 151.11 - * published by the Free Software Foundation; either version 2 of 151.12 - * the License, or (at your option) any later version. 151.13 - * 151.14 - * This program is distributed in the hope that it will be useful, 151.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 151.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 151.17 - * GNU General Public License for more details. 151.18 - * 151.19 - * You should have received a copy of the GNU General Public License 151.20 - * along with this program; if not, write to the Free Software 151.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 151.22 - * Boston, MA 02110-1301, USA 151.23 - */ 151.24 - 151.25 -#include "pipe_pager.h" 151.26 -#include "pipe_object_server.h" 151.27 - 151.28 - 151.29 - 151.30 -/* Initialise a pager for a pipe with a shared page mapper for moderating 151.31 - access to loaded pages. At first, no mapper will be configured: this must be 151.32 - done by requesting a region. */ 151.33 - 151.34 -PipePager::PipePager(PipePaging *paging, bool writing) 151.35 -: Pager(NULL, writing ? L4RE_DS_MAP_FLAG_RW : L4RE_DS_MAP_FLAG_RO), 151.36 - _paging(paging), _writing(writing) 151.37 -{ 151.38 - /* Initialise the size of the paged region. */ 151.39 - 151.40 - _size = _paging->region_size(); 151.41 -} 151.42 - 151.43 -int PipePager::expected_items() 151.44 -{ 151.45 - return PipeObject_expected_items; 151.46 -} 151.47 - 151.48 -ipc_server_handler_type PipePager::handler() 151.49 -{ 151.50 - return (ipc_server_handler_type) handle_PipeObject; 151.51 -} 151.52 - 151.53 - 151.54 - 151.55 -/* Close the pager, releasing the paging coordinator for the pipe. This will 151.56 - release all active page mappers. */ 151.57 - 151.58 -void PipePager::close() 151.59 -{ 151.60 - _paging->detach(); 151.61 -} 151.62 - 151.63 -/* Support paging. */ 151.64 - 151.65 -long PipePager::map(offset_t offset, address_t hot_spot, flags_t flags, l4_snd_fpage_t *region) 151.66 -{ 151.67 - return Pager::map(offset, hot_spot, flags, region); 151.68 -} 151.69 - 151.70 - 151.71 - 151.72 -/* Return details of the current region. */ 151.73 - 151.74 -long PipePager::current_region(offset_t *populated_size, offset_t *size) 151.75 -{ 151.76 - if (_mapper != NULL) 151.77 - { 151.78 - *populated_size = _mapper->get_data_size(); 151.79 - *size = _size; 151.80 - return L4_EOK; 151.81 - } 151.82 - else 151.83 - return -L4_EIO; 151.84 -} 151.85 - 151.86 -/* Obtain the next region and its details. */ 151.87 - 151.88 -long PipePager::next_region(offset_t *populated_size, offset_t *size) 151.89 -{ 151.90 - /* Obtain a new region if writing. */ 151.91 - 151.92 - if (_writing) 151.93 - return next_region_for_writer(populated_size, size); 151.94 - else 151.95 - return next_region_for_reader(populated_size, size); 151.96 -} 151.97 - 151.98 -long PipePager::next_region_for_reader(offset_t *populated_size, offset_t *size) 151.99 -{ 151.100 - PageMapper *mapper = _paging->next_region(); 151.101 - 151.102 - if (mapper == NULL) 151.103 - return -L4_EIO; 151.104 - 151.105 - _mapper = mapper; 151.106 - 151.107 - return current_region(populated_size, size); 151.108 -} 151.109 - 151.110 -long PipePager::next_region_for_writer(offset_t *populated_size, offset_t *size) 151.111 -{ 151.112 - /* Set the populated size before moving on. */ 151.113 - 151.114 - if (_mapper != NULL) 151.115 - _mapper->set_data_size(*populated_size); 151.116 - 151.117 - /* Obtain the page mapper for the region. */ 151.118 - 151.119 - PageMapper *mapper = _paging->add_region(); 151.120 - 151.121 - if (mapper == NULL) 151.122 - return -L4_EIO; 151.123 - 151.124 - _mapper = mapper; 151.125 - 151.126 - return current_region(populated_size, size); 151.127 -} 151.128 - 151.129 -// vim: tabstop=4 expandtab shiftwidth=4
152.1 --- a/pipes/pipe_pager.h Tue Apr 13 00:03:18 2021 +0200 152.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 152.3 @@ -1,70 +0,0 @@ 152.4 -/* 152.5 - * A pipe pager providing access to pipe content and navigation support. 152.6 - * 152.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 152.8 - * 152.9 - * This program is free software; you can redistribute it and/or 152.10 - * modify it under the terms of the GNU General Public License as 152.11 - * published by the Free Software Foundation; either version 2 of 152.12 - * the License, or (at your option) any later version. 152.13 - * 152.14 - * This program is distributed in the hope that it will be useful, 152.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 152.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 152.17 - * GNU General Public License for more details. 152.18 - * 152.19 - * You should have received a copy of the GNU General Public License 152.20 - * along with this program; if not, write to the Free Software 152.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 152.22 - * Boston, MA 02110-1301, USA 152.23 - */ 152.24 - 152.25 -#pragma once 152.26 - 152.27 -#include "pipe_accessor.h" 152.28 -#include "pipe_object_interface.h" 152.29 -#include "pipe_paging.h" 152.30 -#include "pager.h" 152.31 - 152.32 - 152.33 - 152.34 -/* A pager abstraction for a pipe. */ 152.35 - 152.36 -class PipePager : public Pager, public PipeObject 152.37 -{ 152.38 -protected: 152.39 - PipePaging *_paging; 152.40 - bool _writing; 152.41 - 152.42 - /* Helper methods. */ 152.43 - 152.44 - virtual long next_region_for_reader(offset_t *populated_size, offset_t *size); 152.45 - 152.46 - virtual long next_region_for_writer(offset_t *populated_size, offset_t *size); 152.47 - 152.48 -public: 152.49 - explicit PipePager(PipePaging *paging, bool writer); 152.50 - 152.51 - virtual void close(); 152.52 - 152.53 - /* Server details. */ 152.54 - 152.55 - int expected_items(); 152.56 - 152.57 - ipc_server_handler_type handler(); 152.58 - 152.59 - void *interface() 152.60 - { return static_cast<PipeObject *>(this); } 152.61 - 152.62 - /* Pager methods. */ 152.63 - 152.64 - virtual long map(offset_t offset, address_t hot_spot, flags_t flags, l4_snd_fpage_t *region); 152.65 - 152.66 - /* Pipe methods. */ 152.67 - 152.68 - virtual long current_region(offset_t *populated_size, offset_t *size); 152.69 - 152.70 - virtual long next_region(offset_t *populated_size, offset_t *size); 152.71 -}; 152.72 - 152.73 -// vim: tabstop=4 expandtab shiftwidth=4
153.1 --- a/pipes/pipe_paging.cc Tue Apr 13 00:03:18 2021 +0200 153.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 153.3 @@ -1,139 +0,0 @@ 153.4 -/* 153.5 - * A pipe paging coordinator, permitting memory sharing pipe endpoints. 153.6 - * 153.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 153.8 - * 153.9 - * This program is free software; you can redistribute it and/or 153.10 - * modify it under the terms of the GNU General Public License as 153.11 - * published by the Free Software Foundation; either version 2 of 153.12 - * the License, or (at your option) any later version. 153.13 - * 153.14 - * This program is distributed in the hope that it will be useful, 153.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 153.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 153.17 - * GNU General Public License for more details. 153.18 - * 153.19 - * You should have received a copy of the GNU General Public License 153.20 - * along with this program; if not, write to the Free Software 153.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 153.22 - * Boston, MA 02110-1301, USA 153.23 - */ 153.24 - 153.25 -#include "memory_incremental.h" 153.26 -#include "memory_preallocated.h" 153.27 -#include "page_queue_partitioned.h" 153.28 -#include "pipe_paging.h" 153.29 - 153.30 - 153.31 - 153.32 -PipePaging::PipePaging(Memory *memory, offset_t size) 153.33 -: _memory(NULL), _size(size) 153.34 -{ 153.35 - /* Reserve space for two pipe regions. */ 153.36 - 153.37 - _memory = new MemoryPreallocated(memory, round(size, memory->region_size()) * 2); 153.38 - _queue = new PageQueuePartitioned(); 153.39 - _pages = new Pages(_memory, _queue); 153.40 - 153.41 - for (unsigned int i = 0; i < 2; i++) 153.42 - _regions[i] = NULL; 153.43 -} 153.44 - 153.45 -/* Detach one endpoint. */ 153.46 - 153.47 -void PipePaging::detach() 153.48 -{ 153.49 - if (!_endpoints) 153.50 - return; 153.51 - else 153.52 - _endpoints--; 153.53 - 153.54 - /* Return if the other endpoint is attached. */ 153.55 - 153.56 - if (_endpoints) 153.57 - return; 153.58 - 153.59 - /* Discard all regions from the pipe. */ 153.60 - 153.61 - for (unsigned int i = 0; i < 2; i++) 153.62 - { 153.63 - PageMapper *mapper = _regions[i]; 153.64 - 153.65 - if (mapper != NULL) 153.66 - { 153.67 - mapper->detach(); 153.68 - _regions[i] = NULL; 153.69 - delete mapper; 153.70 - } 153.71 - } 153.72 - 153.73 - /* Delete the page collection and related objects. */ 153.74 - 153.75 - delete _pages; 153.76 - delete _queue; 153.77 - delete _memory; 153.78 -} 153.79 - 153.80 -/* Add a region to the sequence. */ 153.81 - 153.82 -PageMapper *PipePaging::add_region() 153.83 -{ 153.84 - /* If the writer already accesses a different region to the reader, no new 153.85 - region is added. */ 153.86 - 153.87 - if (_writing != _reading) 153.88 - return NULL; 153.89 - 153.90 - /* Select the other region of the pair being maintained. */ 153.91 - 153.92 - _writing = 1 - _writing; 153.93 - 153.94 - /* Make a new mapper for the region. */ 153.95 - 153.96 - PageMapper *mapper = new PageMapper(&_accessors[_writing], _pages); 153.97 - 153.98 - /* Initialise and record the mapper. */ 153.99 - 153.100 - mapper->attach(); 153.101 - mapper->set_data_size(0); 153.102 - 153.103 - _regions[_writing] = mapper; 153.104 - return mapper; 153.105 -} 153.106 - 153.107 -/* Return the current region for reading. */ 153.108 - 153.109 -PageMapper *PipePaging::current_region() 153.110 -{ 153.111 - return _regions[_reading]; 153.112 -} 153.113 - 153.114 -/* Return the next region for the reader if the writer is using a different one. 153.115 - Otherwise, return NULL. */ 153.116 - 153.117 -PageMapper *PipePaging::next_region() 153.118 -{ 153.119 - /* If the reader already accesses the same region to the writer, no next 153.120 - region can be obtained. */ 153.121 - 153.122 - if (_reading == _writing) 153.123 - return NULL; 153.124 - 153.125 - /* Detach and discard the current page mapper. */ 153.126 - 153.127 - PageMapper *mapper = _regions[_reading]; 153.128 - 153.129 - if (mapper != NULL) 153.130 - { 153.131 - mapper->detach(); 153.132 - _regions[_reading] = NULL; 153.133 - delete mapper; 153.134 - } 153.135 - 153.136 - /* Return the next region. */ 153.137 - 153.138 - _reading = 1 - _reading; 153.139 - return _regions[_reading]; 153.140 -} 153.141 - 153.142 -// vim: tabstop=4 expandtab shiftwidth=4
154.1 --- a/pipes/pipe_paging.h Tue Apr 13 00:03:18 2021 +0200 154.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 154.3 @@ -1,74 +0,0 @@ 154.4 -/* 154.5 - * A pipe paging coordinator, permitting memory sharing pipe endpoints. 154.6 - * 154.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 154.8 - * 154.9 - * This program is free software; you can redistribute it and/or 154.10 - * modify it under the terms of the GNU General Public License as 154.11 - * published by the Free Software Foundation; either version 2 of 154.12 - * the License, or (at your option) any later version. 154.13 - * 154.14 - * This program is distributed in the hope that it will be useful, 154.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 154.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 154.17 - * GNU General Public License for more details. 154.18 - * 154.19 - * You should have received a copy of the GNU General Public License 154.20 - * along with this program; if not, write to the Free Software 154.21 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, 154.22 - * Boston, MA 02110-1301, USA 154.23 - */ 154.24 - 154.25 -#pragma once 154.26 - 154.27 -#include "page_mapper.h" 154.28 -#include "pages.h" 154.29 -#include "pipe_accessor.h" 154.30 - 154.31 - 154.32 - 154.33 -/* Pipe paging support, maintaining the sequence of active regions or sections 154.34 - in a pipe. */ 154.35 - 154.36 -class PipePaging 154.37 -{ 154.38 -protected: 154.39 - Memory *_memory; 154.40 - Pages *_pages; 154.41 - PageQueue *_queue; 154.42 - 154.43 - /* Regions acting as files with their own accessors. */ 154.44 - 154.45 - PageMapper *_regions[2]; 154.46 - PipeAccessor _accessors[2]; 154.47 - 154.48 - /* The first region is initially exposed to both reader and writer. */ 154.49 - 154.50 - int _reading = 0, _writing = 0; 154.51 - 154.52 - /* Pipe section/region size. */ 154.53 - 154.54 - offset_t _size; 154.55 - 154.56 - /* Endpoint status. */ 154.57 - 154.58 - unsigned int _endpoints = 2; 154.59 - 154.60 -public: 154.61 - explicit PipePaging(Memory *memory, offset_t size); 154.62 - 154.63 - virtual void detach(); 154.64 - 154.65 - virtual offset_t region_size() 154.66 - { return _size; } 154.67 - 154.68 - /* Region management. */ 154.69 - 154.70 - virtual PageMapper *add_region(); 154.71 - 154.72 - virtual PageMapper *current_region(); 154.73 - 154.74 - virtual PageMapper *next_region(); 154.75 -}; 154.76 - 154.77 -// vim: tabstop=4 expandtab shiftwidth=4
155.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 155.2 +++ b/servers/Control Thu Apr 15 23:15:17 2021 +0200 155.3 @@ -0,0 +1,3 @@ 155.4 +requires: libstdc++ libc libipc libfsserver libmem 155.5 +provides: fsservers 155.6 +maintainer: paul@boddie.org.uk
156.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 156.2 +++ b/servers/Makefile Thu Apr 15 23:15:17 2021 +0200 156.3 @@ -0,0 +1,22 @@ 156.4 +PKGDIR ?= . 156.5 +L4DIR ?= $(PKGDIR)/../../.. 156.6 + 156.7 +TARGET = \ 156.8 + dstest_block_server \ 156.9 + dstest_host_server \ 156.10 + dstest_pipe_server \ 156.11 + dstest_test_server 156.12 + 156.13 +MODE = static 156.14 + 156.15 +SRC_CC_dstest_block_server = block_file_server.cc 156.16 + 156.17 +SRC_CC_dstest_host_server = host_file_server.cc 156.18 + 156.19 +SRC_CC_dstest_pipe_server = pipe_server.cc 156.20 + 156.21 +SRC_CC_dstest_test_server = test_file_server.cc 156.22 + 156.23 +REQUIRES_LIBS = l4re_c-util libmem libfsserver libipc libstdc++ libsystypes 156.24 + 156.25 +include $(L4DIR)/mk/prog.mk
157.1 --- a/servers/block_file_server.cc Tue Apr 13 00:03:18 2021 +0200 157.2 +++ b/servers/block_file_server.cc Thu Apr 15 23:15:17 2021 +0200 157.3 @@ -28,12 +28,12 @@ 157.4 #include <string.h> 157.5 #include <stdlib.h> 157.6 157.7 -#include "memory_incremental.h" 157.8 -#include "memory_utils.h" 157.9 -#include "page_queue_shared.h" 157.10 -#include "pages.h" 157.11 -#include "resource_server.h" 157.12 -#include "block_file_opener.h" 157.13 +#include <mem/memory_incremental.h> 157.14 +#include <mem/memory_utils.h> 157.15 +#include <fsserver/page_queue_shared.h> 157.16 +#include <fsserver/pages.h> 157.17 +#include <fsserver/resource_server.h> 157.18 +#include <fsserver/block_file_opener.h> 157.19 157.20 157.21
158.1 --- a/servers/host_file_server.cc Tue Apr 13 00:03:18 2021 +0200 158.2 +++ b/servers/host_file_server.cc Thu Apr 15 23:15:17 2021 +0200 158.3 @@ -28,12 +28,12 @@ 158.4 #include <string.h> 158.5 #include <stdlib.h> 158.6 158.7 -#include "memory_incremental.h" 158.8 -#include "memory_utils.h" 158.9 -#include "page_queue_shared.h" 158.10 -#include "pages.h" 158.11 -#include "resource_server.h" 158.12 -#include "host_file_opener.h" 158.13 +#include <mem/memory_incremental.h> 158.14 +#include <mem/memory_utils.h> 158.15 +#include <fsserver/page_queue_shared.h> 158.16 +#include <fsserver/pages.h> 158.17 +#include <fsserver/resource_server.h> 158.18 +#include <fsserver/host_file_opener.h> 158.19 158.20 158.21
159.1 --- a/servers/pipe_server.cc Tue Apr 13 00:03:18 2021 +0200 159.2 +++ b/servers/pipe_server.cc Thu Apr 15 23:15:17 2021 +0200 159.3 @@ -26,9 +26,9 @@ 159.4 #include <stdio.h> 159.5 #include <stdlib.h> 159.6 159.7 -#include "memory_incremental.h" 159.8 -#include "pipe_opener_resource.h" 159.9 -#include "resource_server.h" 159.10 +#include <mem/memory_incremental.h> 159.11 +#include <fsserver/pipe_opener_resource.h> 159.12 +#include <fsserver/resource_server.h> 159.13 159.14 159.15
160.1 --- a/servers/test_file_server.cc Tue Apr 13 00:03:18 2021 +0200 160.2 +++ b/servers/test_file_server.cc Thu Apr 15 23:15:17 2021 +0200 160.3 @@ -28,12 +28,12 @@ 160.4 #include <string.h> 160.5 #include <stdlib.h> 160.6 160.7 -#include "memory_incremental.h" 160.8 -#include "memory_utils.h" 160.9 -#include "page_queue_shared.h" 160.10 -#include "pages.h" 160.11 -#include "resource_server.h" 160.12 -#include "test_file_opener.h" 160.13 +#include <mem/memory_incremental.h> 160.14 +#include <mem/memory_utils.h> 160.15 +#include <fsserver/page_queue_shared.h> 160.16 +#include <fsserver/pages.h> 160.17 +#include <fsserver/resource_server.h> 160.18 +#include <fsserver/test_file_opener.h> 160.19 160.20 160.21
161.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 161.2 +++ b/tests/Control Thu Apr 15 23:15:17 2021 +0200 161.3 @@ -0,0 +1,3 @@ 161.4 +requires: libstdc++ libc libipc libfsclient libmem 161.5 +provides: fstests 161.6 +maintainer: paul@boddie.org.uk
162.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 162.2 +++ b/tests/Makefile Thu Apr 15 23:15:17 2021 +0200 162.3 @@ -0,0 +1,24 @@ 162.4 +PKGDIR ?= . 162.5 +L4DIR ?= $(PKGDIR)/../../.. 162.6 + 162.7 +TARGET = \ 162.8 + dstest_block_client dstest_block_client_simple \ 162.9 + dstest_host_client \ 162.10 + dstest_pipe_client \ 162.11 + dstest_test_client \ 162.12 + 162.13 +MODE = static 162.14 + 162.15 +SRC_CC_dstest_block_client = dstest_block_client.cc 162.16 + 162.17 +SRC_CC_dstest_block_client_simple = dstest_block_client_simple.cc 162.18 + 162.19 +SRC_CC_dstest_host_client = dstest_host_client.cc 162.20 + 162.21 +SRC_CC_dstest_pipe_client = dstest_pipe_client.cc 162.22 + 162.23 +SRC_CC_dstest_test_client = dstest_test_client.cc 162.24 + 162.25 +REQUIRES_LIBS = l4re_c-util libfsclient libmem libipc libstdc++ libsystypes 162.26 + 162.27 +include $(L4DIR)/mk/prog.mk
163.1 --- a/tests/dstest_block_client.cc Tue Apr 13 00:03:18 2021 +0200 163.2 +++ b/tests/dstest_block_client.cc Thu Apr 15 23:15:17 2021 +0200 163.3 @@ -28,8 +28,8 @@ 163.4 #include <string.h> 163.5 #include <stdlib.h> 163.6 163.7 -#include "file.h" 163.8 -#include "memory_utils.h" 163.9 +#include <fsclient/file.h> 163.10 +#include <mem/memory_utils.h> 163.11 163.12 163.13
164.1 --- a/tests/dstest_block_client_simple.cc Tue Apr 13 00:03:18 2021 +0200 164.2 +++ b/tests/dstest_block_client_simple.cc Thu Apr 15 23:15:17 2021 +0200 164.3 @@ -23,7 +23,7 @@ 164.4 164.5 #include <stdio.h> 164.6 164.7 -#include "client.h" 164.8 +#include <fsclient/client.h> 164.9 164.10 164.11
165.1 --- a/tests/dstest_host_client.cc Tue Apr 13 00:03:18 2021 +0200 165.2 +++ b/tests/dstest_host_client.cc Thu Apr 15 23:15:17 2021 +0200 165.3 @@ -28,8 +28,8 @@ 165.4 #include <string.h> 165.5 #include <stdlib.h> 165.6 165.7 -#include "file.h" 165.8 -#include "memory_utils.h" 165.9 +#include <fsclient/file.h> 165.10 +#include <mem/memory_utils.h> 165.11 165.12 165.13
166.1 --- a/tests/dstest_pipe_client.cc Tue Apr 13 00:03:18 2021 +0200 166.2 +++ b/tests/dstest_pipe_client.cc Thu Apr 15 23:15:17 2021 +0200 166.3 @@ -26,8 +26,8 @@ 166.4 #include <string.h> 166.5 #include <stdlib.h> 166.6 166.7 -#include "file.h" 166.8 -#include "memory_utils.h" 166.9 +#include <fsclient/file.h> 166.10 +#include <mem/memory_utils.h> 166.11 166.12 166.13
167.1 --- a/tests/dstest_test_client.cc Tue Apr 13 00:03:18 2021 +0200 167.2 +++ b/tests/dstest_test_client.cc Thu Apr 15 23:15:17 2021 +0200 167.3 @@ -34,8 +34,8 @@ 167.4 167.5 #include <ipc/thread.h> 167.6 167.7 -#include "file.h" 167.8 -#include "memory_utils.h" 167.9 +#include <fsclient/file.h> 167.10 +#include <mem/memory_utils.h> 167.11 167.12 167.13