1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/include/fsserver/access_map.h Sun Aug 16 23:20:29 2020 +0200
1.3 @@ -0,0 +1,85 @@
1.4 +/*
1.5 + * A flexpage mapping for accessors.
1.6 + *
1.7 + * Copyright (C) 2020 Paul Boddie <paul@boddie.org.uk>
1.8 + *
1.9 + * This program is free software; you can redistribute it and/or
1.10 + * modify it under the terms of the GNU General Public License as
1.11 + * published by the Free Software Foundation; either version 2 of
1.12 + * the License, or (at your option) any later version.
1.13 + *
1.14 + * This program is distributed in the hope that it will be useful,
1.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.17 + * GNU General Public License for more details.
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License
1.20 + * along with this program; if not, write to the Free Software
1.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
1.22 + * Boston, MA 02110-1301, USA
1.23 + */
1.24 +
1.25 +#pragma once
1.26 +
1.27 +#include <l4/sys/semaphore.h>
1.28 +#include <l4/sys/types.h>
1.29 +
1.30 +#include <stdio.h>
1.31 +
1.32 +#include <map>
1.33 +#include <set>
1.34 +
1.35 +#include <fsserver/flexpage.h>
1.36 +
1.37 +/* Forward declarations. */
1.38 +
1.39 +class Pages;
1.40 +class PagingAccessor;
1.41 +
1.42 +
1.43 +
1.44 +/* Collections of flexpages ordered by file positions. */
1.45 +
1.46 +typedef std::map<unsigned long, Flexpage *> Flexpage_map;
1.47 +typedef std::pair<unsigned long, Flexpage *> Flexpage_map_item;
1.48 +
1.49 +
1.50 +
1.51 +/* Page map for accessors. */
1.52 +
1.53 +class AccessMap
1.54 +{
1.55 +protected:
1.56 + /* Available flexpages within each file ordered by file position. */
1.57 +
1.58 + Flexpage_map _map;
1.59 + l4_cap_idx_t _semaphore;
1.60 +
1.61 + void lock_map()
1.62 + {
1.63 + l4_semaphore_down(_semaphore, L4_IPC_NEVER);
1.64 + }
1.65 +
1.66 + void unlock_map()
1.67 + {
1.68 + l4_semaphore_up(_semaphore);
1.69 + }
1.70 +
1.71 + Flexpage *_find(unsigned long data_position);
1.72 +
1.73 +public:
1.74 + explicit AccessMap();
1.75 +
1.76 + virtual ~AccessMap();
1.77 +
1.78 + Flexpage *find(unsigned long data_position);
1.79 +
1.80 + void flush_all(unsigned long start, unsigned long end, bool keep,
1.81 + PagingAccessor *accessor);
1.82 +
1.83 + void insert(Flexpage *flexpage);
1.84 +
1.85 + bool remove(Flexpage *flexpage);
1.86 +
1.87 + void purge(PagingAccessor *accessor, Pages *pages);
1.88 +};
2.1 --- a/include/fsserver/accessor.h Sun Aug 16 22:52:00 2020 +0200
2.2 +++ b/include/fsserver/accessor.h Sun Aug 16 23:20:29 2020 +0200
2.3 @@ -29,6 +29,7 @@
2.4 #include <map>
2.5 #include <set>
2.6
2.7 +#include <fsserver/access_map.h>
2.8 #include <fsserver/flexpage.h>
2.9 #include <fsserver/queue.h>
2.10
2.11 @@ -36,7 +37,6 @@
2.12
2.13 class Paging;
2.14 class Pages;
2.15 -class PagingAccessor;
2.16
2.17
2.18
2.19 @@ -162,52 +162,6 @@
2.20
2.21
2.22
2.23 -/* Collections of flexpages ordered by file positions. */
2.24 -
2.25 -typedef std::map<unsigned long, Flexpage *> Flexpage_map;
2.26 -typedef std::pair<unsigned long, Flexpage *> Flexpage_map_item;
2.27 -
2.28 -
2.29 -
2.30 -/* Page map for accessors. */
2.31 -
2.32 -class AccessMap
2.33 -{
2.34 -protected:
2.35 - /* Available flexpages within each file ordered by file position. */
2.36 -
2.37 - Flexpage_map _map;
2.38 - l4_cap_idx_t _semaphore;
2.39 -
2.40 - void lock_map()
2.41 - {
2.42 - l4_semaphore_down(_semaphore, L4_IPC_NEVER);
2.43 - }
2.44 -
2.45 - void unlock_map()
2.46 - {
2.47 - l4_semaphore_up(_semaphore);
2.48 - }
2.49 -
2.50 -public:
2.51 - explicit AccessMap();
2.52 -
2.53 - virtual ~AccessMap();
2.54 -
2.55 - Flexpage *find(unsigned long data_position);
2.56 -
2.57 - void flush_all(unsigned long start, unsigned long end, bool keep,
2.58 - PagingAccessor *accessor);
2.59 -
2.60 - void insert(Flexpage *flexpage);
2.61 -
2.62 - bool remove(Flexpage *flexpage);
2.63 -
2.64 - void purge(PagingAccessor *accessor, Pages *pages);
2.65 -};
2.66 -
2.67 -
2.68 -
2.69 /* Filesystem object accessor supporting paging. */
2.70
2.71 class PagingAccessor : public FileAccessor
3.1 --- a/lib/src/Makefile Sun Aug 16 22:52:00 2020 +0200
3.2 +++ b/lib/src/Makefile Sun Aug 16 23:20:29 2020 +0200
3.3 @@ -52,6 +52,7 @@
3.4
3.5 PLAIN_SRC_CC = \
3.6 accessor.cc \
3.7 + access_map.cc \
3.8 buffer_support.cc \
3.9 file_resource.cc \
3.10 filesystem_resource.cc \
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/lib/src/access_map.cc Sun Aug 16 23:20:29 2020 +0200
4.3 @@ -0,0 +1,173 @@
4.4 +/*
4.5 + * Accessor flexpage mapping.
4.6 + *
4.7 + * Copyright (C) 2020 Paul Boddie <paul@boddie.org.uk>
4.8 + *
4.9 + * This program is free software; you can redistribute it and/or
4.10 + * modify it under the terms of the GNU General Public License as
4.11 + * published by the Free Software Foundation; either version 2 of
4.12 + * the License, or (at your option) any later version.
4.13 + *
4.14 + * This program is distributed in the hope that it will be useful,
4.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.17 + * GNU General Public License for more details.
4.18 + *
4.19 + * You should have received a copy of the GNU General Public License
4.20 + * along with this program; if not, write to the Free Software
4.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
4.22 + * Boston, MA 02110-1301, USA
4.23 + */
4.24 +
4.25 +#include <l4/re/c/util/cap_alloc.h>
4.26 +#include <l4/re/env.h>
4.27 +#include <l4/sys/factory.h>
4.28 +#include <l4/sys/types.h>
4.29 +
4.30 +#include <stdlib.h>
4.31 +#include <stdio.h>
4.32 +#include <unistd.h>
4.33 +
4.34 +#include "access_map.h"
4.35 +
4.36 +/* Obtain declarations not obtained in the access map header. */
4.37 +
4.38 +#include "pages.h"
4.39 +
4.40 +
4.41 +
4.42 +/* Initialise a page mapping. */
4.43 +
4.44 +AccessMap::AccessMap()
4.45 +{
4.46 + _semaphore = l4re_util_cap_alloc();
4.47 +
4.48 + if (l4_is_valid_cap(_semaphore))
4.49 + {
4.50 + l4_factory_create(l4re_env()->factory, L4_PROTO_SEMAPHORE, _semaphore);
4.51 + unlock_map();
4.52 + }
4.53 +}
4.54 +
4.55 +AccessMap::~AccessMap()
4.56 +{
4.57 + if (l4_is_valid_cap(_semaphore))
4.58 + l4re_util_cap_free_um(_semaphore);
4.59 +}
4.60 +
4.61 +/* Find a flexpage for the given details. */
4.62 +
4.63 +Flexpage *AccessMap::find(unsigned long data_position)
4.64 +{
4.65 + lock_map();
4.66 +
4.67 + Flexpage *flexpage = _find(data_position);
4.68 +
4.69 + unlock_map();
4.70 + return flexpage;
4.71 +}
4.72 +
4.73 +Flexpage *AccessMap::_find(unsigned long data_position)
4.74 +{
4.75 + Flexpage *flexpage = NULL;
4.76 +
4.77 + /* Iterator for accessing the mapping. */
4.78 +
4.79 + Flexpage_map::iterator it;
4.80 +
4.81 + /* Seek to the first flexpage beyond the given position. */
4.82 +
4.83 + it = _map.upper_bound(data_position);
4.84 +
4.85 + /* Obtain any previous flexpage. */
4.86 +
4.87 + if ((_map.size() > 0) && (it != _map.begin()))
4.88 + {
4.89 + it--;
4.90 +
4.91 + Flexpage *test = it->second;
4.92 +
4.93 + /* Test the flexpage for suitability. */
4.94 +
4.95 + if (test->valid() && test->supports(data_position))
4.96 + flexpage = test;
4.97 + }
4.98 +
4.99 + return flexpage;
4.100 +}
4.101 +
4.102 +/* Flush all allocated flexpages within a given region, writing data to
4.103 + storage. If the keep indicator is set to a true value, the flexpages will be
4.104 + retained; otherwise, they are invalidated. */
4.105 +
4.106 +void AccessMap::flush_all(unsigned long start, unsigned long end, bool keep,
4.107 + PagingAccessor *accessor)
4.108 +{
4.109 + lock_map();
4.110 +
4.111 + Flexpage_map::iterator it;
4.112 +
4.113 + for (it = _map.begin(); it != _map.end(); it++)
4.114 + {
4.115 + Flexpage *flexpage = it->second;
4.116 +
4.117 + /* Flush valid, overlapping mapping entries. */
4.118 +
4.119 + if (flexpage->overlap(start, end))
4.120 + accessor->flush_flexpage(flexpage, keep);
4.121 + }
4.122 +
4.123 + unlock_map();
4.124 +}
4.125 +/* Insert the flexpage into the collection. */
4.126 +
4.127 +void AccessMap::insert(Flexpage *flexpage)
4.128 +{
4.129 + lock_map();
4.130 +
4.131 + _map.insert(Flexpage_map_item(flexpage->get_data_start(), flexpage));
4.132 +
4.133 + unlock_map();
4.134 +}
4.135 +
4.136 +/* Remove the given flexpage from the collection, flushing its data. */
4.137 +
4.138 +bool AccessMap::remove(Flexpage *flexpage)
4.139 +{
4.140 + lock_map();
4.141 +
4.142 + if (_find(flexpage->get_data_start()) == NULL)
4.143 + {
4.144 + unlock_map();
4.145 + return false;
4.146 + }
4.147 +
4.148 + _map.erase(flexpage->get_data_start());
4.149 +
4.150 + unlock_map();
4.151 + return true;
4.152 +}
4.153 +
4.154 +/* Purge all flexpages from the collection, flushing their data. */
4.155 +
4.156 +void AccessMap::purge(PagingAccessor *accessor, Pages *pages)
4.157 +{
4.158 + lock_map();
4.159 +
4.160 + Flexpage_map::iterator it;
4.161 +
4.162 + for (it = _map.begin(); it != _map.end(); it++)
4.163 + {
4.164 + Flexpage *flexpage = it->second;
4.165 +
4.166 + if (pages->reserve_flexpage(accessor, flexpage))
4.167 + {
4.168 + accessor->flush_flexpage(flexpage, false, true);
4.169 + pages->release_flexpage(flexpage);
4.170 + }
4.171 + }
4.172 +
4.173 + _map.clear();
4.174 +
4.175 + unlock_map();
4.176 +}
5.1 --- a/lib/src/accessor.cc Sun Aug 16 22:52:00 2020 +0200
5.2 +++ b/lib/src/accessor.cc Sun Aug 16 23:20:29 2020 +0200
5.3 @@ -60,135 +60,6 @@
5.4
5.5
5.6
5.7 -/* Initialise a page mapping. */
5.8 -
5.9 -AccessMap::AccessMap()
5.10 -{
5.11 - _semaphore = l4re_util_cap_alloc();
5.12 -
5.13 - if (l4_is_valid_cap(_semaphore))
5.14 - {
5.15 - l4_factory_create(l4re_env()->factory, L4_PROTO_SEMAPHORE, _semaphore);
5.16 - unlock_map();
5.17 - }
5.18 -}
5.19 -
5.20 -AccessMap::~AccessMap()
5.21 -{
5.22 - if (l4_is_valid_cap(_semaphore))
5.23 - l4re_util_cap_free_um(_semaphore);
5.24 -}
5.25 -
5.26 -/* Find a flexpage for the given details. */
5.27 -
5.28 -Flexpage *AccessMap::find(unsigned long data_position)
5.29 -{
5.30 - lock_map();
5.31 -
5.32 - Flexpage *flexpage = NULL;
5.33 -
5.34 - /* Iterator for accessing the mapping. */
5.35 -
5.36 - Flexpage_map::iterator it;
5.37 -
5.38 - /* Seek to the first flexpage beyond the given position. */
5.39 -
5.40 - it = _map.upper_bound(data_position);
5.41 -
5.42 - /* Obtain any previous flexpage. */
5.43 -
5.44 - if ((_map.size() > 0) && (it != _map.begin()))
5.45 - {
5.46 - it--;
5.47 -
5.48 - Flexpage *test = it->second;
5.49 -
5.50 - /* Test the flexpage for suitability. */
5.51 -
5.52 - if (test->valid() && test->supports(data_position))
5.53 - flexpage = test;
5.54 - }
5.55 -
5.56 - unlock_map();
5.57 -
5.58 - return flexpage;
5.59 -}
5.60 -
5.61 -/* Flush all allocated flexpages within a given region, writing data to
5.62 - storage. If the keep indicator is set to a true value, the flexpages will be
5.63 - retained; otherwise, they are invalidated. */
5.64 -
5.65 -void AccessMap::flush_all(unsigned long start, unsigned long end, bool keep,
5.66 - PagingAccessor *accessor)
5.67 -{
5.68 - lock_map();
5.69 -
5.70 - Flexpage_map::iterator it;
5.71 -
5.72 - for (it = _map.begin(); it != _map.end(); it++)
5.73 - {
5.74 - Flexpage *flexpage = it->second;
5.75 -
5.76 - /* Flush valid, overlapping mapping entries. */
5.77 -
5.78 - if (flexpage->overlap(start, end))
5.79 - accessor->flush_flexpage(flexpage, keep);
5.80 - }
5.81 -
5.82 - unlock_map();
5.83 -}
5.84 -/* Insert the flexpage into the collection. */
5.85 -
5.86 -void AccessMap::insert(Flexpage *flexpage)
5.87 -{
5.88 - lock_map();
5.89 -
5.90 - _map.insert(Flexpage_map_item(flexpage->get_data_start(), flexpage));
5.91 -
5.92 - unlock_map();
5.93 -}
5.94 -
5.95 -/* Remove the given flexpage from the collection, flushing its data. */
5.96 -
5.97 -bool AccessMap::remove(Flexpage *flexpage)
5.98 -{
5.99 - if (find(flexpage->get_data_start()) == NULL)
5.100 - return false;
5.101 -
5.102 - lock_map();
5.103 -
5.104 - _map.erase(flexpage->get_data_start());
5.105 -
5.106 - unlock_map();
5.107 - return true;
5.108 -}
5.109 -
5.110 -/* Purge all flexpages from the collection, flushing their data. */
5.111 -
5.112 -void AccessMap::purge(PagingAccessor *accessor, Pages *pages)
5.113 -{
5.114 - lock_map();
5.115 -
5.116 - Flexpage_map::iterator it;
5.117 -
5.118 - for (it = _map.begin(); it != _map.end(); it++)
5.119 - {
5.120 - Flexpage *flexpage = it->second;
5.121 -
5.122 - if (pages->reserve_flexpage(accessor, flexpage))
5.123 - {
5.124 - accessor->flush_flexpage(flexpage, false, true);
5.125 - pages->release_flexpage(flexpage);
5.126 - }
5.127 - }
5.128 -
5.129 - _map.clear();
5.130 -
5.131 - unlock_map();
5.132 -}
5.133 -
5.134 -
5.135 -
5.136 /* Return the common page collection. */
5.137
5.138 Pages *PagingAccessor::pages()